#include <signal.h>
#include <limits.h>
#include <urcu/uatomic.h>
-#include <urcu/futex.h>
+#include "futex.h"
#include <urcu/compiler.h>
+#include <lttng/urcu/urcu-ust.h>
#include <lttng/align.h>
#include <lttng/ust-events.h>
[ LTTNG_UST_REGISTER_DONE ] = "Registration Done",
[ LTTNG_UST_TRACEPOINT_FIELD_LIST ] = "Create Tracepoint Field List",
+ [ LTTNG_UST_EVENT_NOTIFIER_GROUP_CREATE ] = "Create event notifier group",
+
/* Session FD commands */
[ LTTNG_UST_CHANNEL ] = "Create Channel",
[ LTTNG_UST_SESSION_START ] = "Start Session",
/* Event FD commands */
[ LTTNG_UST_FILTER ] = "Create Filter",
[ LTTNG_UST_EXCLUSION ] = "Add exclusions to event",
+
+ /* Event notifier group commands */
+ [ LTTNG_UST_EVENT_NOTIFIER_CREATE ] = "Create event notifier",
+
+ /* Session and event notifier group commands */
+ [ LTTNG_UST_COUNTER ] = "Create Counter",
+
+ /* Counter commands */
+ [ LTTNG_UST_COUNTER_GLOBAL ] = "Create Counter Global",
+ [ LTTNG_UST_COUNTER_CPU ] = "Create Counter CPU",
};
static const char *str_timeout;
extern void lttng_ring_buffer_client_discard_exit(void);
extern void lttng_ring_buffer_client_discard_rt_exit(void);
extern void lttng_ring_buffer_metadata_client_exit(void);
+extern void lttng_counter_client_percpu_32_modular_init(void);
+extern void lttng_counter_client_percpu_32_modular_exit(void);
+extern void lttng_counter_client_percpu_64_modular_init(void);
+extern void lttng_counter_client_percpu_64_modular_exit(void);
static char *get_map_shm(struct sock_info *sock_info);
static
void lttng_fixup_urcu_bp_tls(void)
{
- rcu_read_lock();
- rcu_read_unlock();
+ (void) lttng_ust_urcu_read_ongoing();
}
void lttng_ust_fixup_tls(void)
}
}
+static inline
+const char *bytecode_type_str(uint32_t cmd)
+{
+ switch (cmd) {
+ case LTTNG_UST_CAPTURE:
+ return "capture";
+ case LTTNG_UST_FILTER:
+ return "filter";
+ default:
+ abort();
+ }
+}
+
+static
+int handle_bytecode_recv(struct sock_info *sock_info,
+ int sock, struct ustcomm_ust_msg *lum)
+{
+ struct lttng_ust_bytecode_node *bytecode;
+ enum lttng_ust_bytecode_node_type type;
+ const struct lttng_ust_objd_ops *ops;
+ uint32_t data_size, data_size_max, reloc_offset;
+ uint64_t seqnum;
+ ssize_t len;
+ int ret = 0;
+
+ switch (lum->cmd) {
+ case LTTNG_UST_FILTER:
+ type = LTTNG_UST_BYTECODE_NODE_TYPE_FILTER;
+ data_size = lum->u.filter.data_size;
+ data_size_max = FILTER_BYTECODE_MAX_LEN;
+ reloc_offset = lum->u.filter.reloc_offset;
+ seqnum = lum->u.filter.seqnum;
+ break;
+ case LTTNG_UST_CAPTURE:
+ type = LTTNG_UST_BYTECODE_NODE_TYPE_CAPTURE;
+ data_size = lum->u.capture.data_size;
+ data_size_max = CAPTURE_BYTECODE_MAX_LEN;
+ reloc_offset = lum->u.capture.reloc_offset;
+ seqnum = lum->u.capture.seqnum;
+ break;
+ default:
+ abort();
+ }
+
+ if (data_size > data_size_max) {
+ ERR("Bytecode %s data size is too large: %u bytes",
+ bytecode_type_str(lum->cmd), data_size);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ if (reloc_offset > data_size) {
+ ERR("Bytecode %s reloc offset %u is not within data",
+ bytecode_type_str(lum->cmd), reloc_offset);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ /* Allocate the structure AND the `data[]` field. */
+ bytecode = zmalloc(sizeof(*bytecode) + data_size);
+ if (!bytecode) {
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ bytecode->bc.len = data_size;
+ bytecode->bc.reloc_offset = reloc_offset;
+ bytecode->bc.seqnum = seqnum;
+ bytecode->type = type;
+
+ len = ustcomm_recv_unix_sock(sock, bytecode->bc.data, bytecode->bc.len);
+ switch (len) {
+ case 0: /* orderly shutdown */
+ ret = 0;
+ goto error_free_bytecode;
+ default:
+ if (len == bytecode->bc.len) {
+ DBG("Bytecode %s data received",
+ bytecode_type_str(lum->cmd));
+ break;
+ } else if (len < 0) {
+ DBG("Receive failed from lttng-sessiond with errno %d",
+ (int) -len);
+ if (len == -ECONNRESET) {
+ ERR("%s remote end closed connection",
+ sock_info->name);
+ ret = len;
+ goto error_free_bytecode;
+ }
+ ret = len;
+ goto error_free_bytecode;
+ } else {
+ DBG("Incorrect %s bytecode data message size: %zd",
+ bytecode_type_str(lum->cmd), len);
+ ret = -EINVAL;
+ goto error_free_bytecode;
+ }
+ }
+
+ ops = objd_ops(lum->handle);
+ if (!ops) {
+ ret = -ENOENT;
+ goto error_free_bytecode;
+ }
+
+ if (ops->cmd) {
+ ret = ops->cmd(lum->handle, lum->cmd,
+ (unsigned long) bytecode,
+ NULL, sock_info);
+ if (ret)
+ goto error_free_bytecode;
+ /* don't free bytecode if everything went fine. */
+ } else {
+ ret = -ENOSYS;
+ goto error_free_bytecode;
+ }
+
+ goto end;
+
+error_free_bytecode:
+ free(bytecode);
+end:
+ return ret;
+}
+
static
int handle_message(struct sock_info *sock_info,
int sock, struct ustcomm_ust_msg *lum)
else
ret = lttng_ust_objd_unref(lum->handle, 1);
break;
+ case LTTNG_UST_CAPTURE:
case LTTNG_UST_FILTER:
- {
- /* Receive filter data */
- struct lttng_ust_filter_bytecode_node *bytecode;
-
- if (lum->u.filter.data_size > FILTER_BYTECODE_MAX_LEN) {
- ERR("Filter data size is too large: %u bytes",
- lum->u.filter.data_size);
- ret = -EINVAL;
- goto error;
- }
-
- if (lum->u.filter.reloc_offset > lum->u.filter.data_size) {
- ERR("Filter reloc offset %u is not within data",
- lum->u.filter.reloc_offset);
- ret = -EINVAL;
- goto error;
- }
-
- bytecode = zmalloc(sizeof(*bytecode) + lum->u.filter.data_size);
- if (!bytecode) {
- ret = -ENOMEM;
+ ret = handle_bytecode_recv(sock_info, sock, lum);
+ if (ret)
goto error;
- }
- len = ustcomm_recv_unix_sock(sock, bytecode->bc.data,
- lum->u.filter.data_size);
- switch (len) {
- case 0: /* orderly shutdown */
- ret = 0;
- free(bytecode);
- goto error;
- default:
- if (len == lum->u.filter.data_size) {
- DBG("filter data received");
- break;
- } else if (len < 0) {
- DBG("Receive failed from lttng-sessiond with errno %d", (int) -len);
- if (len == -ECONNRESET) {
- ERR("%s remote end closed connection", sock_info->name);
- ret = len;
- free(bytecode);
- goto error;
- }
- ret = len;
- free(bytecode);
- goto error;
- } else {
- DBG("incorrect filter data message size: %zd", len);
- ret = -EINVAL;
- free(bytecode);
- goto error;
- }
- }
- bytecode->bc.len = lum->u.filter.data_size;
- bytecode->bc.reloc_offset = lum->u.filter.reloc_offset;
- bytecode->bc.seqnum = lum->u.filter.seqnum;
- if (ops->cmd) {
- ret = ops->cmd(lum->handle, lum->cmd,
- (unsigned long) bytecode,
- &args, sock_info);
- if (ret) {
- free(bytecode);
- }
- /* don't free bytecode if everything went fine. */
- } else {
- ret = -ENOSYS;
- free(bytecode);
- }
break;
- }
case LTTNG_UST_EXCLUSION:
{
/* Receive exclusion names */
}
break;
}
+ case LTTNG_UST_EVENT_NOTIFIER_GROUP_CREATE:
+ {
+ int event_notifier_notif_fd, close_ret;
+
+ len = ustcomm_recv_event_notifier_notif_fd_from_sessiond(sock,
+ &event_notifier_notif_fd);
+ switch (len) {
+ case 0: /* orderly shutdown */
+ ret = 0;
+ goto error;
+ case 1:
+ break;
+ default:
+ if (len < 0) {
+ DBG("Receive failed from lttng-sessiond with errno %d",
+ (int) -len);
+ if (len == -ECONNRESET) {
+ ERR("%s remote end closed connection",
+ sock_info->name);
+ ret = len;
+ goto error;
+ }
+ ret = len;
+ goto error;
+ } else {
+ DBG("Incorrect event notifier fd message size: %zd",
+ len);
+ ret = -EINVAL;
+ goto error;
+ }
+ }
+ args.event_notifier_handle.event_notifier_notif_fd =
+ event_notifier_notif_fd;
+ if (ops->cmd)
+ ret = ops->cmd(lum->handle, lum->cmd,
+ (unsigned long) &lum->u,
+ &args, sock_info);
+ else
+ ret = -ENOSYS;
+ if (args.event_notifier_handle.event_notifier_notif_fd >= 0) {
+ lttng_ust_lock_fd_tracker();
+ close_ret = close(args.event_notifier_handle.event_notifier_notif_fd);
+ lttng_ust_unlock_fd_tracker();
+ if (close_ret)
+ PERROR("close");
+ }
+ break;
+ }
case LTTNG_UST_CHANNEL:
{
void *chan_data;
&args, sock_info);
else
ret = -ENOSYS;
+ if (args.channel.wakeup_fd >= 0) {
+ int close_ret;
+
+ lttng_ust_lock_fd_tracker();
+ close_ret = close(args.channel.wakeup_fd);
+ lttng_ust_unlock_fd_tracker();
+ args.channel.wakeup_fd = -1;
+ if (close_ret)
+ PERROR("close");
+ }
+ free(args.channel.chan_data);
break;
}
case LTTNG_UST_STREAM:
{
+ int close_ret;
+
/* Receive shm_fd, wakeup_fd */
ret = ustcomm_recv_stream_from_sessiond(sock,
NULL,
&args, sock_info);
else
ret = -ENOSYS;
+ if (args.stream.shm_fd >= 0) {
+ lttng_ust_lock_fd_tracker();
+ close_ret = close(args.stream.shm_fd);
+ lttng_ust_unlock_fd_tracker();
+ args.stream.shm_fd = -1;
+ if (close_ret)
+ PERROR("close");
+ }
+ if (args.stream.wakeup_fd >= 0) {
+ lttng_ust_lock_fd_tracker();
+ close_ret = close(args.stream.wakeup_fd);
+ lttng_ust_unlock_fd_tracker();
+ args.stream.wakeup_fd = -1;
+ if (close_ret)
+ PERROR("close");
+ }
break;
}
case LTTNG_UST_CONTEXT:
ret = -ENOSYS;
}
break;
+ case LTTNG_UST_COUNTER:
+ {
+ void *counter_data;
+
+ len = ustcomm_recv_counter_from_sessiond(sock,
+ &counter_data, lum->u.counter.len);
+ switch (len) {
+ case 0: /* orderly shutdown */
+ ret = 0;
+ goto error;
+ default:
+ if (len == lum->u.counter.len) {
+ DBG("counter data received");
+ break;
+ } else if (len < 0) {
+ DBG("Receive failed from lttng-sessiond with errno %d", (int) -len);
+ if (len == -ECONNRESET) {
+ ERR("%s remote end closed connection", sock_info->name);
+ ret = len;
+ goto error;
+ }
+ ret = len;
+ goto error;
+ } else {
+ DBG("incorrect counter data message size: %zd", len);
+ ret = -EINVAL;
+ goto error;
+ }
+ }
+ args.counter.counter_data = counter_data;
+ if (ops->cmd)
+ ret = ops->cmd(lum->handle, lum->cmd,
+ (unsigned long) &lum->u,
+ &args, sock_info);
+ else
+ ret = -ENOSYS;
+ break;
+ }
+ case LTTNG_UST_COUNTER_GLOBAL:
+ {
+ /* Receive shm_fd */
+ ret = ustcomm_recv_counter_shm_from_sessiond(sock,
+ &args.counter_shm.shm_fd);
+ if (ret) {
+ goto error;
+ }
+
+ if (ops->cmd)
+ ret = ops->cmd(lum->handle, lum->cmd,
+ (unsigned long) &lum->u,
+ &args, sock_info);
+ else
+ ret = -ENOSYS;
+ break;
+ }
+ case LTTNG_UST_COUNTER_CPU:
+ {
+ /* Receive shm_fd */
+ ret = ustcomm_recv_counter_shm_from_sessiond(sock,
+ &args.counter_shm.shm_fd);
+ if (ret) {
+ goto error;
+ }
+
+ if (ops->cmd)
+ ret = ops->cmd(lum->handle, lum->cmd,
+ (unsigned long) &lum->u,
+ &args, sock_info);
+ else
+ ret = -ENOSYS;
+ break;
+ }
+ case LTTNG_UST_EVENT_NOTIFIER_CREATE:
+ {
+ /* Receive struct lttng_ust_event_notifier */
+ struct lttng_ust_event_notifier event_notifier;
+
+ if (sizeof(event_notifier) != lum->u.event_notifier.len) {
+ DBG("incorrect event notifier data message size: %u", lum->u.event_notifier.len);
+ ret = -EINVAL;
+ goto error;
+ }
+ len = ustcomm_recv_unix_sock(sock, &event_notifier, sizeof(event_notifier));
+ switch (len) {
+ case 0: /* orderly shutdown */
+ ret = 0;
+ goto error;
+ default:
+ if (len == sizeof(event_notifier)) {
+ DBG("event notifier data received");
+ break;
+ } else if (len < 0) {
+ DBG("Receive failed from lttng-sessiond with errno %d", (int) -len);
+ if (len == -ECONNRESET) {
+ ERR("%s remote end closed connection", sock_info->name);
+ ret = len;
+ goto error;
+ }
+ ret = len;
+ goto error;
+ } else {
+ DBG("incorrect event notifier data message size: %zd", len);
+ ret = -EINVAL;
+ goto error;
+ }
+ }
+ if (ops->cmd)
+ ret = ops->cmd(lum->handle, lum->cmd,
+ (unsigned long) &event_notifier,
+ &args, sock_info);
+ else
+ ret = -ENOSYS;
+ break;
+ }
+
default:
if (ops->cmd)
ret = ops->cmd(lum->handle, lum->cmd,
if (uatomic_read((int32_t *) sock_info->wait_shm_mmap))
goto end_wait;
- while (futex_async((int32_t *) sock_info->wait_shm_mmap,
+ while (lttng_ust_futex_async((int32_t *) sock_info->wait_shm_mmap,
FUTEX_WAIT, 0, NULL, NULL, 0)) {
switch (errno) {
case EWOULDBLOCK:
lttng_ring_buffer_client_overwrite_rt_init();
lttng_ring_buffer_client_discard_init();
lttng_ring_buffer_client_discard_rt_init();
+ lttng_counter_client_percpu_32_modular_init();
+ lttng_counter_client_percpu_64_modular_init();
lttng_perf_counter_init();
/*
* Invoke ust malloc wrapper init before starting other threads.
lttng_ring_buffer_client_overwrite_rt_exit();
lttng_ring_buffer_client_overwrite_exit();
lttng_ring_buffer_metadata_client_exit();
+ lttng_counter_client_percpu_32_modular_exit();
+ lttng_counter_client_percpu_64_modular_exit();
lttng_ust_statedump_destroy();
exit_tracepoint();
if (!exiting) {
pthread_mutex_lock(&ust_fork_mutex);
ust_lock_nocheck();
- urcu_bp_before_fork();
+ lttng_ust_urcu_before_fork();
+ if (lttng_ust_liburcu_bp_before_fork)
+ lttng_ust_liburcu_bp_before_fork();
lttng_ust_lock_fd_tracker();
lttng_perf_lock();
}
if (URCU_TLS(lttng_ust_nest_count))
return;
DBG("process %d", getpid());
- urcu_bp_after_fork_parent();
+ lttng_ust_urcu_after_fork_parent();
+ if (lttng_ust_liburcu_bp_after_fork_parent)
+ lttng_ust_liburcu_bp_after_fork_parent();
/* Release mutexes and reenable signals */
ust_after_fork_common(restore_sigset);
}
ust_context_vgids_reset();
DBG("process %d", getpid());
/* Release urcu mutexes */
- urcu_bp_after_fork_child();
+ lttng_ust_urcu_after_fork_child();
+ if (lttng_ust_liburcu_bp_after_fork_child)
+ lttng_ust_liburcu_bp_after_fork_child();
lttng_ust_cleanup(0);
/* Release mutexes and reenable signals */
ust_after_fork_common(restore_sigset);