From: Mathieu Desnoyers Date: Sat, 27 May 2017 06:17:39 +0000 (+0200) Subject: Introduce "--blocking-timeout" channel parameter X-Git-Tag: v2.11.0-rc1~527 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=491d15395b58df09f8a3e7ba7404eb1f46392b79 Introduce "--blocking-timeout" channel parameter 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 Signed-off-by: Jérémie Galarneau --- diff --git a/configure.ac b/configure.ac index 8fb84787f..b49a4f45d 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/doc/man/lttng-enable-channel.1.txt b/doc/man/lttng-enable-channel.1.txt index f9b0b1f5a..d66d2fb51 100644 --- a/doc/man/lttng-enable-channel.1.txt +++ b/doc/man/lttng-enable-channel.1.txt @@ -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) diff --git a/include/lttng/channel-internal.h b/include/lttng/channel-internal.h index d78a720d4..53171f42c 100644 --- a/include/lttng/channel-internal.h +++ b/include/lttng/channel-internal.h @@ -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 */ diff --git a/include/lttng/channel.h b/include/lttng/channel.h index e20ed4f4f..4e61a611b 100644 --- a/include/lttng/channel.h +++ b/include/lttng/channel.h @@ -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 diff --git a/src/bin/lttng-sessiond/channel.c b/src/bin/lttng-sessiond/channel.c index 8a88ecced..5aa0cd82b 100644 --- a/src/bin/lttng-sessiond/channel.c +++ b/src/bin/lttng-sessiond/channel.c @@ -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) { diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 9e761958a..b836f3d8f 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -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); diff --git a/src/bin/lttng-sessiond/consumer.c b/src/bin/lttng-sessiond/consumer.c index 4a7287b61..33ccfe224 100644 --- a/src/bin/lttng-sessiond/consumer.c +++ b/src/bin/lttng-sessiond/consumer.c @@ -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)); diff --git a/src/bin/lttng-sessiond/consumer.h b/src/bin/lttng-sessiond/consumer.h index 77bc2b1f1..b8d5630f4 100644 --- a/src/bin/lttng-sessiond/consumer.h +++ b/src/bin/lttng-sessiond/consumer.h @@ -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, diff --git a/src/bin/lttng-sessiond/lttng-ust-abi.h b/src/bin/lttng-sessiond/lttng-ust-abi.h index 972de0c34..687eb0b23 100644 --- a/src/bin/lttng-sessiond/lttng-ust-abi.h +++ b/src/bin/lttng-sessiond/lttng-ust-abi.h @@ -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 diff --git a/src/bin/lttng-sessiond/lttng-ust-ctl.h b/src/bin/lttng-sessiond/lttng-ust-ctl.h index cba0e272d..1d67e858c 100644 --- a/src/bin/lttng-sessiond/lttng-ust-ctl.h +++ b/src/bin/lttng-sessiond/lttng-ust-ctl.h @@ -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; /* diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index 314c21e38..bcb04fe57 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -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) { diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index 98f45e055..eb0f83716 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -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. diff --git a/src/bin/lttng-sessiond/ust-consumer.c b/src/bin/lttng-sessiond/ust-consumer.c index fe2c8f4c8..43bf2616a 100644 --- a/src/bin/lttng-sessiond/ust-consumer.c +++ b/src/bin/lttng-sessiond/ust-consumer.c @@ -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(); diff --git a/src/bin/lttng/commands/enable_channels.c b/src/bin/lttng/commands/enable_channels.c index 22331cec2..27d4618a9 100644 --- a/src/bin/lttng/commands/enable_channels.c +++ b/src/bin/lttng/commands/enable_channels.c @@ -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; diff --git a/src/bin/lttng/commands/list.c b/src/bin/lttng/commands/list.c index 1315783f3..942e4a4c2 100644 --- a/src/bin/lttng/commands/list.c +++ b/src/bin/lttng/commands/list.c @@ -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); diff --git a/src/common/config/config-session-abi.h b/src/common/config/config-session-abi.h index 2faa354a0..5f91109cc 100644 --- a/src/common/config/config-session-abi.h +++ b/src/common/config/config-session-abi.h @@ -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; diff --git a/src/common/config/session-config.c b/src/common/config/session-config.c index 69b62d752..a62931201 100644 --- a/src/common/config/session-config.c +++ b/src/common/config/session-config.c @@ -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"; diff --git a/src/common/config/session.xsd b/src/common/config/session.xsd index 550fea0ee..6efdc433c 100644 --- a/src/common/config/session.xsd +++ b/src/common/config/session.xsd @@ -43,6 +43,18 @@ elementFormDefault="qualified" version="2.8"> + + + + + + + + @@ -186,6 +198,7 @@ elementFormDefault="qualified" version="2.8"> + diff --git a/src/common/defaults.h b/src/common/defaults.h index 1e6a1171d..8669a8412 100644 --- a/src/common/defaults.h +++ b/src/common/defaults.h @@ -221,6 +221,7 @@ #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 */ @@ -244,6 +245,9 @@ #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 diff --git a/src/common/mi-lttng-3.0.xsd b/src/common/mi-lttng-3.0.xsd index 56b65a364..8b2e45359 100644 --- a/src/common/mi-lttng-3.0.xsd +++ b/src/common/mi-lttng-3.0.xsd @@ -43,6 +43,19 @@ THE SOFTWARE. + + + + + + + + @@ -363,6 +376,7 @@ THE SOFTWARE. + diff --git a/src/common/mi-lttng.c b/src/common/mi-lttng.c index 197add2d4..9c1597b36 100644 --- a/src/common/mi-lttng.c +++ b/src/common/mi-lttng.c @@ -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, diff --git a/src/common/sessiond-comm/sessiond-comm.h b/src/common/sessiond-comm/sessiond-comm.h index f6179f31d..cd5ee0622 100644 --- a/src/common/sessiond-comm/sessiond-comm.h +++ b/src/common/sessiond-comm/sessiond-comm.h @@ -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; diff --git a/src/common/ust-consumer/ust-consumer.c b/src/common/ust-consumer/ust-consumer.c index 147fe8aaf..99803a693 100644 --- a/src/common/ust-consumer/ust-consumer.c +++ b/src/common/ust-consumer/ust-consumer.c @@ -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) { diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index a8c6c9b24..a1e10f25e 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -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. * diff --git a/tests/regression/ust/blocking/test_blocking b/tests/regression/ust/blocking/test_blocking index 261e0b8b3..c5c95903b 100755 --- a/tests/regression/ust/blocking/test_blocking +++ b/tests/regression/ust/blocking/test_blocking @@ -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"