Introduce "--blocking-timeout" channel parameter
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 27 May 2017 06:17:39 +0000 (08:17 +0200)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 12 Jun 2017 22:10:53 +0000 (18:10 -0400)
Introduce the blocking timeout channel parameter to control blocking
behavior for lttng-ust buffers. It only affects applications launched
with the LTTNG_UST_ALLOW_BLOCKING environment variable.

The blocking timeout parameter expects:

- 0 (default) which does not block,
- a timeout value in usec,
- -1 (block forever).

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
25 files changed:
configure.ac
doc/man/lttng-enable-channel.1.txt
include/lttng/channel-internal.h
include/lttng/channel.h
src/bin/lttng-sessiond/channel.c
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/consumer.c
src/bin/lttng-sessiond/consumer.h
src/bin/lttng-sessiond/lttng-ust-abi.h
src/bin/lttng-sessiond/lttng-ust-ctl.h
src/bin/lttng-sessiond/trace-ust.c
src/bin/lttng-sessiond/ust-app.c
src/bin/lttng-sessiond/ust-consumer.c
src/bin/lttng/commands/enable_channels.c
src/bin/lttng/commands/list.c
src/common/config/config-session-abi.h
src/common/config/session-config.c
src/common/config/session.xsd
src/common/defaults.h
src/common/mi-lttng-3.0.xsd
src/common/mi-lttng.c
src/common/sessiond-comm/sessiond-comm.h
src/common/ust-consumer/ust-consumer.c
src/lib/lttng-ctl/lttng-ctl.c
tests/regression/ust/blocking/test_blocking

index 37b036eed361eb971022a566e08780cad858bc4d..9daa61611de33be24aa0765da6628f3811f1471b 100644 (file)
@@ -301,6 +301,7 @@ m4_define([_DEFAULT_CHANNEL_SWITCH_TIMER], [0])
 m4_define([_DEFAULT_CHANNEL_LIVE_TIMER], [0])
 m4_define([_DEFAULT_CHANNEL_READ_TIMER], [200000])
 m4_define([_DEFAULT_CHANNEL_MONITOR_TIMER], [1000000])
+m4_define([_DEFAULT_CHANNEL_BLOCKING_TIMEOUT], [0])
 _AC_DEFINE_AND_SUBST([DEFAULT_AGENT_TCP_PORT], [5345])
 _AC_DEFINE_AND_SUBST([DEFAULT_APP_SOCKET_RW_TIMEOUT], [5])
 _AC_DEFINE_AND_SUBST([DEFAULT_CHANNEL_SUBBUF_SIZE], [_DEFAULT_CHANNEL_SUBBUF_SIZE])
@@ -312,6 +313,7 @@ _AC_DEFINE_AND_SUBST([DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM], [_DEFAULT_CHANNEL_SUBB
 _AC_DEFINE_AND_SUBST([DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE], [1048576])
 _AC_DEFINE_AND_SUBST([DEFAULT_KERNEL_CHANNEL_SWITCH_TIMER], [_DEFAULT_CHANNEL_SWITCH_TIMER])
 _AC_DEFINE_AND_SUBST([DEFAULT_KERNEL_CHANNEL_MONITOR_TIMER], [_DEFAULT_CHANNEL_MONITOR_TIMER])
+_AC_DEFINE_AND_SUBST([DEFAULT_KERNEL_CHANNEL_BLOCKING_TIMEOUT], [_DEFAULT_CHANNEL_BLOCKING_TIMEOUT])
 _AC_DEFINE_AND_SUBST([DEFAULT_LTTNG_LIVE_TIMER], [1000000])
 _AC_DEFINE_AND_SUBST([DEFAULT_METADATA_CACHE_SIZE], [4096])
 _AC_DEFINE_AND_SUBST([DEFAULT_METADATA_READ_TIMER], [0])
@@ -323,12 +325,14 @@ _AC_DEFINE_AND_SUBST([DEFAULT_NETWORK_DATA_PORT], [5343])
 _AC_DEFINE_AND_SUBST([DEFAULT_NETWORK_VIEWER_PORT], [5344])
 _AC_DEFINE_AND_SUBST([DEFAULT_UST_PID_CHANNEL_LIVE_TIMER], [_DEFAULT_CHANNEL_LIVE_TIMER])
 _AC_DEFINE_AND_SUBST([DEFAULT_UST_PID_CHANNEL_READ_TIMER], [0])
+_AC_DEFINE_AND_SUBST([DEFAULT_UST_PID_CHANNEL_BLOCKING_TIMEOUT], [0])
 _AC_DEFINE_AND_SUBST([DEFAULT_UST_PID_CHANNEL_SUBBUF_NUM], [_DEFAULT_CHANNEL_SUBBUF_NUM])
 _AC_DEFINE_AND_SUBST([DEFAULT_UST_PID_CHANNEL_SUBBUF_SIZE], [_DEFAULT_CHANNEL_SUBBUF_SIZE])
 _AC_DEFINE_AND_SUBST([DEFAULT_UST_PID_CHANNEL_SWITCH_TIMER], [_DEFAULT_CHANNEL_SWITCH_TIMER])
 _AC_DEFINE_AND_SUBST([DEFAULT_UST_PID_CHANNEL_MONITOR_TIMER], [_DEFAULT_CHANNEL_MONITOR_TIMER])
 _AC_DEFINE_AND_SUBST([DEFAULT_UST_UID_CHANNEL_LIVE_TIMER], [_DEFAULT_CHANNEL_LIVE_TIMER])
 _AC_DEFINE_AND_SUBST([DEFAULT_UST_UID_CHANNEL_READ_TIMER], [0])
+_AC_DEFINE_AND_SUBST([DEFAULT_UST_UID_CHANNEL_BLOCKING_TIMEOUT], [0])
 _AC_DEFINE_AND_SUBST([DEFAULT_UST_UID_CHANNEL_SUBBUF_NUM], [_DEFAULT_CHANNEL_SUBBUF_NUM])
 _AC_DEFINE_AND_SUBST([DEFAULT_UST_UID_CHANNEL_SUBBUF_SIZE], [524288])
 _AC_DEFINE_AND_SUBST([DEFAULT_UST_UID_CHANNEL_SWITCH_TIMER], [_DEFAULT_CHANNEL_SWITCH_TIMER])
index f9b0b1f5a59da57eb99e0a0722d2269fcf479776..d66d2fb51228064ddfa0105445ad47a5e9e4dcfe 100644 (file)
@@ -26,6 +26,7 @@ Create a user space channel:
       [option:--overwrite] [option:--buffers-pid]
       [option:--subbuf-size='SIZE'] [option:--num-subbuf='COUNT']
       [option:--switch-timer='PERIODUS'] [option:--read-timer='PERIODUS']
+      [option:--blocking-timeout='TIMEOUTUS']
       [option:--tracefile-size='SIZE'] [option:--tracefile-count='COUNT']
       [option:--session='SESSION'] 'CHANNEL'
 
@@ -358,6 +359,16 @@ Default values:
 * option:--kernel option: {default_kernel_channel_switch_timer}
 * `metadata` channel: {default_metadata_switch_timer}
 
+Timeouts
+~~~~~~~~
+option:--blocking-timeout:
+    Set the channel's blocking timeout value to 'TIMEOUTUS' µs. 0
+    (default) does not block. -1 blocks forever until room is
+    available in the buffer to write the event. Positive
+    values are a timeout bounding the maximum blocking time
+    when trying to write into the buffer. Note that this option
+    only affects applications launched with the
+    LTTNG_UST_ALLOW_BLOCKING environment variable set.
 
 include::common-cmd-help-options.txt[]
 
@@ -385,4 +396,5 @@ include::common-cmd-footer.txt[]
 SEE ALSO
 --------
 man:lttng-disable-channel(1),
-man:lttng(1)
+man:lttng(1),
+man:lttng-ust(3)
index d78a720d4e378dc183c0101740892eac1eec8a35..53171f42c639554d5ed432cca16e35964f3169c0 100644 (file)
@@ -22,6 +22,7 @@ struct lttng_channel_extended {
        uint64_t discarded_events;
        uint64_t lost_packets;
        uint64_t monitor_timer_interval;
+       int64_t blocking_timeout;
 } LTTNG_PACKED;
 
 #endif /* LTTNG_CHANNEL_INTERNAL_H */
index e20ed4f4fce981cff071482817ca5108677df026..4e61a611b4c4b2f19f83dd8950165a766d711325 100644 (file)
@@ -138,6 +138,12 @@ extern int lttng_channel_get_monitor_timer_interval(struct lttng_channel *chan,
 extern int lttng_channel_set_monitor_timer_interval(struct lttng_channel *chan,
                uint64_t monitor_timer_interval);
 
+extern int lttng_channel_get_blocking_timeout(struct lttng_channel *chan,
+               int64_t *blocking_timeout);
+
+extern int lttng_channel_set_blocking_timeout(struct lttng_channel *chan,
+               int64_t blocking_timeout);
+
 #ifdef __cplusplus
 }
 #endif
index 8a88eccedb62ab788835468f56f193ce86d9b8fc..5aa0cd82b60884782e7a60644c0715e9b8e10176 100644 (file)
@@ -72,6 +72,7 @@ struct lttng_channel *channel_new_default_attr(int dom,
                chan->attr.switch_timer_interval = DEFAULT_KERNEL_CHANNEL_SWITCH_TIMER;
                chan->attr.read_timer_interval = DEFAULT_KERNEL_CHANNEL_READ_TIMER;
                chan->attr.live_timer_interval = DEFAULT_KERNEL_CHANNEL_LIVE_TIMER;
+               extended_attr->blocking_timeout = DEFAULT_KERNEL_CHANNEL_BLOCKING_TIMEOUT;
                extended_attr->monitor_timer_interval =
                        DEFAULT_KERNEL_CHANNEL_MONITOR_TIMER;
                break;
@@ -97,6 +98,7 @@ common_ust:
                                DEFAULT_UST_UID_CHANNEL_READ_TIMER;
                        chan->attr.live_timer_interval =
                                DEFAULT_UST_UID_CHANNEL_LIVE_TIMER;
+                       extended_attr->blocking_timeout = DEFAULT_UST_UID_CHANNEL_BLOCKING_TIMEOUT;
                        extended_attr->monitor_timer_interval =
                                DEFAULT_UST_UID_CHANNEL_MONITOR_TIMER;
                        break;
@@ -111,6 +113,7 @@ common_ust:
                                DEFAULT_UST_PID_CHANNEL_READ_TIMER;
                        chan->attr.live_timer_interval =
                                DEFAULT_UST_PID_CHANNEL_LIVE_TIMER;
+                       extended_attr->blocking_timeout = DEFAULT_UST_PID_CHANNEL_BLOCKING_TIMEOUT;
                        extended_attr->monitor_timer_interval =
                                DEFAULT_UST_PID_CHANNEL_MONITOR_TIMER;
                        break;
@@ -217,6 +220,15 @@ static int channel_validate(struct lttng_channel *attr)
        return 0;
 }
 
+static int channel_validate_kernel(struct lttng_channel *attr)
+{
+       /* Kernel channels do not support blocking timeout. */
+       if (((struct lttng_channel_extended *)attr->attr.extended.ptr)->blocking_timeout) {
+               return -1;
+       }
+       return 0;
+}
+
 /*
  * Create kernel channel of the kernel session and notify kernel thread.
  */
@@ -258,6 +270,11 @@ int channel_kernel_create(struct ltt_kernel_session *ksession,
                goto error;
        }
 
+       if (channel_validate_kernel(attr) < 0) {
+               ret = LTTNG_ERR_INVALID;
+               goto error;
+       }
+
        /* Channel not found, creating it */
        ret = kernel_create_channel(ksession, attr);
        if (ret < 0) {
index 9e761958a19ffc1138f62186c9ddecc47b9515c4..b836f3d8f5a4c71b408731c3dcdfe1e394e3147e 100644 (file)
@@ -277,6 +277,7 @@ static ssize_t list_lttng_channels(enum lttng_domain_type domain,
                                chan_exts[i].lost_packets = lost_packets;
                                chan_exts[i].monitor_timer_interval =
                                                extended->monitor_timer_interval;
+                               chan_exts[i].blocking_timeout = 0;
                                i++;
                        }
                }
@@ -324,6 +325,8 @@ static ssize_t list_lttng_channels(enum lttng_domain_type domain,
 
                        chan_exts[i].monitor_timer_interval =
                                        uchan->monitor_timer_interval;
+                       chan_exts[i].blocking_timeout =
+                               uchan->attr.u.s.blocking_timeout;
 
                        ret = get_ust_runtime_stats(session, uchan,
                                        &discarded_events, &lost_packets);
index 4a7287b61ba78f46365b76ffc1fd011525d82064..33ccfe2248c91bd50fa0a4c94489790404e24264 100644 (file)
@@ -822,6 +822,7 @@ void consumer_init_ask_channel_comm_msg(struct lttcomm_consumer_msg *msg,
                uint64_t session_id_per_pid,
                unsigned int monitor,
                uint32_t ust_app_uid,
+               int64_t blocking_timeout,
                const char *root_shm_path,
                const char *shm_path)
 {
@@ -851,6 +852,7 @@ void consumer_init_ask_channel_comm_msg(struct lttcomm_consumer_msg *msg,
        msg->u.ask_channel.tracefile_count = tracefile_count;
        msg->u.ask_channel.monitor = monitor;
        msg->u.ask_channel.ust_app_uid = ust_app_uid;
+       msg->u.ask_channel.blocking_timeout = blocking_timeout;
 
        memcpy(msg->u.ask_channel.uuid, uuid, sizeof(msg->u.ask_channel.uuid));
 
index 77bc2b1f12b8cf6c08a7fc402a953be4ce86a296..b8d5630f472aed7b37e16a5ad9827fdb205bf0b0 100644 (file)
@@ -256,6 +256,7 @@ void consumer_init_ask_channel_comm_msg(struct lttcomm_consumer_msg *msg,
                uint64_t session_id_per_pid,
                unsigned int monitor,
                uint32_t ust_app_uid,
+               int64_t blocking_timeout,
                const char *root_shm_path,
                const char *shm_path);
 void consumer_init_stream_comm_msg(struct lttcomm_consumer_msg *msg,
index 972de0c34022b908f1472ece4312c6f73792e887..687eb0b231991b6c559b933720fa3f3af20ed004 100644 (file)
@@ -181,7 +181,12 @@ struct lttng_ust_channel_attr {
        unsigned int switch_timer_interval;     /* usec */
        unsigned int read_timer_interval;       /* usec */
        enum lttng_ust_output output;           /* splice, mmap */
-       char padding[LTTNG_UST_CHANNEL_ATTR_PADDING];
+       union {
+               struct {
+                       int64_t blocking_timeout;       /* Retry timeout (usec) */
+               } s;
+               char padding[LTTNG_UST_CHANNEL_ATTR_PADDING];
+       } u;
 } LTTNG_PACKED;
 
 #define LTTNG_UST_TRACEPOINT_ITER_PADDING      16
index cba0e272d6a37a47d9e14b7893ef8aab0f0f861e..1d67e858caa44fc7c899face35928e8bbd6f5834 100644 (file)
@@ -53,6 +53,7 @@ struct ustctl_consumer_channel_attr {
        enum lttng_ust_output output;           /* splice, mmap */
        uint32_t chan_id;           /* channel ID */
        unsigned char uuid[LTTNG_UST_UUID_LEN]; /* Trace session unique ID */
+       int64_t blocking_timeout;                       /* Retry timeout (usec) */
 } LTTNG_PACKED;
 
 /*
index 314c21e3804b2b35c899da154bd35889e48b4d00..bcb04fe5733c4b1c8779b023b481fe6875dc4438 100644 (file)
@@ -358,6 +358,8 @@ struct ltt_ust_channel *trace_ust_create_channel(struct lttng_channel *chan,
        luc->attr.output = (enum lttng_ust_output) chan->attr.output;
        luc->monitor_timer_interval = ((struct lttng_channel_extended *)
                        chan->attr.extended.ptr)->monitor_timer_interval;
+       luc->attr.u.s.blocking_timeout = ((struct lttng_channel_extended *)
+                       chan->attr.extended.ptr)->blocking_timeout;
 
        /* Translate to UST output enum */
        switch (luc->attr.output) {
index 98f45e05561ea53fbeaf7918ac85aa9cbd402f8e..eb0f837160edf5b533bbc822ef0e8ddd768962f4 100644 (file)
@@ -92,6 +92,7 @@ static void copy_channel_attr_to_ustctl(
        attr->switch_timer_interval = uattr->switch_timer_interval;
        attr->read_timer_interval = uattr->read_timer_interval;
        attr->output = uattr->output;
+       attr->blocking_timeout = uattr->u.s.blocking_timeout;
 }
 
 /*
@@ -1040,6 +1041,7 @@ struct ust_app_channel *alloc_ust_app_channel(char *name,
                ua_chan->attr.switch_timer_interval = attr->switch_timer_interval;
                ua_chan->attr.read_timer_interval = attr->read_timer_interval;
                ua_chan->attr.output = attr->output;
+               ua_chan->attr.blocking_timeout = attr->u.s.blocking_timeout;
        }
        /* By default, the channel is a per cpu channel. */
        ua_chan->attr.type = LTTNG_UST_CHAN_PER_CPU;
@@ -1803,6 +1805,8 @@ static void shadow_copy_channel(struct ust_app_channel *ua_chan,
        ua_chan->attr.read_timer_interval = uchan->attr.read_timer_interval;
        ua_chan->monitor_timer_interval = uchan->monitor_timer_interval;
        ua_chan->attr.output = uchan->attr.output;
+       ua_chan->attr.blocking_timeout = uchan->attr.u.s.blocking_timeout;
+
        /*
         * Note that the attribute channel type is not set since the channel on the
         * tracing registry side does not have this information.
index fe2c8f4c8055b41048e6b9645ab7e2e2572f5c21..43bf2616a2c4a93ba91f81f2a6f60476289dbe7c 100644 (file)
@@ -192,6 +192,7 @@ static int ask_channel_creation(struct ust_app_session *ua_sess,
                        ua_sess->id,
                        ua_sess->output_traces,
                        ua_sess->uid,
+                       ua_chan->attr.blocking_timeout,
                        root_shm_path, shm_path);
 
        health_code_update();
index 22331cec2b2ead8d032ede422df7f581df4f7c38..27d4618a9d0fd5b2f40f7c0dd7b05055bbd90d79 100644 (file)
@@ -48,6 +48,10 @@ static struct {
        bool set;
        uint32_t interval;
 } opt_monitor_timer;
+static struct {
+       bool set;
+       int64_t value;
+} opt_blocking_timeout;
 
 static struct mi_writer *writer;
 
@@ -70,6 +74,7 @@ enum {
        OPT_LIST_OPTIONS,
        OPT_TRACEFILE_SIZE,
        OPT_TRACEFILE_COUNT,
+       OPT_BLOCKING_TIMEOUT,
 };
 
 static struct lttng_handle *handle;
@@ -97,6 +102,7 @@ static struct poptOption long_options[] = {
        {"buffers-global", 0,   POPT_ARG_VAL, &opt_buffer_global, 1, 0, 0},
        {"tracefile-size", 'C',   POPT_ARG_INT, 0, OPT_TRACEFILE_SIZE, 0, 0},
        {"tracefile-count", 'W',   POPT_ARG_INT, 0, OPT_TRACEFILE_COUNT, 0, 0},
+       {"blocking-timeout",     0,   POPT_ARG_INT, 0, OPT_BLOCKING_TIMEOUT, 0, 0},
        {0, 0, 0, 0, 0, 0, 0}
 };
 
@@ -151,6 +157,15 @@ static int enable_channel(char *session_name)
 
        memset(&dom, 0, sizeof(dom));
 
+       /* Validate options. */
+       if (opt_kernel) {
+               if (opt_blocking_timeout.set) {
+                       ERR("Retry timeout option not supported for kernel domain (-k)");
+                       ret = CMD_ERROR;
+                       goto error;
+               }
+       }
+
        /* Create lttng domain */
        if (opt_kernel) {
                dom.type = LTTNG_DOMAIN_KERNEL;
@@ -262,6 +277,15 @@ static int enable_channel(char *session_name)
                                goto error;
                        }
                }
+               if (opt_blocking_timeout.set) {
+                       ret = lttng_channel_set_blocking_timeout(channel,
+                                       opt_blocking_timeout.value);
+                       if (ret) {
+                               ERR("Failed to set the channel's blocking timeout");
+                               error = 1;
+                               goto error;
+                       }
+               }
 
                DBG("Enabling channel %s", channel_name);
 
@@ -530,6 +554,51 @@ int cmd_enable_channels(int argc, const char **argv)
                        DBG("Channel monitor timer interval set to %d", opt_monitor_timer.interval);
                        break;
                }
+               case OPT_BLOCKING_TIMEOUT:
+               {
+                       long long v;    /* in usec */
+                       long long v_msec;
+
+                       errno = 0;
+                       opt_arg = poptGetOptArg(pc);
+                       v = strtoll(opt_arg, NULL, 0);
+                       if (errno != 0 || (!isdigit(opt_arg[0]) && opt_arg[0] != '-')
+                                       || v < -1) {
+                               ERR("Wrong value in --blocking-timeout parameter: %s", opt_arg);
+                               ret = CMD_ERROR;
+                               goto end;
+                       }
+                       if (v >= 0) {
+                               /*
+                                * While LTTng-UST and LTTng-tools will accept
+                                * a blocking timeout expressed in µs, the
+                                * current tracer implementation relies on
+                                * poll() which takes an "int timeout" parameter
+                                * expressed in msec.
+                                *
+                                * Since the error reporting from the tracer
+                                * is not precise, we perform this check here
+                                * to provide a helpful error message in case of
+                                * overflow.
+                                *
+                                * The setter (liblttng-ctl) also performs an
+                                * equivalent check.
+                                */
+                               v_msec = v / 1000;
+                               if (v_msec != (int32_t) v_msec) {
+                                       ERR("32-bit milliseconds overflow in --blocking-timeout parameter: %s", opt_arg);
+                                       ret = CMD_ERROR;
+                                       goto end;
+                               }
+                       } else if (v != -1) {
+                               ERR("Invalid negative value passed as --blocking-timeout parameter; -1 (block forever) is the only valid negative value");
+                       }
+                       opt_blocking_timeout.value = (int64_t) v;
+                       opt_blocking_timeout.set = true;
+                       DBG("Channel blocking timeout set to %" PRId64 " (µs)",
+                                       opt_blocking_timeout.value);
+                       break;
+               }
                case OPT_USERSPACE:
                        opt_userspace = 1;
                        break;
index 1315783f34149721163cfdd125947e7dccb9bbb1..942e4a4c2c3f46a4e48ff1ce3d246b15e5f95deb 100644 (file)
@@ -1173,6 +1173,7 @@ static void print_channel(struct lttng_channel *channel)
 {
        int ret;
        uint64_t discarded_events, lost_packets, monitor_timer_interval;
+       int64_t blocking_timeout;
 
        ret = lttng_channel_get_discarded_event_count(channel,
                        &discarded_events);
@@ -1195,6 +1196,13 @@ static void print_channel(struct lttng_channel *channel)
                return;
        }
 
+       ret = lttng_channel_get_blocking_timeout(channel,
+                       &blocking_timeout);
+       if (ret) {
+               ERR("Failed to retrieve blocking timeout of channel");
+               return;
+       }
+
        MSG("- %s:%s\n", channel->name, enabled_string(channel->enabled));
 
        MSG("%sAttributes:", indent4);
@@ -1204,6 +1212,7 @@ static void print_channel(struct lttng_channel *channel)
        MSG("%sswitch timer interval: %u", indent6, channel->attr.switch_timer_interval);
        MSG("%sread timer interval: %u", indent6, channel->attr.read_timer_interval);
        MSG("%smonitor timer interval: %" PRIu64, indent6, monitor_timer_interval);
+       MSG("%sblocking timeout (µs): %" PRId64, indent6, blocking_timeout);
        MSG("%strace file count: %" PRIu64, indent6, channel->attr.tracefile_count);
        MSG("%strace file size (bytes): %" PRIu64, indent6, channel->attr.tracefile_size);
        MSG("%sdiscarded events: %" PRIu64, indent6, discarded_events);
index 2faa354a0d05136d939dc83ae24abcd818e64269..5f91109ccda1ff90cb71d97159dde6e696c4c905 100644 (file)
@@ -42,6 +42,7 @@ extern const char * const config_element_num_subbuf;
 extern const char * const config_element_switch_timer_interval;
 extern const char * const config_element_read_timer_interval;
 extern const char * const config_element_monitor_timer_interval;
+extern const char * const config_element_blocking_timeout;
 extern const char * const config_element_output;
 extern const char * const config_element_output_type;
 extern const char * const config_element_tracefile_size;
index 69b62d7523b6cd286df13f6bddb918bba5f726ce..a62931201c9dfb04a4c31c000f91f25ce7b56abf 100644 (file)
@@ -92,6 +92,7 @@ const char * const config_element_num_subbuf = "subbuffer_count";
 const char * const config_element_switch_timer_interval = "switch_timer_interval";
 const char * const config_element_read_timer_interval = "read_timer_interval";
 const char * const config_element_monitor_timer_interval = "monitor_timer_interval";
+const char * const config_element_blocking_timeout = "blocking_timeout";
 const char * const config_element_output = "output";
 const char * const config_element_output_type = "output_type";
 const char * const config_element_tracefile_size = "tracefile_size";
index 550fea0ee2376d427860d0b1a6744aad003558dc..6efdc433caefc115f3a01e498e306ff4cb5584a1 100644 (file)
@@ -43,6 +43,18 @@ elementFormDefault="qualified" version="2.8">
        </xs:restriction>
 </xs:simpleType>
 
+<!--
+Maps to the range allowed for blocking timeout: -1 (block forever),
+0 (do not block), positive integer value (blocking time in usec) limited
+by its signed 32-bit representation when converted to msec.
+-->
+<xs:simpleType name="blocking_timeout_type">
+       <xs:restriction base="xs:integer">
+               <xs:minInclusive value="-1" />
+               <xs:maxInclusive value="2147483648000" />
+       </xs:restriction>
+</xs:simpleType>
+
 <xs:simpleType name="channel_overwrite_mode_type">
        <xs:restriction base="xs:string">
                <xs:enumeration value="DISCARD"/>
@@ -186,6 +198,7 @@ elementFormDefault="qualified" version="2.8">
                <xs:element name="subbuffer_count" type="uint64_type" default="4" minOccurs="0"/>
                <xs:element name="switch_timer_interval" type="uint32_type" default="0" minOccurs="0"/>  <!-- usec -->
                <xs:element name="read_timer_interval" type="uint32_type"/>  <!-- usec -->
+               <xs:element name="blocking_timeout" type="blocking_timeout_type" default="0" minOccurs="0" /> <!-- usec -->
                <xs:element name="output_type" type="event_output_type"/>
                <xs:element name="tracefile_size" type="uint64_type" default="0" minOccurs="0"/> <!-- bytes -->
                <xs:element name="tracefile_count" type="uint64_type" default="0" minOccurs="0"/>
index 1e6a1171d14fb44a5eafa2fe8f80558fb16e6fa3..8669a84129e604276e7f6f8f8b6be9878cdaf0d8 100644 (file)
 #define DEFAULT_KERNEL_CHANNEL_MONITOR_TIMER   CONFIG_DEFAULT_KERNEL_CHANNEL_MONITOR_TIMER
 #define DEFAULT_KERNEL_CHANNEL_READ_TIMER      CONFIG_DEFAULT_KERNEL_CHANNEL_READ_TIMER
 #define DEFAULT_KERNEL_CHANNEL_LIVE_TIMER      CONFIG_DEFAULT_KERNEL_CHANNEL_LIVE_TIMER
+#define DEFAULT_KERNEL_CHANNEL_BLOCKING_TIMEOUT        CONFIG_DEFAULT_KERNEL_CHANNEL_BLOCKING_TIMEOUT
 
 /* User space defaults */
 
 #define DEFAULT_UST_PID_CHANNEL_READ_TIMER      CONFIG_DEFAULT_UST_PID_CHANNEL_READ_TIMER
 #define DEFAULT_UST_UID_CHANNEL_READ_TIMER      CONFIG_DEFAULT_UST_UID_CHANNEL_READ_TIMER
 
+#define DEFAULT_UST_PID_CHANNEL_BLOCKING_TIMEOUT       CONFIG_DEFAULT_UST_PID_CHANNEL_BLOCKING_TIMEOUT
+#define DEFAULT_UST_UID_CHANNEL_BLOCKING_TIMEOUT       CONFIG_DEFAULT_UST_UID_CHANNEL_BLOCKING_TIMEOUT
+
 /*
  * Default timeout value for the sem_timedwait() call. Blocking forever is not
  * wanted so a timeout is used to control the data flow and not freeze the
index 56b65a364d7c8a0110f124a58ab9860e8b7491f9..8b2e45359ec173a4f2938df32ae1581fba08fe87 100644 (file)
@@ -43,6 +43,19 @@ THE SOFTWARE.
                </xs:restriction>
        </xs:simpleType>
 
+       <!--
+       Maps to the range allowed for blocking timeout: -1 (block
+       forever), 0 (do not block), positive integer value (blocking
+       time in usec) limited by its signed 32-bit representation when
+       converted to msec.
+       -->
+       <xs:simpleType name="blocking_timeout_type">
+               <xs:restriction base="xs:integer">
+                       <xs:minInclusive value="-1" />
+                       <xs:maxInclusive value="2147483648000" />
+               </xs:restriction>
+       </xs:simpleType>
+
        <!-- Maps to the char name[LTTNG_SYMBOL_NAME_LEN] -->
        <xs:simpleType name="name_type">
                <xs:restriction base="xs:string">
@@ -363,6 +376,7 @@ THE SOFTWARE.
                        <xs:element name="discarded_events" type="tns:uint64_type" default="0" minOccurs="0" />
                        <xs:element name="lost_packets" type="tns:uint64_type" default="0" minOccurs="0" />
                        <xs:element name="monitor_timer_interval" type="tns:uint64_type" default="0" minOccurs="0" />
+                       <xs:element name="blocking_timeout" type="tns:blocking_timeout_type" default="0" minOccurs="0" />
                </xs:all>
        </xs:complexType>
 
index 197add2d470518bf0e18f4f2ecc16320d8a88265..9c1597b363f67a7ed230443160f81a434f6dea35 100644 (file)
@@ -863,6 +863,7 @@ int mi_lttng_channel_attr(struct mi_writer *writer,
        struct lttng_channel *chan = caa_container_of(attr,
                        struct lttng_channel, attr);
        uint64_t discarded_events, lost_packets, monitor_timer_interval;
+       int64_t blocking_timeout;
 
        assert(attr);
 
@@ -882,6 +883,12 @@ int mi_lttng_channel_attr(struct mi_writer *writer,
                goto end;
        }
 
+       ret = lttng_channel_get_blocking_timeout(chan,
+                       &blocking_timeout);
+       if (ret) {
+               goto end;
+       }
+
        /* Opening Attributes */
        ret = mi_lttng_writer_open_element(writer, config_element_attributes);
        if (ret) {
@@ -936,6 +943,14 @@ int mi_lttng_channel_attr(struct mi_writer *writer,
                goto end;
        }
 
+       /* Retry timeout in usec */
+       ret = mi_lttng_writer_write_element_signed_int(writer,
+               config_element_blocking_timeout,
+               blocking_timeout);
+       if (ret) {
+               goto end;
+       }
+
        /* Event output */
        ret = mi_lttng_writer_write_element_string(writer,
                config_element_output_type,
index f6179f31dc5132838516b5c75021d32eeecd6ada..cd5ee062230c51da3826dee0cde97864af309eec 100644 (file)
@@ -482,6 +482,7 @@ struct lttcomm_consumer_msg {
                         * because the application can be in the tracing for instance.
                         */
                        uint32_t ust_app_uid;
+                       int64_t blocking_timeout;
                        char root_shm_path[PATH_MAX];
                        char shm_path[PATH_MAX];
                } LTTNG_PACKED ask_channel;
index 147fe8aafe899a092a91ee8be58357786d7f074f..99803a693f95b0beffaff9eef4313b521ce2f2e9 100644 (file)
@@ -1456,6 +1456,7 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx,
                attr.read_timer_interval = msg.u.ask_channel.read_timer_interval;
                attr.chan_id = msg.u.ask_channel.chan_id;
                memcpy(attr.uuid, msg.u.ask_channel.uuid, sizeof(attr.uuid));
+               attr.blocking_timeout= msg.u.ask_channel.blocking_timeout;
 
                /* Match channel buffer type to the UST abi. */
                switch (msg.u.ask_channel.output) {
index a8c6c9b24adc33a3b13a14b2f206ffea5edc8230..a1e10f25e82176393f92206c2779d09355c063e6 100644 (file)
@@ -2073,6 +2073,8 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain,
                if (extended) {
                        extended->monitor_timer_interval =
                                        DEFAULT_KERNEL_CHANNEL_MONITOR_TIMER;
+                       extended->blocking_timeout =
+                                       DEFAULT_KERNEL_CHANNEL_BLOCKING_TIMEOUT;
                }
                break;
        case LTTNG_DOMAIN_UST:
@@ -2088,6 +2090,8 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain,
                        if (extended) {
                                extended->monitor_timer_interval =
                                                DEFAULT_UST_UID_CHANNEL_MONITOR_TIMER;
+                               extended->blocking_timeout =
+                                               DEFAULT_UST_UID_CHANNEL_BLOCKING_TIMEOUT;
                        }
                        break;
                case LTTNG_BUFFER_PER_PID:
@@ -2102,6 +2106,8 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain,
                        if (extended) {
                                extended->monitor_timer_interval =
                                                DEFAULT_UST_PID_CHANNEL_MONITOR_TIMER;
+                               extended->blocking_timeout =
+                                               DEFAULT_UST_PID_CHANNEL_BLOCKING_TIMEOUT;
                        }
                        break;
                }
@@ -2203,6 +2209,61 @@ end:
        return ret;
 }
 
+int lttng_channel_get_blocking_timeout(struct lttng_channel *chan,
+               int64_t *blocking_timeout)
+{
+       int ret = 0;
+
+       if (!chan || !blocking_timeout) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       if (!chan->attr.extended.ptr) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       *blocking_timeout = ((struct lttng_channel_extended *)
+                       chan->attr.extended.ptr)->blocking_timeout;
+end:
+       return ret;
+}
+
+int lttng_channel_set_blocking_timeout(struct lttng_channel *chan,
+               int64_t blocking_timeout)
+{
+       int ret = 0;
+       int64_t msec_timeout;
+
+       if (!chan || !chan->attr.extended.ptr) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       if (blocking_timeout < 0 && blocking_timeout != -1) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       /*
+        * LTTng-ust's use of poll() to implement this timeout mechanism forces
+        * us to accept a narrower range of values (msecs expressed as a signed
+        * 32-bit integer).
+        */
+       msec_timeout = blocking_timeout / 1000;
+       if (msec_timeout != (int32_t) msec_timeout) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       ((struct lttng_channel_extended *)
+                       chan->attr.extended.ptr)->blocking_timeout =
+                       blocking_timeout;
+end:
+       return ret;
+}
+
 /*
  * Check if session daemon is alive.
  *
index 261e0b8b3f3f40d72dbd96f18a163f077a5e51ec..c5c95903b0190f06efe639691129fc8d1d923496 100755 (executable)
@@ -20,13 +20,14 @@ TEST_DESC="UST - Blocking mode"
 CURDIR=$(dirname $0)/
 TESTDIR=$CURDIR/../../..
 SESSION_NAME="blocking"
+CHANNEL_NAME="testchan"
 
 TESTAPP_PATH="$TESTDIR/utils/testapp"
 TESTAPP_NAME="gen-ust-events"
 TESTAPP_BIN="$TESTAPP_PATH/$TESTAPP_NAME/$TESTAPP_NAME"
 EVENT_NAME="tp:tptest"
 
-NUM_TESTS=45
+NUM_TESTS=49
 
 source $TESTDIR/utils/utils.sh
 
@@ -40,11 +41,11 @@ function run_app()
 
 function test_ust_implicit_no_blocking()
 {
-       NUM_EVENT=500000
+       NUM_EVENT=5000000
        diag "UST implicit non-blocking mode (default): will hang if fails"
 
-       # Test without the plugin
        start_lttng_sessiond
+       # session in no-output mode
        create_lttng_session_no_output $SESSION_NAME
        enable_ust_lttng_event_ok $SESSION_NAME "$EVENT_NAME"
        start_lttng_tracing_ok $SESSION_NAME
@@ -56,17 +57,18 @@ function test_ust_implicit_no_blocking()
        ok 0 "Does not hang"
 }
 
-function test_ust_explicit_no_blocking()
+function test_ust_implicit_no_blocking_with_channel_blocking()
 {
-       NUM_EVENT=500000
-       diag "UST explicit non-blocking mode: will hang if fails"
+       NUM_EVENT=5000000
+       diag "UST implicit non-blocking mode (default) with blocking-timeout=-1 channel: will hang if fails"
 
-       # Test without the plugin
        start_lttng_sessiond
+       # session in no-output mode
        create_lttng_session_no_output $SESSION_NAME
-       enable_ust_lttng_event_ok $SESSION_NAME "$EVENT_NAME"
+       enable_ust_lttng_channel_ok $SESSION_NAME $CHANNEL_NAME "--blocking-timeout=-1"
+       enable_ust_lttng_event_ok $SESSION_NAME "$EVENT_NAME" $CHANNEL_NAME
        start_lttng_tracing_ok $SESSION_NAME
-       LTTNG_UST_BLOCKING_RETRY_TIMEOUT=0 run_app
+       run_app
        stop_lttng_tracing_ok $SESSION_NAME
        destroy_lttng_session_ok $SESSION_NAME
        stop_lttng_sessiond
@@ -77,14 +79,16 @@ function test_ust_explicit_no_blocking()
 function test_ust_timeout_no_blocking()
 {
        NUM_EVENT=12500
-       diag "UST 1ms timeout retry mode: will hang if fails"
+       diag "UST 1ms timeout blocking mode: will hang if fails"
 
        start_lttng_sessiond
+       # session in no-output mode
        create_lttng_session_no_output $SESSION_NAME
-       enable_ust_lttng_event_ok $SESSION_NAME "$EVENT_NAME"
+       # blocking timeout 1ms
+       enable_ust_lttng_channel_ok $SESSION_NAME $CHANNEL_NAME "--blocking-timeout=1000"
+       enable_ust_lttng_event_ok $SESSION_NAME "$EVENT_NAME" $CHANNEL_NAME
        start_lttng_tracing_ok $SESSION_NAME
-       # retry timeout 1ms
-       LTTNG_UST_BLOCKING_RETRY_TIMEOUT=1 run_app
+       LTTNG_UST_ALLOW_BLOCKING=1 run_app
        stop_lttng_tracing_ok $SESSION_NAME
        destroy_lttng_session_ok $SESSION_NAME
        stop_lttng_sessiond
@@ -94,15 +98,17 @@ function test_ust_timeout_no_blocking()
 
 function test_ust_snapshot_no_blocking()
 {
-       NUM_EVENT=500000
+       NUM_EVENT=5000000
        diag "UST blocking mode: don't block in snapshot mode"
 
        # Test without the plugin
        start_lttng_sessiond
        create_lttng_session_ok $SESSION_NAME $TRACE_PATH --snapshot
-       enable_ust_lttng_event_ok $SESSION_NAME "$EVENT_NAME"
+       # blocking timeout 1ms
+       enable_ust_lttng_channel_ok $SESSION_NAME $CHANNEL_NAME "--blocking-timeout=1000"
+       enable_ust_lttng_event_ok $SESSION_NAME "$EVENT_NAME" $CHANNEL_NAME
        start_lttng_tracing_ok $SESSION_NAME
-       LTTNG_UST_BLOCKING_RETRY_TIMEOUT=-1 run_app
+       LTTNG_UST_ALLOW_BLOCKING=1 run_app
        stop_lttng_tracing_ok $SESSION_NAME
        destroy_lttng_session_ok $SESSION_NAME
        stop_lttng_sessiond
@@ -112,16 +118,17 @@ function test_ust_snapshot_no_blocking()
 
 function test_ust_blocking_no_discard()
 {
-       NUM_EVENT=500000
+       NUM_EVENT=5000000
        diag "UST blocking mode: no event discarded"
 
        # Test without the plugin
        start_lttng_sessiond
        create_lttng_session_ok $SESSION_NAME $TRACE_PATH
-       enable_ust_lttng_event_ok $SESSION_NAME "$EVENT_NAME"
+       # infinite blocking timeout
+       enable_ust_lttng_channel_ok $SESSION_NAME $CHANNEL_NAME "--blocking-timeout=-1"
+       enable_ust_lttng_event_ok $SESSION_NAME "$EVENT_NAME" $CHANNEL_NAME
        start_lttng_tracing_ok $SESSION_NAME
-       # infinite retry timeout
-       LTTNG_UST_BLOCKING_RETRY_TIMEOUT=-1 run_app
+       LTTNG_UST_ALLOW_BLOCKING=1 run_app
        stop_lttng_tracing_ok $SESSION_NAME
        destroy_lttng_session_ok $SESSION_NAME
        stop_lttng_sessiond
@@ -138,7 +145,7 @@ print_test_banner "$TEST_DESC"
 
 TESTS=(
        "test_ust_implicit_no_blocking"
-       "test_ust_explicit_no_blocking"
+       "test_ust_implicit_no_blocking_with_channel_blocking"
        "test_ust_timeout_no_blocking"
        "test_ust_snapshot_no_blocking"
        "test_ust_blocking_no_discard"
This page took 0.044428 seconds and 4 git commands to generate.