start work on enabling VMCORE and adding support in ustd
authorPierre-Marc Fournier <pierre-marc.fournier@polymtl.ca>
Sun, 22 Mar 2009 15:28:14 +0000 (11:28 -0400)
committerPierre-Marc Fournier <pierre-marc.fournier@polymtl.ca>
Sun, 22 Mar 2009 15:28:14 +0000 (11:28 -0400)
libtracing/relay.c
libtracing/relay.h
share/kernelcompat.h
ustd/Makefile
ustd/lowlevel.c [new file with mode: 0644]
ustd/ustd.c
ustd/ustd.h [new file with mode: 0644]

index 2087bcd98a9294b163ea7619353f58996a14ae53..6bb5a35d63d6aaed2497e0920287801b9e49d4a3 100644 (file)
@@ -1463,10 +1463,10 @@ static int ltt_relay_create_buffer(struct ltt_trace_struct *trace,
        int fds[2];
        int result;
 
-       ltt_buf->commit_count =
-               zmalloc(sizeof(ltt_buf->commit_count) * n_subbufs);
-       if (!ltt_buf->commit_count)
-               return -ENOMEM;
+//ust//        ltt_buf->commit_count =
+//ust//                zmalloc(sizeof(ltt_buf->commit_count) * n_subbufs);
+//ust//        if (!ltt_buf->commit_count)
+//ust//                return -ENOMEM;
        kref_get(&trace->kref);
        kref_get(&trace->ltt_transport_kref);
        kref_get(&ltt_chan->kref);
@@ -1505,8 +1505,8 @@ static void ltt_relay_destroy_buffer(struct ltt_channel_struct *ltt_chan)
        kref_put(&ltt_chan->trace->ltt_transport_kref,
                ltt_release_transport);
        ltt_relay_print_buffer_errors(ltt_chan);
-       kfree(ltt_buf->commit_count);
-       ltt_buf->commit_count = NULL;
+//ust//        kfree(ltt_buf->commit_count);
+//ust//        ltt_buf->commit_count = NULL;
        kref_put(&ltt_chan->kref, ltt_relay_release_channel);
        kref_put(&trace->kref, ltt_release_trace);
 //ust//        wake_up_interruptible(&trace->kref_wq);
@@ -1518,6 +1518,7 @@ static void ltt_chan_alloc_ltt_buf(struct ltt_channel_struct *ltt_chan)
        int result;
 
        /* Get one page */
+       /* FIXME: increase size if we have a commit_count array that overflows the page */
        size_t size = PAGE_ALIGN(1);
 
        result = ltt_chan->buf_shmid = shmget(getpid(), size, IPC_CREAT | IPC_EXCL | 0700);
@@ -2025,7 +2026,7 @@ static inline void ltt_reserve_switch_old_subbuf(
  * sub-buffer before this code gets executed, caution.  The commit makes sure
  * that this code is executed before the deliver of this sub-buffer.
  */
-static inline void ltt_reserve_switch_new_subbuf(
+static /*inline*/ void ltt_reserve_switch_new_subbuf(
                struct ltt_channel_struct *ltt_channel,
                struct ltt_channel_buf_struct *ltt_buf, struct rchan *rchan,
                struct rchan_buf *buf,
@@ -2237,14 +2238,13 @@ static notrace void ltt_force_switch(struct rchan_buf *buf,
  * fill the subbuffer completely (so the subbuf index stays in the previous
  * subbuffer).
  */
-#ifdef CONFIG_LTT_VMCORE
-static inline void ltt_write_commit_counter(struct rchan_buf *buf,
+//ust// #ifdef CONFIG_LTT_VMCORE
+static /*inline*/ void ltt_write_commit_counter(struct rchan_buf *buf,
                long buf_offset, size_t slot_size)
 {
        struct ltt_channel_struct *ltt_channel =
                (struct ltt_channel_struct *)buf->chan->private_data;
-       struct ltt_channel_buf_struct *ltt_buf =
-                       percpu_ptr(ltt_channel->buf, buf->cpu);
+       struct ltt_channel_buf_struct *ltt_buf = ltt_channel->buf;
        struct ltt_subbuffer_header *header;
        long offset, subbuf_idx, commit_count;
        uint32_t lost_old, lost_new;
@@ -2271,12 +2271,12 @@ static inline void ltt_write_commit_counter(struct rchan_buf *buf,
                }
        }
 }
-#else
-static inline void ltt_write_commit_counter(struct rchan_buf *buf,
-               long buf_offset, size_t slot_size)
-{
-}
-#endif
+//ust// #else
+//ust// static inline void ltt_write_commit_counter(struct rchan_buf *buf,
+//ust//                long buf_offset, size_t slot_size)
+//ust// {
+//ust// }
+//ust// #endif
 
 /*
  * Atomic unordered slot commit. Increments the commit count in the
@@ -2315,6 +2315,8 @@ static notrace void ltt_relay_commit_slot(
         * ltt buffers from vmcore, after crash.
         */
        ltt_write_commit_counter(buf, buf_offset, slot_size);
+
+       DBG("commited slot. now commit count is %ld", commit_count);
 }
 
 /*
index cd3baae3f3d180c81dcc585e8d89c1c89e3772e6..4b27b5bc8a7a476e5ded96c5ff7c84cbbe4287b0 100644 (file)
@@ -320,7 +320,7 @@ extern const struct file_operations ltt_relay_file_operations;
 struct ltt_channel_buf_struct {
        /* First 32 bytes cache-hot cacheline */
        local_t offset;                 /* Current offset in the buffer */
-       local_t *commit_count;          /* Commit count per sub-buffer */
+//ust//        local_t *commit_count;          /* Commit count per sub-buffer */
        atomic_long_t consumed;         /*
                                         * Current offset in the buffer
                                         * standard atomic access (shared)
@@ -353,6 +353,9 @@ struct ltt_channel_buf_struct {
        int data_ready_fd_write;
        /* the reading end of the pipe */
        int data_ready_fd_read;
+
+       /* commit count per subbuffer; must be at end of struct */
+       local_t commit_count[0] ____cacheline_aligned;
 } ____cacheline_aligned;
 
 int ltt_do_get_subbuf(struct rchan_buf *buf, struct ltt_channel_buf_struct *ltt_buf, long *pconsumed_old);
index a18460e041554cd6568ea3c0d01c1f61d1fcfd39..c0f4c9938c47a1959bcd5114036db63519ea1d3c 100644 (file)
@@ -6,6 +6,7 @@
 #include "compiler.h"
 
 #include <string.h>
+#include <sys/time.h>
 
 #define container_of(ptr, type, member) ({                      \
         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
index 0de51f87b6f3884bd8910bc6894876b65fa173fa..fb5c0e30d04338a137a03a4b7e93d307974a8c54 100644 (file)
@@ -1,6 +1,17 @@
+CFLAGS="-g -Wall"
+
 all: ustd
 
-ustd: ustd.c
-       gcc -g -Wall -I ../libustcomm -I. -I ../../../../libkcompat -lpthread -o ustd ustd.c ../libustcomm/ustcomm.c
+lowlevel.o: lowlevel.c
+       gcc -g -Wall -I ../libustcomm -I. -I ../../../../libkcompat -I ../libtracing -I ../share -I ../../../../urcu -I ../libmarkers -lpthread -c lowlevel.c
+
+ustd.o: ustd.c
+       gcc -g -Wall -I ../libustcomm -I. -I ../../../../libkcompat -lpthread -c ustd.c
+
+ustcomm.o: ../libustcomm/ustcomm.c
+       gcc -g -Wall -I ../share ../libustcomm/ustcomm.c
+
+ustd: ustd.o lowlevel.o ustcomm.o
+       gcc -g -Wall -lpthread -o ustd ustd.o lowlevel.o ustcomm.o
 
 .PHONY: ustd
diff --git a/ustd/lowlevel.c b/ustd/lowlevel.c
new file mode 100644 (file)
index 0000000..f386089
--- /dev/null
@@ -0,0 +1,50 @@
+#include "tracer.h"
+#include "ustd.h"
+#include "localerr.h"
+
+#define USTD_BUFFER_TRUNC(offset, bufinfo) \
+       ((offset) & (~(((bufinfo)->subbuf_size*(bufinfo)->n_subbufs)-1)))
+
+void finish_consuming_dead_subbuffer(struct buffer_info *buf)
+{
+       struct ltt_channel_buf_struct *ltt_buf = buf->bufstruct_mem;
+
+       long write_offset = local_read(&ltt_buf->offset);
+       long consumed_offset = atomic_long_read(&ltt_buf->consumed);
+
+       long i_subbuf;
+
+       DBG("processing died buffer");
+       DBG("consumed offset is %ld", consumed_offset);
+       DBG("write offset is %ld", write_offset);
+
+       long first_subbuf = write_offset / buf->subbuf_size;
+       long last_subbuf = consumed_offset / buf->subbuf_size;
+
+       if(last_subbuf - first_subbuf > buf->n_subbufs) {
+               DBG("an overflow has occurred, nothing can be recovered");
+               return;
+       }
+
+       for(i_subbuf=first_subbuf; ; i_subbuf++, i_subbuf %= buf->n_subbufs) {
+               long commit_count = local_read(&ltt_buf->commit_count[i_subbuf]);
+
+               unsigned long valid_length = buf->subbuf_size;
+               long n_subbufs_order = get_count_order(buf->n_subbufs);
+               long commit_count_mask = (~0UL >> n_subbufs_order);
+
+               /* check if subbuf was fully written */
+               if (((commit_count - buf->subbuf_size) & commit_count_mask)
+                   - (USTD_BUFFER_TRUNC(consumed_offset, buf) >> n_subbufs_order)
+                   != 0) {
+                       struct ltt_subbuffer_header *header = (struct ltt_subbuffer_header *)((char *)buf->mem)+i_subbuf*buf->subbuf_size;
+                       valid_length = buf->subbuf_size - header->lost_size;
+               }
+
+               patient_write(buf->file_fd, buf->mem + i_subbuf * buf->subbuf_size, buf->subbuf_size);
+
+               if(i_subbuf == last_subbuf)
+                       break;
+       }
+}
+
index a4c7e1f3f0c8a6dbdd17ac2fbf349a3fe7cb6f9d..ab4ec7aaac38c281f3c4cc6ac8f2c735453784ff 100644 (file)
 #include <stdio.h>
 #include <string.h>
 
+#include "ustd.h"
 #include "localerr.h"
 #include "ustcomm.h"
 
 struct list_head buffers = LIST_HEAD_INIT(buffers);
 
-struct buffer_info {
-       char *name;
-       pid_t pid;
-       struct ustcomm_connection conn;
-
-       int shmid;
-       int bufstruct_shmid;
-
-       /* the buffer memory */
-       void *mem;
-       /* buffer size */
-       int memlen;
-       /* number of subbuffers in buffer */
-       int n_subbufs;
-       /* size of each subbuffer */
-       int subbuf_size;
-
-       /* the buffer information struct */
-       void *bufstruct_mem;
-
-       int file_fd; /* output file */
-
-       struct list_head list;
-
-       long consumed_old;
-};
-
 /* return value: 0 = subbuffer is finished, it won't produce data anymore
  *               1 = got subbuffer successfully
  *               <0 = error
@@ -170,80 +144,25 @@ ssize_t patient_write(int fd, const void *buf, size_t count)
        return bufc-(const char *)buf;
 }
 
-int get_subbuffer_died(struct buffer_info *buf)
-{
-       return 0;
-}
-
-//int ltt_do_get_subbuf(struct rchan_buf *buf, struct ltt_channel_buf_struct *ltt_buf, long *pconsumed_old)
-//{
-//     struct ltt_channel_buf_struct *ltt_buf = buf->bufstruct_mem;
-//
-////ust//      struct ltt_channel_struct *ltt_channel = (struct ltt_channel_struct *)buf->chan->private_data;
-//     long consumed_old, consumed_idx, commit_count, write_offset;
-//     consumed_old = atomic_long_read(&ltt_buf->consumed);
-//     consumed_idx = SUBBUF_INDEX(consumed_old, buf->chan);
-//     commit_count = local_read(&ltt_buf->commit_count[consumed_idx]);
-//     /*
-//      * Make sure we read the commit count before reading the buffer
-//      * data and the write offset. Correct consumed offset ordering
-//      * wrt commit count is insured by the use of cmpxchg to update
-//      * the consumed offset.
-//      */
-//     smp_rmb();
-//     write_offset = local_read(&ltt_buf->offset);
-//     /*
-//      * Check that the subbuffer we are trying to consume has been
-//      * already fully committed.
-//      */
-//     if (((commit_count - buf->chan->subbuf_size)
-//          & ltt_channel->commit_count_mask)
-//         - (BUFFER_TRUNC(consumed_old, buf->chan)
-//            >> ltt_channel->n_subbufs_order)
-//         != 0) {
-//             return -EAGAIN;
-//     }
-//     /*
-//      * Check that we are not about to read the same subbuffer in
-//      * which the writer head is.
-//      */
-//     if ((SUBBUF_TRUNC(write_offset, buf->chan)
-//        - SUBBUF_TRUNC(consumed_old, buf->chan))
-//        == 0) {
-//             return -EAGAIN;
-//     }
-//
-//     *pconsumed_old = consumed_old;
-//     return 0;
-//}
-
 void *consumer_thread(void *arg)
 {
        struct buffer_info *buf = (struct buffer_info *) arg;
        int result;
-       int died = 0;
 
        for(;;) {
                /* get the subbuffer */
-               if(died == 0) {
-                       result = get_subbuffer(buf);
-                       if(result == -1) {
-                               ERR("error getting subbuffer");
-                               continue;
-                       }
-                       else if(result == GET_SUBBUF_DONE) {
-                               /* this is done */
-                               break;
-                       }
-                       else if(result == GET_SUBBUF_DIED) {
-                               died = 1;
-                       }
+               result = get_subbuffer(buf);
+               if(result == -1) {
+                       ERR("error getting subbuffer");
+                       continue;
                }
-               if(died == 1) {
-                       result = get_subbuffer_died(buf);
-                       if(result <= 0) {
-                               break;
-                       }
+               else if(result == GET_SUBBUF_DONE) {
+                       /* this is done */
+                       break;
+               }
+               else if(result == GET_SUBBUF_DIED) {
+                       finish_consuming_dead_subbuffer(buf);
+                       break;
                }
 
                /* write data to file */
@@ -254,15 +173,10 @@ void *consumer_thread(void *arg)
                }
 
                /* put the subbuffer */
-               if(died == 0) {
-                       result = put_subbuffer(buf);
-                       if(result == -1) {
-                               ERR("error putting subbuffer");
-                               break;
-                       }
-               }
-               else {
-//                     result = put_subbuffer_died(buf);
+               result = put_subbuffer(buf);
+               if(result == -1) {
+                       ERR("error putting subbuffer");
+                       break;
                }
        }
 
diff --git a/ustd/ustd.h b/ustd/ustd.h
new file mode 100644 (file)
index 0000000..7296813
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef USTD_H
+#define USTD_H
+
+#include "ustcomm.h"
+
+struct buffer_info {
+       char *name;
+       pid_t pid;
+       struct ustcomm_connection conn;
+
+       int shmid;
+       int bufstruct_shmid;
+
+       /* the buffer memory */
+       void *mem;
+       /* buffer size */
+       int memlen;
+       /* number of subbuffers in buffer */
+       int n_subbufs;
+       /* size of each subbuffer */
+       int subbuf_size;
+
+       /* the buffer information struct */
+       void *bufstruct_mem;
+
+       int file_fd; /* output file */
+
+       struct list_head list;
+
+       long consumed_old;
+};
+
+ssize_t patient_write(int fd, const void *buf, size_t count);
+
+void finish_consuming_dead_subbuffer(struct buffer_info *buf);
+
+#endif /* USTD_H */
This page took 0.031813 seconds and 4 git commands to generate.