X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=src%2Flttng-syscalls.c;h=d74851b7bc43224d1a5a1726a6dd32d0e8fabae3;hb=578c38e1da508b4224aaf2e27ec41f130a570c9c;hp=bd836c001d658257e5bf529d61a3cbeabc84a168;hpb=ac847066a7e106d38fd18587044622d050dc86a1;p=lttng-modules.git diff --git a/src/lttng-syscalls.c b/src/lttng-syscalls.c index bd836c00..d74851b7 100644 --- a/src/lttng-syscalls.c +++ b/src/lttng-syscalls.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -135,6 +136,15 @@ struct lttng_syscall_filter { DECLARE_BITMAP(sc_exit, NR_syscalls); DECLARE_BITMAP(sc_compat_entry, NR_compat_syscalls); DECLARE_BITMAP(sc_compat_exit, NR_compat_syscalls); + + /* + * Reference counters keeping track of number of events enabled + * for each bit. + */ + u32 sc_entry_refcount_map[NR_syscalls]; + u32 sc_exit_refcount_map[NR_syscalls]; + u32 sc_compat_entry_refcount_map[NR_compat_syscalls]; + u32 sc_compat_exit_refcount_map[NR_compat_syscalls]; }; static void syscall_entry_event_unknown(struct hlist_head *unknown_action_list_head, @@ -1367,6 +1377,7 @@ int lttng_syscall_filter_enable( { const char *syscall_name; unsigned long *bitmap; + u32 *refcount_map; int syscall_nr; syscall_name = get_syscall_name(desc_name, abi, entryexit); @@ -1389,9 +1400,11 @@ int lttng_syscall_filter_enable( switch (abi) { case LTTNG_SYSCALL_ABI_NATIVE: bitmap = filter->sc_entry; + refcount_map = filter->sc_entry_refcount_map; break; case LTTNG_SYSCALL_ABI_COMPAT: bitmap = filter->sc_compat_entry; + refcount_map = filter->sc_compat_entry_refcount_map; break; default: return -EINVAL; @@ -1401,9 +1414,11 @@ int lttng_syscall_filter_enable( switch (abi) { case LTTNG_SYSCALL_ABI_NATIVE: bitmap = filter->sc_exit; + refcount_map = filter->sc_exit_refcount_map; break; case LTTNG_SYSCALL_ABI_COMPAT: bitmap = filter->sc_compat_exit; + refcount_map = filter->sc_compat_exit_refcount_map; break; default: return -EINVAL; @@ -1412,9 +1427,10 @@ int lttng_syscall_filter_enable( default: return -EINVAL; } - if (test_bit(syscall_nr, bitmap)) - return -EEXIST; - bitmap_set(bitmap, syscall_nr, 1); + if (refcount_map[syscall_nr] == U32_MAX) + return -EOVERFLOW; + if (refcount_map[syscall_nr]++ == 0) + bitmap_set(bitmap, syscall_nr, 1); return 0; } @@ -1428,13 +1444,16 @@ int lttng_syscall_filter_enable_event_notifier( WARN_ON_ONCE(event_notifier->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL); + /* Skip unknown syscall */ + if (syscall_id == -1U) + return 0; + ret = lttng_syscall_filter_enable(group->sc_filter, event_notifier->priv->parent.desc->event_name, event_notifier->priv->parent.u.syscall.abi, event_notifier->priv->parent.u.syscall.entryexit); - if (ret) { - goto end; - } + if (ret) + return ret; switch (event_notifier->priv->parent.u.syscall.entryexit) { case LTTNG_SYSCALL_ENTRY: @@ -1471,15 +1490,21 @@ int lttng_syscall_filter_enable_event_notifier( hlist_add_head_rcu(&event_notifier->priv->parent.u.syscall.node, dispatch_list); end: - return ret ; + return ret; } int lttng_syscall_filter_enable_event( struct lttng_kernel_channel_buffer *channel, struct lttng_kernel_event_recorder *event_recorder) { + unsigned int syscall_id = event_recorder->priv->parent.u.syscall.syscall_id; + WARN_ON_ONCE(event_recorder->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL); + /* Skip unknown syscall */ + if (syscall_id == -1U) + return 0; + return lttng_syscall_filter_enable(channel->priv->parent.sc_filter, event_recorder->priv->parent.desc->event_name, event_recorder->priv->parent.u.syscall.abi, @@ -1494,6 +1519,7 @@ int lttng_syscall_filter_disable( { const char *syscall_name; unsigned long *bitmap; + u32 *refcount_map; int syscall_nr; syscall_name = get_syscall_name(desc_name, abi, entryexit); @@ -1516,9 +1542,11 @@ int lttng_syscall_filter_disable( switch (abi) { case LTTNG_SYSCALL_ABI_NATIVE: bitmap = filter->sc_entry; + refcount_map = filter->sc_entry_refcount_map; break; case LTTNG_SYSCALL_ABI_COMPAT: bitmap = filter->sc_compat_entry; + refcount_map = filter->sc_compat_entry_refcount_map; break; default: return -EINVAL; @@ -1528,9 +1556,11 @@ int lttng_syscall_filter_disable( switch (abi) { case LTTNG_SYSCALL_ABI_NATIVE: bitmap = filter->sc_exit; + refcount_map = filter->sc_exit_refcount_map; break; case LTTNG_SYSCALL_ABI_COMPAT: bitmap = filter->sc_compat_exit; + refcount_map = filter->sc_compat_exit_refcount_map; break; default: return -EINVAL; @@ -1539,10 +1569,10 @@ int lttng_syscall_filter_disable( default: return -EINVAL; } - if (!test_bit(syscall_nr, bitmap)) - return -EEXIST; - bitmap_clear(bitmap, syscall_nr, 1); - + if (refcount_map[syscall_nr] == 0) + return -ENOENT; + if (--refcount_map[syscall_nr] == 0) + bitmap_clear(bitmap, syscall_nr, 1); return 0; } @@ -1550,15 +1580,21 @@ int lttng_syscall_filter_disable_event_notifier( struct lttng_kernel_event_notifier *event_notifier) { struct lttng_event_notifier_group *group = event_notifier->priv->group; + unsigned int syscall_id = event_notifier->priv->parent.u.syscall.syscall_id; int ret; WARN_ON_ONCE(event_notifier->priv->parent.instrumentation != LTTNG_KERNEL_ABI_SYSCALL); + /* Skip unknown syscall */ + if (syscall_id == -1U) + return 0; + ret = lttng_syscall_filter_disable(group->sc_filter, event_notifier->priv->parent.desc->event_name, event_notifier->priv->parent.u.syscall.abi, event_notifier->priv->parent.u.syscall.entryexit); - WARN_ON_ONCE(ret != 0); + if (ret) + return ret; hlist_del_rcu(&event_notifier->priv->parent.u.syscall.node); return 0; @@ -1568,6 +1604,12 @@ int lttng_syscall_filter_disable_event( struct lttng_kernel_channel_buffer *channel, struct lttng_kernel_event_recorder *event_recorder) { + unsigned int syscall_id = event_recorder->priv->parent.u.syscall.syscall_id; + + /* Skip unknown syscall */ + if (syscall_id == -1U) + return 0; + return lttng_syscall_filter_disable(channel->priv->parent.sc_filter, event_recorder->priv->parent.desc->event_name, event_recorder->priv->parent.u.syscall.abi,