X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=lttng-events.c;h=ffb605106ab6f775f467a7409f507947a1cdbc95;hb=70795b22cb4f81bcfd31e10584ca24ecde115303;hp=9769f89de2aa78bef23410cf1dce84fdaf0c4584;hpb=a606b6e893b99bc31cacee98415942dbc577c90c;p=lttng-modules.git diff --git a/lttng-events.c b/lttng-events.c index 9769f89d..ffb60510 100644 --- a/lttng-events.c +++ b/lttng-events.c @@ -50,6 +50,7 @@ #include "lttng-events.h" #include "lttng-tracer.h" #include "lttng-abi-old.h" +#include "wrapper/vzalloc.h" #define METADATA_CACHE_DEFAULT_SIZE 4096 @@ -133,7 +134,7 @@ struct lttng_session *lttng_session_create(void) GFP_KERNEL); if (!metadata_cache) goto err_free_session; - metadata_cache->data = vzalloc(METADATA_CACHE_DEFAULT_SIZE); + metadata_cache->data = lttng_vzalloc(METADATA_CACHE_DEFAULT_SIZE); if (!metadata_cache->data) goto err_free_cache; metadata_cache->cache_alloc = METADATA_CACHE_DEFAULT_SIZE; @@ -328,8 +329,23 @@ int lttng_event_enable(struct lttng_event *event) ret = -EEXIST; goto end; } - ACCESS_ONCE(event->enabled) = 1; - lttng_session_sync_enablers(event->chan->session); + switch (event->instrumentation) { + case LTTNG_KERNEL_TRACEPOINT: + case LTTNG_KERNEL_SYSCALL: + ret = -EINVAL; + break; + case LTTNG_KERNEL_KPROBE: + case LTTNG_KERNEL_FUNCTION: + case LTTNG_KERNEL_NOOP: + ACCESS_ONCE(event->enabled) = 1; + break; + case LTTNG_KERNEL_KRETPROBE: + ret = lttng_kretprobes_event_enable_state(event, 1); + break; + default: + WARN_ON_ONCE(1); + ret = -EINVAL; + } end: mutex_unlock(&sessions_mutex); return ret; @@ -348,8 +364,23 @@ int lttng_event_disable(struct lttng_event *event) ret = -EEXIST; goto end; } - ACCESS_ONCE(event->enabled) = 0; - lttng_session_sync_enablers(event->chan->session); + switch (event->instrumentation) { + case LTTNG_KERNEL_TRACEPOINT: + case LTTNG_KERNEL_SYSCALL: + ret = -EINVAL; + break; + case LTTNG_KERNEL_KPROBE: + case LTTNG_KERNEL_FUNCTION: + case LTTNG_KERNEL_NOOP: + ACCESS_ONCE(event->enabled) = 0; + break; + case LTTNG_KERNEL_KRETPROBE: + ret = lttng_kretprobes_event_enable_state(event, 0); + break; + default: + WARN_ON_ONCE(1); + ret = -EINVAL; + } end: mutex_unlock(&sessions_mutex); return ret; @@ -537,7 +568,11 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan, smp_wmb(); break; case LTTNG_KERNEL_KPROBE: - event->enabled = 1; + /* + * Needs to be explicitly enabled after creation, since + * we may want to apply filters. + */ + event->enabled = 0; event->registered = 1; /* * Populate lttng_event structure before event @@ -561,7 +596,11 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan, struct lttng_event *event_return; /* kretprobe defines 2 events */ - event->enabled = 1; + /* + * Needs to be explicitly enabled after creation, since + * we may want to apply filters. + */ + event->enabled = 0; event->registered = 1; event_return = kmem_cache_zalloc(event_cache, GFP_KERNEL); @@ -572,7 +611,7 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan, event_return->chan = chan; event_return->filter = filter; event_return->id = chan->free_event_id++; - event_return->enabled = 1; + event_return->enabled = 0; event_return->registered = 1; event_return->instrumentation = itype; /* @@ -607,7 +646,11 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan, break; } case LTTNG_KERNEL_FUNCTION: - event->enabled = 1; + /* + * Needs to be explicitly enabled after creation, since + * we may want to apply filters. + */ + event->enabled = 0; event->registered = 1; /* * Populate lttng_event structure before event @@ -625,7 +668,11 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan, break; case LTTNG_KERNEL_NOOP: case LTTNG_KERNEL_SYSCALL: - event->enabled = 1; + /* + * Needs to be explicitly enabled after creation, since + * we may want to apply filters. + */ + event->enabled = 0; event->registered = 0; event->desc = event_desc; if (!event->desc) { @@ -996,17 +1043,22 @@ int lttng_session_list_tracker_pids(struct lttng_session *session) ret = PTR_ERR(tracker_pids_list_file); goto file_error; } + if (atomic_long_add_unless(&session->file->f_count, + 1, INT_MAX) == INT_MAX) { + goto refcount_error; + } ret = lttng_tracker_pids_list_fops.open(NULL, tracker_pids_list_file); if (ret < 0) goto open_error; m = tracker_pids_list_file->private_data; m->private = session; fd_install(file_fd, tracker_pids_list_file); - atomic_long_inc(&session->file->f_count); return file_fd; open_error: + atomic_long_dec(&session->file->f_count); +refcount_error: fput(tracker_pids_list_file); file_error: put_unused_fd(file_fd); @@ -1531,7 +1583,7 @@ int lttng_metadata_printf(struct lttng_session *session, tmp_cache_alloc_size = max_t(unsigned int, session->metadata_cache->cache_alloc + len, session->metadata_cache->cache_alloc << 1); - tmp_cache_realloc = vzalloc(tmp_cache_alloc_size); + tmp_cache_realloc = lttng_vzalloc(tmp_cache_alloc_size); if (!tmp_cache_realloc) goto err; if (session->metadata_cache->data) { @@ -1908,11 +1960,14 @@ int _lttng_event_header_declare(struct lttng_session *session) * taken at start of trace. * Yes, this is only an approximation. Yes, we can (and will) do better * in future versions. + * Return 0 if offset is negative. It may happen if the system sets + * the REALTIME clock to 0 after boot. */ static uint64_t measure_clock_offset(void) { - uint64_t offset, monotonic[2], realtime; + uint64_t monotonic_avg, monotonic[2], realtime; + int64_t offset; struct timespec rts = { 0, 0 }; unsigned long flags; @@ -1923,10 +1978,12 @@ uint64_t measure_clock_offset(void) monotonic[1] = trace_clock_read64(); local_irq_restore(flags); - offset = (monotonic[0] + monotonic[1]) >> 1; + monotonic_avg = (monotonic[0] + monotonic[1]) >> 1; realtime = (uint64_t) rts.tv_sec * NSEC_PER_SEC; realtime += rts.tv_nsec; - offset = realtime - offset; + offset = (int64_t) realtime - monotonic_avg; + if (offset < 0) + return 0; return offset; } @@ -2138,6 +2195,9 @@ static int __init lttng_events_init(void) if (ret) return ret; ret = wrapper_get_pfnblock_flags_mask_init(); + if (ret) + return ret; + ret = wrapper_get_pageblock_flags_mask_init(); if (ret) return ret; ret = lttng_context_init();