Fix: pre-fault TLS in ust-malloc instrumentation
[lttng-ust.git] / libringbuffer / ring_buffer_frontend.c
index 45d46054cf45b2e6b4025a2f15e068068968a1f8..908539a8663973fde0a8e51384907b4690b0e30d 100644 (file)
 #include "tlsfixup.h"
 #include "../liblttng-ust/compat.h"    /* For ENODATA */
 
-#ifndef max
-#define max(a, b)      ((a) > (b) ? (a) : (b))
-#endif
-
 /* Print DBG() messages about events lost only every 1048576 hits */
 #define DBG_PRINT_NR_LOST      (1UL << 20)
 
@@ -164,10 +160,14 @@ static struct timer_signal_data timer_signal = {
 void lib_ring_buffer_reset(struct lttng_ust_lib_ring_buffer *buf,
                           struct lttng_ust_shm_handle *handle)
 {
-       struct channel *chan = shmp(handle, buf->backend.chan);
-       const struct lttng_ust_lib_ring_buffer_config *config = &chan->backend.config;
+       struct channel *chan;
+       const struct lttng_ust_lib_ring_buffer_config *config;
        unsigned int i;
 
+       chan = shmp(handle, buf->backend.chan);
+       if (!chan)
+               abort();
+       config = &chan->backend.config;
        /*
         * Reset iterator first. It will put the subbuffer if it currently holds
         * it.
@@ -400,6 +400,9 @@ void lib_ring_buffer_channel_switch_timer(int sig, siginfo_t *si, void *uc)
                for_each_possible_cpu(cpu) {
                        struct lttng_ust_lib_ring_buffer *buf =
                                shmp(handle, chan->backend.buf[cpu].shmp);
+
+                       if (!buf)
+                               abort();
                        if (uatomic_read(&buf->active_readers))
                                lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE,
                                        chan->handle);
@@ -408,6 +411,8 @@ void lib_ring_buffer_channel_switch_timer(int sig, siginfo_t *si, void *uc)
                struct lttng_ust_lib_ring_buffer *buf =
                        shmp(handle, chan->backend.buf[0].shmp);
 
+               if (!buf)
+                       abort();
                if (uatomic_read(&buf->active_readers))
                        lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE,
                                chan->handle);
@@ -435,6 +440,8 @@ void lib_ring_buffer_channel_do_read(struct channel *chan)
                        struct lttng_ust_lib_ring_buffer *buf =
                                shmp(handle, chan->backend.buf[cpu].shmp);
 
+                       if (!buf)
+                               abort();
                        if (uatomic_read(&buf->active_readers)
                            && lib_ring_buffer_poll_deliver(config, buf,
                                        chan, handle)) {
@@ -445,6 +452,8 @@ void lib_ring_buffer_channel_do_read(struct channel *chan)
                struct lttng_ust_lib_ring_buffer *buf =
                        shmp(handle, chan->backend.buf[0].shmp);
 
+               if (!buf)
+                       abort();
                if (uatomic_read(&buf->active_readers)
                    && lib_ring_buffer_poll_deliver(config, buf,
                                chan, handle)) {
@@ -629,7 +638,7 @@ void lib_ring_buffer_channel_switch_timer_start(struct channel *chan)
        }
 
        its.it_value.tv_sec = chan->switch_timer_interval / 1000000;
-       its.it_value.tv_nsec = chan->switch_timer_interval % 1000000;
+       its.it_value.tv_nsec = (chan->switch_timer_interval % 1000000) * 1000;
        its.it_interval.tv_sec = its.it_value.tv_sec;
        its.it_interval.tv_nsec = its.it_value.tv_nsec;
 
@@ -683,7 +692,7 @@ void lib_ring_buffer_channel_read_timer_start(struct channel *chan)
        }
 
        its.it_value.tv_sec = chan->read_timer_interval / 1000000;
-       its.it_value.tv_nsec = chan->read_timer_interval % 1000000;
+       its.it_value.tv_nsec = (chan->read_timer_interval % 1000000) * 1000;
        its.it_interval.tv_sec = its.it_value.tv_sec;
        its.it_interval.tv_nsec = its.it_value.tv_nsec;
 
@@ -1479,7 +1488,8 @@ void lib_ring_buffer_print_errors(struct channel *chan,
 /*
  * lib_ring_buffer_switch_old_start: Populate old subbuffer header.
  *
- * Only executed when the buffer is finalized, in SWITCH_FLUSH.
+ * Only executed by SWITCH_FLUSH, which can be issued while tracing is
+ * active or at buffer finalization (destroy).
  */
 static
 void lib_ring_buffer_switch_old_start(struct lttng_ust_lib_ring_buffer *buf,
@@ -1653,12 +1663,14 @@ int lib_ring_buffer_try_switch_slow(enum switch_mode mode,
                unsigned long sb_index, commit_count;
 
                /*
-                * We are performing a SWITCH_FLUSH. At this stage, there are no
-                * concurrent writes into the buffer.
+                * We are performing a SWITCH_FLUSH. There may be concurrent
+                * writes into the buffer if e.g. invoked while performing a
+                * snapshot on an active trace.
                 *
-                * The client does not save any header information.  Don't
-                * switch empty subbuffer on finalize, because it is invalid to
-                * deliver a completely empty subbuffer.
+                * If the client does not save any header information
+                * (sub-buffer header size == 0), don't switch empty subbuffer
+                * on finalize, because it is invalid to deliver a completely
+                * empty subbuffer.
                 */
                if (!config->cb.subbuffer_header_size())
                        return -1;
This page took 0.029566 seconds and 4 git commands to generate.