bpf, tracing: introduce bpf raw tracepoints
Subsystems (23)
v5 cover bpf, tracing: introduce bpf raw tracepoints
From: Alexei Starovoitov <[email protected]>
v4->v5:
- adopted Daniel's fancy REPEAT macro in bpf_trace.c in patch 7
v3->v4:
- adopted Linus's CAST_TO_U64 macro to cast any integer, pointer, or small struct to u64. That nicely reduced the size of patch 1
v2->v3:
- with Linus's suggestion introduced generic COUNT_ARGS and CONCATENATE macros (or rather moved them from apparmor)
that cleaned up patches 6 and 7
- added patch 4 to refactor trace_iwlwifi_dev_ucode_error() from 17 args to 4 Now any tracepoint with >12 args will have build error
v1->v2:
- simplified api by combing bpf_raw_tp_open(name) + bpf_attach(prog_fd) into bpf_raw_tp_open(name, prog_fd) as suggested by Daniel.
That simplifies bpf_detach as well which is now simple close() of fd.
- fixed memory leak in error path which was spotted by Daniel.
- fixed bpf_get_stackid(), bpf_perf_event_output() called from raw tracepoints
- added more tests
- fixed allyesconfig build caught by buildbot
v1:
This patch set is a different way to address the pressing need to access task_struct pointers in sched tracepoints from bpf programs.
The first approach simply added these pointers to sched tracepoints:
https://lkml.org/lkml/2017/12/14/753
which Peter nacked.
Few options were discussed and eventually the discussion converged on doing bpf specific tracepoint_probe_register() probe functions. Details here:
https://lkml.org/lkml/2017/12/20/929
Patch 1 is kernel wide cleanup of pass-struct-by-value into pass-struct-by-reference into tracepoints.
Patches 2 and 3 are minor cleanups to address allyesconfig build
Patch 4 refactor trace_iwlwifi_dev_ucode_error from 17 to 4 args
Patch 5 introduces COUNT_ARGS macro
Patch 6 minor prep work to expose number of arguments passed into tracepoints.
Patch 7 introduces BPF_RAW_TRACEPOINT api.
the auto-cleanup and multiple concurrent users are must have features of tracing api. For bpf raw tracepoints it looks like:
// load bpf prog with BPF_PROG_TYPE_RAW_TRACEPOINT type prog_fd = bpf_prog_load(...);
// receive anon_inode fd for given bpf_raw_tracepoint // and attach bpf program to it
raw_tp_fd = bpf_raw_tracepoint_open("xdp_exception", prog_fd);
Ctrl-C of tracing daemon or cmdline tool will automatically detach bpf program, unload it and unregister tracepoint probe. More details in patch 7.
Patch 8 - trivial support in libbpf
Patches 9, 10 - user space tests
samples/bpf/test_overhead performance on 1 cpu:
tracepoint base kprobe+bpf tracepoint+bpf raw_tracepoint+bpf task_rename 1.1M 769K 947K 1.0M urandom_read 789K 697K 750K 755K
Alexei Starovoitov (10):
treewide: remove large struct-pass-by-value from tracepoint arguments net/mediatek: disambiguate mt76 vs mt7601u trace events net/mac802154: disambiguate mac80215 vs mac802154 trace events net/wireless/iwlwifi: fix iwlwifi_dev_ucode_error tracepoint
macro: introduce COUNT_ARGS() macro
tracepoint: compute num_args at build time
bpf: introduce BPF_RAW_TRACEPOINT
libbpf: add bpf_raw_tracepoint_open helper
samples/bpf: raw tracepoint test
selftests/bpf: test for bpf_get_stackid() from raw tracepoints
drivers/infiniband/hw/hfi1/file_ops.c | 2 +- drivers/infiniband/hw/hfi1/trace_ctxts.h | 12 +- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 7 +- .../wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h | 39 ++--- drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c | 1 + drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 7 +- drivers/net/wireless/mediatek/mt7601u/trace.h | 6 +- include/linux/bpf_types.h | 1 + include/linux/kernel.h | 7 + include/linux/trace_events.h | 37 ++++ include/linux/tracepoint-defs.h | 1 + include/linux/tracepoint.h | 28 ++- include/trace/bpf_probe.h | 87 ++++++++++ include/trace/define_trace.h | 15 +- include/trace/events/f2fs.h | 2 +- include/uapi/linux/bpf.h | 11 ++ kernel/bpf/syscall.c | 87 ++++++++++ kernel/trace/bpf_trace.c | 188 +++++++++++++++++++++ kernel/tracepoint.c | 27 +-- net/mac802154/trace.h | 8 +- net/wireless/trace.h | 2 +- samples/bpf/Makefile | 1 + samples/bpf/bpf_load.c | 14 ++ samples/bpf/test_overhead_raw_tp_kern.c | 17 ++ samples/bpf/test_overhead_user.c | 12 ++ security/apparmor/include/path.h | 7 +- sound/firewire/amdtp-stream-trace.h | 2 +- tools/include/uapi/linux/bpf.h | 11 ++ tools/lib/bpf/bpf.c | 11 ++ tools/lib/bpf/bpf.h | 1 + tools/testing/selftests/bpf/test_progs.c | 91 +++++++--- 31 files changed, 638 insertions(+), 104 deletions(-) create mode 100644 include/trace/bpf_probe.h create mode 100644 samples/bpf/test_overhead_raw_tp_kern.c
Signature · 1 line
2.9.5
PATCH v5 1/10 treewide: remove large struct-pass-by-value from tracepoint arguments
From: Alexei Starovoitov <[email protected]>
- fix trace_hfi1_ctxt_info() to pass large struct by reference instead of by value
- convert 'type array[]' tracepoint arguments into 'type *array', since compiler will warn that sizeof('type array[]') == sizeof('type *array') and later should be used instead
The CAST_TO_U64 macro in the later patch will enforce that tracepoint arguments can only be integers, pointers, or less than 8 byte structures. Larger structures should be passed by reference.
--- drivers/infiniband/hw/hfi1/file_ops.c | 2 +- drivers/infiniband/hw/hfi1/trace_ctxts.h | 12 ++++++------ include/trace/events/f2fs.h | 2 +- net/wireless/trace.h | 2 +- sound/firewire/amdtp-stream-trace.h | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-)
drivers/infiniband/hw/hfi1/file_ops.c +1 -1
@@ -1153,7 +1153,7 @@ static int get_ctxt_info(struct hfi1_filedata *fd, unsigned long arg, u32 len) cinfo.sdma_ring_size = fd->cq->nentries; cinfo.rcvegr_size = uctxt->egrbufs.rcvtid_size; -trace_hfi1_ctxt_info (uctxt->dd, uctxt->ctxt, fd->subctxt, cinfo); +trace_hfi1_ctxt_info (uctxt->dd, uctxt->ctxt, fd->subctxt, &cinfo);if (copy_to_user ((void __user *)arg, &cinfo, len))return -EFAULT ;
drivers/infiniband/hw/hfi1/trace_ctxts.h +6 -6
@@ -106,7 +106,7 @@ TRACE_EVENT(hfi1_uctxtdata, TRACE_EVENT(hfi1_ctxt_info, TP_PROTO(struct hfi1_devdata *dd, unsigned int ctxt, unsigned int subctxt, - struct hfi1_ctxt_info cinfo), + struct hfi1_ctxt_info *cinfo), TP_ARGS(dd, ctxt, subctxt, cinfo), TP_STRUCT__entry(DD_DEV_ENTRY(dd) __field(unsigned int, ctxt)
@@ -120,11 +120,11 @@ TRACE_EVENT(hfi1_ctxt_info, TP_fast_assign(DD_DEV_ASSIGN(dd); __entry->ctxt = ctxt; __entry->subctxt = subctxt; - __entry->egrtids = cinfo.egrtids; - __entry->rcvhdrq_cnt = cinfo.rcvhdrq_cnt; - __entry->rcvhdrq_size = cinfo.rcvhdrq_entsize; - __entry->sdma_ring_size = cinfo.sdma_ring_size; - __entry->rcvegr_size = cinfo.rcvegr_size; + __entry->egrtids = cinfo->egrtids; + __entry->rcvhdrq_cnt = cinfo->rcvhdrq_cnt; + __entry->rcvhdrq_size = cinfo->rcvhdrq_entsize; + __entry->sdma_ring_size = cinfo->sdma_ring_size; + __entry->rcvegr_size = cinfo->rcvegr_size; ), TP_printk("[%s] ctxt %u:%u " CINFO_FMT, __get_str(dev),
include/trace/events/f2fs.h +1 -1
@@ -491,7 +491,7 @@ DEFINE_EVENT(f2fs__truncate_node, f2fs_truncate_node, TRACE_EVENT(f2fs_truncate_partial_nodes, - TP_PROTO(struct inode *inode, nid_t nid[], int depth, int err), + TP_PROTO(struct inode *inode, nid_t *nid, int depth, int err), TP_ARGS(inode, nid, depth, err),
net/wireless/trace.h +1 -1
@@ -3137,7 +3137,7 @@ TRACE_EVENT(rdev_start_radar_detection, TRACE_EVENT(rdev_set_mcast_rate, TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, - int mcast_rate[NUM_NL80211_BANDS]), + int *mcast_rate), TP_ARGS(wiphy, netdev, mcast_rate), TP_STRUCT__entry( WIPHY_ENTRY
sound/firewire/amdtp-stream-trace.h +1 -1
@@ -14,7 +14,7 @@#include <linux/tracepoint.h> TRACE_EVENT(in_packet, - TP_PROTO(const struct amdtp_stream *s, u32 cycles, u32 cip_header[2], unsigned int payload_length, unsigned int index), + TP_PROTO(const struct amdtp_stream *s, u32 cycles, u32 *cip_header, unsigned int payload_length, unsigned int index), TP_ARGS(s, cycles, cip_header, payload_length, index), TP_STRUCT__entry( __field(unsigned int, second)
Signature · 1 line
2.9.5
PATCH v5 2/10 net/mediatek: disambiguate mt76 vs mt7601u trace events
In reply to Alexei StarovoitovFrom: Alexei Starovoitov <[email protected]>
two trace events defined with the same name and both unused. They conflict in allyesconfig build. Rename one of them.
--- drivers/net/wireless/mediatek/mt7601u/trace.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/mediatek/mt7601u/trace.h +3 -3
@@ -34,7 +34,7 @@#define REG_PR_FMT "%04x=%08x"#define REG_PR_ARG __entry->reg, __entry->val -DECLARE_EVENT_CLASS(dev_reg_evt, +DECLARE_EVENT_CLASS(dev_reg_evtu, TP_PROTO(struct mt7601u_dev *dev, u32 reg, u32 val), TP_ARGS(dev, reg, val), TP_STRUCT__entry(
@@ -51,12 +51,12 @@ DECLARE_EVENT_CLASS(dev_reg_evt, ) ); -DEFINE_EVENT (dev_reg_evt, reg_read, +DEFINE_EVENT (dev_reg_evtu, reg_read, TP_PROTO(struct mt7601u_dev *dev, u32 reg, u32 val),TP_ARGS (dev, reg, val) ); -DEFINE_EVENT (dev_reg_evt, reg_write, +DEFINE_EVENT (dev_reg_evtu, reg_write, TP_PROTO(struct mt7601u_dev *dev, u32 reg, u32 val),TP_ARGS (dev, reg, val) );
Signature · 1 line
2.9.5
PATCH v5 3/10 net/mac802154: disambiguate mac80215 vs mac802154 trace events
In reply to Alexei StarovoitovFrom: Alexei Starovoitov <[email protected]>
two trace events defined with the same name and both unused. They conflict in allyesconfig build. Rename one of them.
--- net/mac802154/trace.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/mac802154/trace.h +4 -4
@@ -33,7 +33,7 @@/* Tracing for driver callbacks */ -DECLARE_EVENT_CLASS(local_only_evt, +DECLARE_EVENT_CLASS(local_only_evt4, TP_PROTO(struct ieee802154_local *local), TP_ARGS(local), TP_STRUCT__entry(
@@ -45,7 +45,7 @@ DECLARE_EVENT_CLASS(local_only_evt,TP_printk (LOCAL_PR_FMT ,LOCAL_PR_ARG ) ); -DEFINE_EVENT(local_only_evt, 802154_drv_return_void, +DEFINE_EVENT(local_only_evt4, 802154_drv_return_void, TP_PROTO(struct ieee802154_local *local),TP_ARGS (local) );
@@ -65,12 +65,12 @@ TRACE_EVENT(802154_drv_return_int, __entry->ret) ); -DEFINE_EVENT(local_only_evt, 802154_drv_start, +DEFINE_EVENT(local_only_evt4, 802154_drv_start, TP_PROTO(struct ieee802154_local *local),TP_ARGS (local) ); -DEFINE_EVENT(local_only_evt, 802154_drv_stop, +DEFINE_EVENT(local_only_evt4, 802154_drv_stop, TP_PROTO(struct ieee802154_local *local),TP_ARGS (local) );
Signature · 1 line
2.9.5
PATCH v5 4/10 net/wireless/iwlwifi: fix iwlwifi_dev_ucode_error tracepoint
In reply to Alexei StarovoitovFrom: Alexei Starovoitov <[email protected]>
fix iwlwifi_dev_ucode_error tracepoint to pass pointer to a table instead of all 17 arguments by value.dvm/main.c and mvm/utils.c have 'struct iwl_error_event_table' defined with very similar yet subtly different fields and offsets. tracepoint is still common and using definition of 'struct iwl_error_event_table' from dvm/commands.h while copying fields.
Long term this tracepoint probably should be split into two.
--- drivers/net/wireless/intel/iwlwifi/dvm/main.c | 7 +--- .../wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h | 39 ++++++++++------------ drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c | 1 + drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 7 +--- 4 files changed, 21 insertions(+), 33 deletions(-)
drivers/net/wireless/intel/iwlwifi/dvm/main.c +1 -6
@@ -1651,12 +1651,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) priv->status, table.valid); } -trace_iwlwifi_dev_ucode_error (trans->dev, table.error_id, table.tsf_low, - table.data1, table.data2, table.line, - table.blink2, table.ilink1, table.ilink2, - table.bcon_time, table.gp1, table.gp2, - table.gp3, table.ucode_ver, table.hw_ver, -0 , table.brd_ver); +trace_iwlwifi_dev_ucode_error (trans->dev, &table,0 , table.brd_ver);IWL_ERR (priv,"0x%08X | %-28s\n" , table.error_id,desc_lookup (table.error_id));IWL_ERR (priv,"0x%08X | uPc\n" , table.pc);
drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h +18 -21
@@ -126,14 +126,11 @@ TRACE_EVENT(iwlwifi_dev_tx, __entry->framelen, __entry->skbaddr) ); +struct iwl_error_event_table ; TRACE_EVENT(iwlwifi_dev_ucode_error, - TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low, - u32 data1, u32 data2, u32 line, u32 blink2, u32 ilink1, - u32 ilink2, u32 bcon_time, u32 gp1, u32 gp2, u32 rev_type, - u32 major, u32 minor, u32 hw_ver, u32 brd_ver), - TP_ARGS(dev, desc, tsf_low, data1, data2, line, - blink2, ilink1, ilink2, bcon_time, gp1, gp2, - rev_type, major, minor, hw_ver, brd_ver), + TP_PROTO(const struct device *dev, const struct iwl_error_event_table *table, + u32 hw_ver, u32 brd_ver), + TP_ARGS(dev, table, hw_ver, brd_ver), TP_STRUCT__entry( DEV_ENTRY __field(u32, desc)
@@ -155,20 +152,20 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, ),TP_fast_assign ( DEV_ASSIGN; - __entry->desc = desc; - __entry->tsf_low = tsf_low; - __entry->data1 = data1; - __entry->data2 = data2; - __entry->line = line; - __entry->blink2 = blink2; - __entry->ilink1 = ilink1; - __entry->ilink2 = ilink2; - __entry->bcon_time = bcon_time; - __entry->gp1 = gp1; - __entry->gp2 = gp2; - __entry->rev_type = rev_type; - __entry->major = major; - __entry->minor = minor; + __entry->desc = table->error_id; + __entry->tsf_low = table->tsf_low; + __entry->data1 = table->data1; + __entry->data2 = table->data2; + __entry->line = table->line; + __entry->blink2 = table->blink2; + __entry->ilink1 = table->ilink1; + __entry->ilink2 = table->ilink2; + __entry->bcon_time = table->bcon_time; + __entry->gp1 = table->gp1; + __entry->gp2 = table->gp2; + __entry->rev_type = table->gp3; + __entry->major = table->ucode_ver; + __entry->minor = table->hw_ver; __entry->hw_ver = hw_ver; __entry->brd_ver = brd_ver; ),
drivers/net/wireless/intel/iwlwifi/iwl-devtrace.c +1 -0
@@ -30,6 +30,7 @@#ifndef __CHECKER__#include "iwl-trans.h" +#include "dvm/commands.h" #define CREATE_TRACE_POINTS #include "iwl-devtrace.h"
drivers/net/wireless/intel/iwlwifi/mvm/utils.c +1 -6
@@ -549,12 +549,7 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm *mvm, u32 base)IWL_ERR (mvm,"Loaded firmware version: %s\n" , mvm->fw->fw_version); -trace_iwlwifi_dev_ucode_error (trans->dev, table.error_id, table.tsf_low, - table.data1, table.data2, table.data3, - table.blink2, table.ilink1, - table.ilink2, table.bcon_time, table.gp1, - table.gp2, table.fw_rev_type, table.major, - table.minor, table.hw_ver, table.brd_ver); +trace_iwlwifi_dev_ucode_error (trans->dev, &table, table.hw_ver, table.brd_ver);IWL_ERR (mvm,"0x%08X | %-28s\n" , table.error_id,desc_lookup (table.error_id));IWL_ERR (mvm,"0x%08X | trm_hw_status0\n" , table.trm_hw_status0);
Signature · 1 line
2.9.5
PATCH v5 5/10 macro: introduce COUNT_ARGS() macro
In reply to Alexei StarovoitovFrom: Alexei Starovoitov <[email protected]>
move COUNT_ARGS() macro from apparmor to generic header and extend it to count till twelve.
COUNT() was an alternative name for this logic, but it's used for different purpose in many other places.
Similarly for CONCATENATE() macro.
--- include/linux/kernel.h | 7 +++++++ security/apparmor/include/path.h | 7 +------ 2 files changed, 8 insertions(+), 6 deletions(-)
include/linux/kernel.h +7 -0
@@ -919,6 +919,13 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }#define swap (a, b) \ do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) +/* This counts to 12. Any more, it will return 13th argument. */ +#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n +#define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) + +#define __CONCAT (a, b) a ## b +#define CONCATENATE (a, b) __CONCAT(a, b) +/** * container_of - cast a member of a structure out to the containing structure * @ptr: the pointer to the member.
security/apparmor/include/path.h +1 -6
@@ -43,15 +43,10 @@ struct aa_buffers { DECLARE_PER_CPU(struct aa_buffers, aa_buffers); -#define COUNT_ARGS(X...) COUNT_ARGS_HELPER(, ##X, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) -#define COUNT_ARGS_HELPER(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, n, X...) n -#define CONCAT (X ,Y ) X ## Y -#define CONCAT_AFTER (X ,Y ) CONCAT(X, Y) -#define ASSIGN (FN ,X ,N ) ((X) = FN(N))#define EVAL1 (FN ,X ) ASSIGN(FN, X, 0)/*X = FN(0)*/ #define EVAL2(FN, X, Y...) do { ASSIGN(FN, X, 1); EVAL1(FN, Y); } while (0) -#define EVAL(FN, X...) CONCAT_AFTER(EVAL, COUNT_ARGS(X))(FN, X) +#define EVAL(FN, X...) CONCATENATE(EVAL, COUNT_ARGS(X))(FN, X)#define for_each_cpu_buffer (I ) for ((I) = 0; (I) < MAX_PATH_BUFFERS; (I)++)
Signature · 1 line
2.9.5
PATCH v5 6/10 tracepoint: compute num_args at build time
In reply to Alexei StarovoitovFrom: Alexei Starovoitov <[email protected]>
add fancy macro to compute number of arguments passed into tracepoint at compile time and store it as part of 'struct tracepoint'. The number is necessary to check safety of bpf program access that is coming in subsequent patch.
for_each_tracepoint_range() api has no users inside the kernel. Make it more useful with ability to stop for_each() loop depending via callback return value.
In such form it's used in subsequent patch.
--- include/linux/tracepoint-defs.h | 1 + include/linux/tracepoint.h | 28 +++++++++++++++++++--------- include/trace/define_trace.h | 14 +++++++------- kernel/tracepoint.c | 27 ++++++++++++++++----------- 4 files changed, 43 insertions(+), 27 deletions(-)
include/linux/tracepoint-defs.h +1 -0
@@ -33,6 +33,7 @@ struct tracepoint {int (*regfunc)(void );void (*unregfunc)(void );struct tracepoint_func __rcu *funcs; + u32 num_args; };#endif
include/linux/tracepoint.h +19 -9
@@ -40,9 +40,19 @@ tracepoint_probe_register_prio(struct tracepoint *tp, void *probe, void *data, int prio);extern int tracepoint_probe_unregister (struct tracepoint *tp,void *probe,void *data); -extern void -for_each_kernel_tracepoint (void (*fct)(struct tracepoint *tp,void *priv), -void *priv); + +#ifdef CONFIG_TRACEPOINTS +void * +for_each_kernel_tracepoint (void *(*fct)(struct tracepoint *tp,void *priv), +void *priv); +#else +static inline void * +for_each_kernel_tracepoint (void *(*fct)(struct tracepoint *tp,void *priv), +void *priv) +{ +return NULL ; +} +#endif #ifdef CONFIG_MODULES struct tp_module {
@@ -230,18 +240,18 @@ extern void syscall_unregfunc(void);* structures, so we create an array of pointers that will be used for iteration * on the tracepoints. */ -#define DEFINE_TRACE_FN (name, reg, unreg) \ +#define DEFINE_TRACE_FN (name, reg, unreg, num_args) \ static const char __tpstrtab_##name[] \ __attribute__((section("__tracepoints_strings"))) = #name; \ struct tracepoint __tracepoint_##name \ __attribute__((section("__tracepoints"))) = \ - { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\ + { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL, num_args };\ static struct tracepoint * const __tracepoint_ptr_##name __used \ __attribute__((section("__tracepoints_ptrs"))) = \ &__tracepoint_##name; -#define DEFINE_TRACE (name) \ - DEFINE_TRACE_FN(name, NULL, NULL); +#define DEFINE_TRACE (name, num_args) \ + DEFINE_TRACE_FN(name, NULL, NULL, num_args);#define EXPORT_TRACEPOINT_SYMBOL_GPL (name) \ EXPORT_SYMBOL_GPL(__tracepoint_##name)
@@ -275,8 +285,8 @@ extern void syscall_unregfunc(void);return false; \ } -#define DEFINE_TRACE_FN (name, reg, unreg) -#define DEFINE_TRACE (name) +#define DEFINE_TRACE_FN (name, reg, unreg, num_args) +#define DEFINE_TRACE (name, num_args)#define EXPORT_TRACEPOINT_SYMBOL_GPL (name)#define EXPORT_TRACEPOINT_SYMBOL (name)
include/trace/define_trace.h +7 -7
@@ -25,7 +25,7 @@#undef TRACE_EVENT#define TRACE_EVENT (name, proto, args, tstruct, assign, print) \ - DEFINE_TRACE(name) + DEFINE_TRACE(name, COUNT_ARGS(args))#undef TRACE_EVENT_CONDITION#define TRACE_EVENT_CONDITION (name, proto, args, cond, tstruct, assign, print) \
@@ -39,24 +39,24 @@#undef TRACE_EVENT_FN#define TRACE_EVENT_FN (name, proto, args, tstruct, \ assign, print, reg, unreg) \ - DEFINE_TRACE_FN(name, reg, unreg) + DEFINE_TRACE_FN(name, reg, unreg, COUNT_ARGS(args))#undef TRACE_EVENT_FN_COND#define TRACE_EVENT_FN_COND (name, proto, args, cond, tstruct, \ assign, print, reg, unreg) \ - DEFINE_TRACE_FN(name, reg, unreg) + DEFINE_TRACE_FN(name, reg, unreg, COUNT_ARGS(args))#undef DEFINE_EVENT#define DEFINE_EVENT (template, name, proto, args) \ - DEFINE_TRACE(name) + DEFINE_TRACE(name, COUNT_ARGS(args))#undef DEFINE_EVENT_FN#define DEFINE_EVENT_FN (template, name, proto, args, reg, unreg) \ - DEFINE_TRACE_FN(name, reg, unreg) + DEFINE_TRACE_FN(name, reg, unreg, COUNT_ARGS(args))#undef DEFINE_EVENT_PRINT#define DEFINE_EVENT_PRINT (template, name, proto, args, print) \ - DEFINE_TRACE(name) + DEFINE_TRACE(name, COUNT_ARGS(args))#undef DEFINE_EVENT_CONDITION#define DEFINE_EVENT_CONDITION (template, name, proto, args, cond) \
@@ -64,7 +64,7 @@#undef DECLARE_TRACE#define DECLARE_TRACE (name, proto, args) \ - DEFINE_TRACE(name) + DEFINE_TRACE(name, COUNT_ARGS(args))#undef TRACE_INCLUDE#undef __TRACE_INCLUDE
kernel/tracepoint.c +16 -11
@@ -502,17 +502,22 @@ static __init int init_tracepoints(void)__initcall (init_tracepoints);#endif /* CONFIG_MODULES */ -static void for_each_tracepoint_range (struct tracepoint *const *begin, -struct tracepoint *const *end, -void (*fct)(struct tracepoint *tp,void *priv), -void *priv) +static void *for_each_tracepoint_range (struct tracepoint *const *begin, +struct tracepoint *const *end, +void *(*fct)(struct tracepoint *tp,void *priv), +void *priv) {struct tracepoint *const *iter; +void *ret;if (!begin) -return ; -for (iter = begin; iter < end; iter++) -fct (*iter, priv); +return NULL ; +for (iter = begin; iter < end; iter++) { + ret =fct (*iter, priv); +if (ret) +return ret; + } +return NULL ; }/**
@@ -520,11 +525,11 @@ static void for_each_tracepoint_range(struct tracepoint * const *begin,* @fct: callback * @priv: private data */ -void for_each_kernel_tracepoint (void (*fct)(struct tracepoint *tp,void *priv), -void *priv) +void *for_each_kernel_tracepoint (void *(*fct)(struct tracepoint *tp,void *priv), +void *priv) { -for_each_tracepoint_range (__start___tracepoints_ptrs, - __stop___tracepoints_ptrs, fct, priv); +return for_each_tracepoint_range (__start___tracepoints_ptrs, + __stop___tracepoints_ptrs, fct, priv); }EXPORT_SYMBOL_GPL (for_each_kernel_tracepoint);
Signature · 1 line
2.9.5
Steven Rostedt
maintainerRe: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 11 lines · On Fri, 23 Mar 2018 19:30:34 -0700 Alexei Starovoitov <[email protected]> wrote:
From: Alexei Starovoitov <[email protected]>
add fancy macro to compute number of arguments passed into tracepoint at compile time and store it as part of 'struct tracepoint'. The number is necessary to check safety of bpf program access that is coming in subsequent patch.
for_each_tracepoint_range()api has no users inside the kernel. Make it more useful with ability to stopfor_each()loop depending via callback return value.
In such form it's used in subsequent patch.
I believe this is used by LTTng.
-- Steve
Quoted 184 lines
Signed-off-by Alexei Starovoitov <[email protected]>--- include/linux/tracepoint-defs.h | 1 + include/linux/tracepoint.h | 28 +++++++++++++++++++--------- include/trace/define_trace.h | 14 +++++++------- kernel/tracepoint.c | 27 ++++++++++++++++----------- 4 files changed, 43 insertions(+), 27 deletions(-)include/linux/tracepoint-defs.h +1
-0@@ -33,6 +33,7 @@ struct tracepoint {int (*regfunc)(void );void (*unregfunc)(void );struct tracepoint_func __rcu *funcs; + u32 num_args; };#endif include/linux/tracepoint.h +19
-9@@ -40,9 +40,19 @@ tracepoint_probe_register_prio(struct tracepoint *tp, void *probe, void *data, int prio);extern int tracepoint_probe_unregister (struct tracepoint *tp,void *probe,void *data); -extern void -for_each_kernel_tracepoint (void (*fct)(struct tracepoint *tp,void *priv), -void *priv); + +#ifdef CONFIG_TRACEPOINTS +void * +for_each_kernel_tracepoint (void *(*fct)(struct tracepoint *tp,void *priv), +void *priv); +#else +static inline void * +for_each_kernel_tracepoint (void *(*fct)(struct tracepoint *tp,void *priv), +void *priv) +{ +return NULL ; +} +#endif #ifdef CONFIG_MODULES struct tp_module {@@ -230,18 +240,18 @@ extern void syscall_unregfunc(void);* structures, so we create an array of pointers that will be used for iteration * on the tracepoints. */ -#define DEFINE_TRACE_FN (name, reg, unreg) \ +#define DEFINE_TRACE_FN (name, reg, unreg, num_args) \ static const char __tpstrtab_##name[] \ __attribute__((section("__tracepoints_strings"))) = #name; \ struct tracepoint __tracepoint_##name \ __attribute__((section("__tracepoints"))) = \ - { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\ + { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL, num_args };\ static struct tracepoint * const __tracepoint_ptr_##name __used \ __attribute__((section("__tracepoints_ptrs"))) = \ &__tracepoint_##name; -#define DEFINE_TRACE (name) \ - DEFINE_TRACE_FN(name, NULL, NULL); +#define DEFINE_TRACE (name, num_args) \ + DEFINE_TRACE_FN(name, NULL, NULL, num_args);#define EXPORT_TRACEPOINT_SYMBOL_GPL (name) \ EXPORT_SYMBOL_GPL(__tracepoint_##name)@@ -275,8 +285,8 @@ extern void syscall_unregfunc(void);return false; \ } -#define DEFINE_TRACE_FN (name, reg, unreg) -#define DEFINE_TRACE (name) +#define DEFINE_TRACE_FN (name, reg, unreg, num_args) +#define DEFINE_TRACE (name, num_args)#define EXPORT_TRACEPOINT_SYMBOL_GPL (name)#define EXPORT_TRACEPOINT_SYMBOL (name)include/trace/define_trace.h +7
-7@@ -25,7 +25,7 @@#undef TRACE_EVENT#define TRACE_EVENT (name, proto, args, tstruct, assign, print) \ - DEFINE_TRACE(name) + DEFINE_TRACE(name, COUNT_ARGS(args))#undef TRACE_EVENT_CONDITION#define TRACE_EVENT_CONDITION (name, proto, args, cond, tstruct, assign, print) \@@ -39,24 +39,24 @@#undef TRACE_EVENT_FN#define TRACE_EVENT_FN (name, proto, args, tstruct, \ assign, print, reg, unreg) \ - DEFINE_TRACE_FN(name, reg, unreg) + DEFINE_TRACE_FN(name, reg, unreg, COUNT_ARGS(args))#undef TRACE_EVENT_FN_COND#define TRACE_EVENT_FN_COND (name, proto, args, cond, tstruct, \ assign, print, reg, unreg) \ - DEFINE_TRACE_FN(name, reg, unreg) + DEFINE_TRACE_FN(name, reg, unreg, COUNT_ARGS(args))#undef DEFINE_EVENT#define DEFINE_EVENT (template, name, proto, args) \ - DEFINE_TRACE(name) + DEFINE_TRACE(name, COUNT_ARGS(args))#undef DEFINE_EVENT_FN#define DEFINE_EVENT_FN (template, name, proto, args, reg, unreg) \ - DEFINE_TRACE_FN(name, reg, unreg) + DEFINE_TRACE_FN(name, reg, unreg, COUNT_ARGS(args))#undef DEFINE_EVENT_PRINT#define DEFINE_EVENT_PRINT (template, name, proto, args, print) \ - DEFINE_TRACE(name) + DEFINE_TRACE(name, COUNT_ARGS(args))#undef DEFINE_EVENT_CONDITION#define DEFINE_EVENT_CONDITION (template, name, proto, args, cond) \@@ -64,7 +64,7 @@#undef DECLARE_TRACE#define DECLARE_TRACE (name, proto, args) \ - DEFINE_TRACE(name) + DEFINE_TRACE(name, COUNT_ARGS(args))#undef TRACE_INCLUDE#undef __TRACE_INCLUDEkernel/tracepoint.c +16
-11@@ -502,17 +502,22 @@ static __init int init_tracepoints(void)__initcall (init_tracepoints);#endif /* CONFIG_MODULES */ -static void for_each_tracepoint_range (struct tracepoint *const *begin, -struct tracepoint *const *end, -void (*fct)(struct tracepoint *tp,void *priv), -void *priv) +static void *for_each_tracepoint_range (struct tracepoint *const *begin, +struct tracepoint *const *end, +void *(*fct)(struct tracepoint *tp,void *priv), +void *priv) {struct tracepoint *const *iter; +void *ret;if (!begin) -return ; -for (iter = begin; iter < end; iter++) -fct (*iter, priv); +return NULL ; +for (iter = begin; iter < end; iter++) { + ret =fct (*iter, priv); +if (ret) +return ret; + } +return NULL ; }/** @@ -520,11 +525,11 @@ static void for_each_tracepoint_range(struct tracepoint * const *begin,* @fct: callback * @priv: private data */ -void for_each_kernel_tracepoint (void (*fct)(struct tracepoint *tp,void *priv), -void *priv) +void *for_each_kernel_tracepoint (void *(*fct)(struct tracepoint *tp,void *priv), +void *priv) { -for_each_tracepoint_range (__start___tracepoints_ptrs, - __stop___tracepoints_ptrs, fct, priv); +return for_each_tracepoint_range (__start___tracepoints_ptrs, + __stop___tracepoints_ptrs, fct, priv); }EXPORT_SYMBOL_GPL (for_each_kernel_tracepoint);
Mathieu Desnoyers
reviewerRe: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 10 lines · ----- On Mar 26, 2018, at 11:02 AM, rostedt [email protected] wrote:
Quoted 7 lines · On Fri, 23 Mar 2018 19:30:34 -0700 Alexei Starovoitov <[email protected]> wrote:
From: Alexei Starovoitov <[email protected]>
add fancy macro to compute number of arguments passed into tracepoint at compile time and store it as part of 'struct tracepoint'. The number is necessary to check safety of bpf program access that is coming in subsequent patch.
Quoted 6 lines
Quoted 4 lines
for_each_tracepoint_range()api has no users inside the kernel. Make it more useful with ability to stopfor_each()loop depending via callback return value.
In such form it's used in subsequent patch.I believe this is used by LTTng.
Indeed, and by SystemTAP as well.
What justifies the need to stop mid-iteration ? A less intrusive alternative would be to use the "priv" data pointer to keep state telling further calls to return immediately. Does performance of iteration over tracepoints really matter here so much that stopping iteration immediately is worth it ?
Thanks,
Mathieu
Quoted 189 lines
-- Steve
Quoted 186 lines
Signed-off-by Alexei Starovoitov <[email protected]>--- include/linux/tracepoint-defs.h | 1 + include/linux/tracepoint.h | 28 +++++++++++++++++++--------- include/trace/define_trace.h | 14 +++++++------- kernel/tracepoint.c | 27 ++++++++++++++++----------- 4 files changed, 43 insertions(+), 27 deletions(-)include/linux/tracepoint-defs.h +1
-0@@ -33,6 +33,7 @@ struct tracepoint {int (*regfunc)(void );void (*unregfunc)(void );struct tracepoint_func __rcu *funcs; + u32 num_args; };#endif include/linux/tracepoint.h +13
-3@@ -40,9 +40,19 @@ tracepoint_probe_register_prio(struct tracepoint *tp, void *probe, void *data, int prio);extern int tracepoint_probe_unregister (struct tracepoint *tp,void *probe,void *data); -extern void -for_each_kernel_tracepoint (void (*fct)(struct tracepoint *tp,void *priv), -void *priv); + +#ifdef CONFIG_TRACEPOINTS +void * +for_each_kernel_tracepoint (void *(*fct)(struct tracepoint *tp,void *priv), +void *priv); +#else +static inline void * +for_each_kernel_tracepoint (void *(*fct)(struct tracepoint *tp,void *priv), +void *priv) +{ +return NULL ; +} +#endif #ifdef CONFIG_MODULES struct
tp_module{include/linux/tracepoint.h +6
-6@@ -230,18 +240,18 @@ extern void syscall_unregfunc(void);* structures, so we create an array of pointers that will be used for iteration * on the tracepoints. */ -#define DEFINE_TRACE_FN (name, reg, unreg) \ +#define DEFINE_TRACE_FN (name, reg, unreg, num_args) \ static const char __tpstrtab_##name[] \ __attribute__((section("__tracepoints_strings"))) = #name; \ struct tracepoint __tracepoint_##name \ __attribute__((section("__tracepoints"))) = \ - { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\ + { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL, num_args };\ static struct tracepoint * const __tracepoint_ptr_##name __used \ __attribute__((section("__tracepoints_ptrs"))) = \ &__tracepoint_##name; -#define DEFINE_TRACE (name) \ - DEFINE_TRACE_FN(name, NULL, NULL); +#define DEFINE_TRACE (name, num_args) \ + DEFINE_TRACE_FN(name, NULL, NULL, num_args);#define EXPORT_TRACEPOINT_SYMBOL_GPL (name) \ EXPORT_SYMBOL_GPL(__tracepoint_##name)@@ -275,8 +285,8 @@ extern void syscall_unregfunc(void);return false; \ } -#define DEFINE_TRACE_FN (name, reg, unreg) -#define DEFINE_TRACE (name) +#define DEFINE_TRACE_FN (name, reg, unreg, num_args) +#define DEFINE_TRACE (name, num_args)#define EXPORT_TRACEPOINT_SYMBOL_GPL (name)#define EXPORT_TRACEPOINT_SYMBOL (name)include/trace/define_trace.h +7
-7@@ -25,7 +25,7 @@#undef TRACE_EVENT#define TRACE_EVENT (name, proto, args, tstruct, assign, print) \ - DEFINE_TRACE(name) + DEFINE_TRACE(name, COUNT_ARGS(args))#undef TRACE_EVENT_CONDITION#define TRACE_EVENT_CONDITION (name, proto, args, cond, tstruct, assign, print) \@@ -39,24 +39,24 @@#undef TRACE_EVENT_FN#define TRACE_EVENT_FN (name, proto, args, tstruct, \ assign, print, reg, unreg) \ - DEFINE_TRACE_FN(name, reg, unreg) + DEFINE_TRACE_FN(name, reg, unreg, COUNT_ARGS(args))#undef TRACE_EVENT_FN_COND#define TRACE_EVENT_FN_COND (name, proto, args, cond, tstruct, \ assign, print, reg, unreg) \ - DEFINE_TRACE_FN(name, reg, unreg) + DEFINE_TRACE_FN(name, reg, unreg, COUNT_ARGS(args))#undef DEFINE_EVENT#define DEFINE_EVENT (template, name, proto, args) \ - DEFINE_TRACE(name) + DEFINE_TRACE(name, COUNT_ARGS(args))#undef DEFINE_EVENT_FN#define DEFINE_EVENT_FN (template, name, proto, args, reg, unreg) \ - DEFINE_TRACE_FN(name, reg, unreg) + DEFINE_TRACE_FN(name, reg, unreg, COUNT_ARGS(args))#undef DEFINE_EVENT_PRINT#define DEFINE_EVENT_PRINT (template, name, proto, args, print) \ - DEFINE_TRACE(name) + DEFINE_TRACE(name, COUNT_ARGS(args))#undef DEFINE_EVENT_CONDITION#define DEFINE_EVENT_CONDITION (template, name, proto, args, cond) \@@ -64,7 +64,7 @@#undef DECLARE_TRACE#define DECLARE_TRACE (name, proto, args) \ - DEFINE_TRACE(name) + DEFINE_TRACE(name, COUNT_ARGS(args))#undef TRACE_INCLUDE#undef __TRACE_INCLUDEkernel/tracepoint.c +16
-11@@ -502,17 +502,22 @@ static __init int init_tracepoints(void)__initcall (init_tracepoints);#endif /* CONFIG_MODULES */ -static void for_each_tracepoint_range (struct tracepoint *const *begin, -struct tracepoint *const *end, -void (*fct)(struct tracepoint *tp,void *priv), -void *priv) +static void *for_each_tracepoint_range (struct tracepoint *const *begin, +struct tracepoint *const *end, +void *(*fct)(struct tracepoint *tp,void *priv), +void *priv) {struct tracepoint *const *iter; +void *ret;if (!begin) -return ; -for (iter = begin; iter < end; iter++) -fct (*iter, priv); +return NULL ; +for (iter = begin; iter < end; iter++) { + ret =fct (*iter, priv); +if (ret) +return ret; + } +return NULL ; }/** @@ -520,11 +525,11 @@ static void for_each_tracepoint_range(struct tracepoint *const *begin, * @fct: callback * @priv: private data */ -void for_each_kernel_tracepoint (void (*fct)(struct tracepoint *tp,void *priv), -void *priv) +void *for_each_kernel_tracepoint (void *(*fct)(struct tracepoint *tp,void *priv), +void *priv) { -for_each_tracepoint_range (__start___tracepoints_ptrs, - __stop___tracepoints_ptrs, fct, priv); +return for_each_tracepoint_range (__start___tracepoints_ptrs, + __stop___tracepoints_ptrs, fct, priv); }
EXPORT_SYMBOL_GPL(for_each_kernel_tracepoint);
Signature · 3 lines
Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com
Re: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 17 lines · Mathieu Desnoyers
Quoted 15 lines · ----- On Mar 26, 2018, at 11:02 AM, rostedt [email protected] wrote:
Quoted 11 lines · On Fri, 23 Mar 2018 19:30:34 -0700 Alexei Starovoitov <[email protected]> wrote:
From: Alexei Starovoitov <[email protected]>
add fancy macro to compute number of arguments passed into tracepoint at compile time and store it as part of 'struct tracepoint'. The number is necessary to check safety of bpf program access that is coming in subsequent patch.
for_each_tracepoint_range()api has no users inside the kernel. Make it more useful with ability to stopfor_each()loop depending via callback return value.
In such form it's used in subsequent patch.
Quoted 8 lines
Quoted 1 line
I believe this is used by LTTng.
Indeed, and by SystemTAP as well.
What justifies the need to stop mid-iteration ? A less intrusive alternative would be to use the "priv" data pointer to keep state telling further calls to return immediately. Does performance of iteration over tracepoints really matter here so much that stopping iteration immediately is worth it ?
I'm sure both you and Steven are not serious when you object to _in-tree_ change to for_each_kernel_tracepoint() that affects _out-of_tree_ modules?
Just change your module to 'return NULL' instead of plain 'return'.
Mathieu Desnoyers
reviewerRe: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 27 lines · ----- On Mar 26, 2018, at 11:42 AM, Alexei Starovoitov [email protected] wrote:
Quoted 17 lines · Mathieu Desnoyers
Quoted 15 lines · ----- On Mar 26, 2018, at 11:02 AM, rostedt [email protected] wrote:
Quoted 11 lines · On Fri, 23 Mar 2018 19:30:34 -0700 Alexei Starovoitov <[email protected]> wrote:
From: Alexei Starovoitov <[email protected]>
add fancy macro to compute number of arguments passed into tracepoint at compile time and store it as part of 'struct tracepoint'. The number is necessary to check safety of bpf program access that is coming in subsequent patch.
for_each_tracepoint_range()api has no users inside the kernel. Make it more useful with ability to stopfor_each()loop depending via callback return value.
In such form it's used in subsequent patch.Quoted 8 lines
Quoted 1 line
I believe this is used by LTTng.
Indeed, and by SystemTAP as well.
What justifies the need to stop mid-iteration ? A less intrusive alternative would be to use the "priv" data pointer to keep state telling further calls to return immediately. Does performance of iteration over tracepoints really matter here so much that stopping iteration immediately is worth it ?
Quoted 5 lines
I'm sure both you and Steven are not serious when you object to _in-tree_ change to
for_each_kernel_tracepoint()that affects _out-of_tree_ modules?Just change your module to 'return NULL' instead of plain 'return'.
I never said I objected to adapt the LTTng out of tree code. If there is a solid reason for changing the kernel API, I will adapt my code to those changes.
What I'm trying to understand here is whether there is solid ground for the added complexity you are proposing. Is it a performance enhancement ? If so, explanation of the use cases targeted, and numbers that measure performance improvements are needed.
How is your patch making tracepoints "more useful" ?
Thanks,
Mathieu
Signature · 3 lines
Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com
Re: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 39 lines · Mathieu Desnoyers
Quoted 27 lines · ----- On Mar 26, 2018, at 11:42 AM, Alexei Starovoitov [email protected] wrote:
Quoted 17 lines · Mathieu Desnoyers
Quoted 15 lines · ----- On Mar 26, 2018, at 11:02 AM, rostedt [email protected] wrote:
Quoted 11 lines · On Fri, 23 Mar 2018 19:30:34 -0700 Alexei Starovoitov <[email protected]> wrote:
From: Alexei Starovoitov <[email protected]>
add fancy macro to compute number of arguments passed into tracepoint at compile time and store it as part of 'struct tracepoint'. The number is necessary to check safety of bpf program access that is coming in subsequent patch.
for_each_tracepoint_range()api has no users inside the kernel. Make it more useful with ability to stopfor_each()loop depending via callback return value.
In such form it's used in subsequent patch.Quoted 8 lines
Quoted 1 line
I believe this is used by LTTng.
Indeed, and by SystemTAP as well.
What justifies the need to stop mid-iteration ? A less intrusive alternative would be to use the "priv" data pointer to keep state telling further calls to return immediately. Does performance of iteration over tracepoints really matter here so much that stopping iteration immediately is worth it ?
Quoted 5 lines
I'm sure both you and Steven are not serious when you object to _in-tree_ change to
for_each_kernel_tracepoint()that affects _out-of_tree_ modules?Just change your module to 'return NULL' instead of plain 'return'.
I never said I objected to adapt the LTTng out of tree code. If there is a solid reason for changing the kernel API, I will adapt my code to those changes.
Quoted 6 lines
What I'm trying to understand here is whether there is solid ground for the added complexity you are proposing. Is it a performance enhancement ? If so, explanation of the use cases targeted, and numbers that measure performance improvements are needed.
How is your patch making tracepoints "more useful" ?
are you arguing about the whole set overall or about a change to for_each_kernel_tracepoint() ?
I'm hearing your arguments as that now changes to all exported functions need to be "solid" (not sure what exactly means 'solid' here) to justify breakage of out-of-tree modules?
re: 'added complexity'...
- for (iter = begin; iter < end; iter++)
- fct(*iter, priv);
+ return NULL;
+ for (iter = begin; iter < end; iter++) {
+ ret = fct(*iter, priv);
+ if (ret)
+ return ret;
+ }
+ return NULL;
where do you see 'added complexity' ?
Isn't the above diff self-explanatory that for_each_tracepoint_range() can be used not only to iterate over all tracepoints
(just do 'return NULL') from callback _and_ to find one particular tracepoint as patch 7 does ?
Mathieu Desnoyers
reviewerRe: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 45 lines · ----- On Mar 26, 2018, at 12:08 PM, Alexei Starovoitov [email protected] wrote:
Quoted 44 lines · Mathieu Desnoyers
Quoted 27 lines · ----- On Mar 26, 2018, at 11:42 AM, Alexei Starovoitov [email protected] wrote:
Quoted 17 lines · Mathieu Desnoyers
Quoted 15 lines · ----- On Mar 26, 2018, at 11:02 AM, rostedt [email protected] wrote:
Quoted 11 lines · On Fri, 23 Mar 2018 19:30:34 -0700 Alexei Starovoitov <[email protected]> wrote:
From: Alexei Starovoitov <[email protected]>
add fancy macro to compute number of arguments passed into tracepoint at compile time and store it as part of 'struct tracepoint'. The number is necessary to check safety of bpf program access that is coming in subsequent patch.
for_each_tracepoint_range()api has no users inside the kernel. Make it more useful with ability to stopfor_each()loop depending via callback return value.
In such form it's used in subsequent patch.Quoted 8 lines
Quoted 1 line
I believe this is used by LTTng.
Indeed, and by SystemTAP as well.
What justifies the need to stop mid-iteration ? A less intrusive alternative would be to use the "priv" data pointer to keep state telling further calls to return immediately. Does performance of iteration over tracepoints really matter here so much that stopping iteration immediately is worth it ?
Quoted 5 lines
I'm sure both you and Steven are not serious when you object to _in-tree_ change to
for_each_kernel_tracepoint()that affects _out-of_tree_ modules?Just change your module to 'return NULL' instead of plain 'return'.
I never said I objected to adapt the LTTng out of tree code. If there is a solid reason for changing the kernel API, I will adapt my code to those changes.
What I'm trying to understand here is whether there is solid ground for the added complexity you are proposing. Is it a performance enhancement ? If so, explanation of the use cases targeted, and numbers that measure performance improvements are needed.
Quoted 4 lines
Quoted 1 line
How is your patch making tracepoints "more useful" ?
are you arguing about the whole set overall or about a change to
for_each_kernel_tracepoint()?
I'm perfectly fine with adding the "num_args" stuff. I think it's really useful. It's only the for_each_kernel_tracepoint change for which I'm trying to understand the rationale.
Quoted 3 lines
I'm hearing your arguments as that now changes to all exported functions need to be "solid" (not sure what exactly means 'solid' here) to justify breakage of out-of-tree modules?
No. Any added complexity to tracepoint.c needs to be justified appropriately.
Quoted 12 lines
re: 'added complexity'...
kernel/tracepoint.c +7
-2-for (iter = begin; iter < end; iter++) -fct (*iter, priv); +return NULL ; +for (iter = begin; iter < end; iter++) { + ret =fct (*iter, priv); +if (ret) +return ret; + } +return NULL ;
Quoted 5 lines
where do you see 'added complexity' ?
Isn't the above diff self-explanatory thatfor_each_tracepoint_range()can be used not only to iterate over all tracepoints
(just do 'return NULL') from callback _and_ to find one particular tracepoint as patch 7 does ?
I am not arguing about your proposed implementation. I am arguing about the lack of justification behind this change. Why is this change needed ? What is it allowing you to do that cannot be done using the private data pointer ?
Thanks,
Mathieu
Signature · 3 lines
Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com
Re: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 18 lines · Mathieu Desnoyers
Quoted 12 lines
re: 'added complexity'...
(quoted diff) +7
-2- for (iter = begin; iter < end; iter++) - fct(*iter, priv); + return NULL; + for (iter = begin; iter < end; iter++) { + ret = fct(*iter, priv); + if (ret) + return ret; + } + return NULL;Quoted 5 lines
where do you see 'added complexity' ?
Isn't the above diff self-explanatory thatfor_each_tracepoint_range()can be used not only to iterate over all tracepoints
(just do 'return NULL') from callback _and_ to find one particular tracepoint as patch 7 does ?
Quoted 4 lines
I am not arguing about your proposed implementation. I am arguing about the lack of justification behind this change. Why is this change needed ? What is it allowing you to do that cannot be done using the private data pointer ?
commit log of patch 6 states:
"for_each_tracepoint_range() api has no users inside the kernel. Make it more useful with ability to stop for_each() loop depending via callback return value.
In such form it's used in subsequent patch."
and in patch 7:
+static void *__find_tp(struct tracepoint *tp, void *priv) +{
+ char *name = priv;
+
+ if (!strcmp(tp->name, name))
+ return tp;
+ return NULL;
+}
...
+ struct tracepoint *tp;
...
+ tp = for_each_kernel_tracepoint(__find_tp, tp_name);
+ if (!tp)
+ return -ENOENT;
still not obvious?
Steven Rostedt
maintainerRe: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 24 lines · On Mon, 26 Mar 2018 09:25:07 -0700 Alexei Starovoitov <[email protected]> wrote:
commit log of patch 6 states:
"
for_each_tracepoint_range()api has no users inside the kernel. Make it more useful with ability to stopfor_each()loop depending via callback return value.
In such form it's used in subsequent patch."and in patch 7:
(quoted diff) +12
-0+static void *__find_tp(struct tracepoint *tp, void *priv) +{ + char *name = priv; + + if (!strcmp(tp->name, name)) + return tp; + return NULL; +} + struct tracepoint *tp; + tp = for_each_kernel_tracepoint(__find_tp, tp_name); + if (!tp) + return -ENOENT;
Quoted 1 line
still not obvious?
Please just create a new function called tracepoint_find_by_name(), and use that. I don't see any benefit in using a for_each* function for such a simple routine. Not to mention, you then don't need to know the internals of a tracepoint in kernel/bpf/syscall.c.
-- Steve
Re: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 27 lines · Steven Rostedt
Quoted 24 lines · On Mon, 26 Mar 2018 09:25:07 -0700 Alexei Starovoitov <[email protected]> wrote:
commit log of patch 6 states:
"
for_each_tracepoint_range()api has no users inside the kernel. Make it more useful with ability to stopfor_each()loop depending via callback return value.
In such form it's used in subsequent patch."and in patch 7:
(quoted diff) +12
-0+static void *__find_tp(struct tracepoint *tp, void *priv) +{ + char *name = priv; + + if (!strcmp(tp->name, name)) + return tp; + return NULL; +} + struct tracepoint *tp; + tp = for_each_kernel_tracepoint(__find_tp, tp_name); + if (!tp) + return -ENOENT;
Quoted 6 lines
Quoted 1 line
still not obvious?
Please just create a new function called
tracepoint_find_by_name(), and use that. I don't see any benefit in using a for_each* function for such a simple routine. Not to mention, you then don't need to know the internals of a tracepoint inkernel/bpf/syscall.c.
It's a standard pattern in the kernel to stop for_each*() iterator when callback function returns non-null.
Few examples:idr_for_eachcfs_hash_for_each
and there are plenty more.
I don't mind to _rename_ for_each_kernel_tracepoint() into tracepoint_find_by_name(), but keeping exported function just to be used by out-of-tree modules would be wrong message for the kernel community in general.
With my patch the for_each_kernel_tracepoint() will be used by bpf side and out-of-tree can trivially hack their callbacks to keep working. imo that's a better approach then renaming it.
Steven Rostedt
maintainerRe: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 7 lines · On Mon, 26 Mar 2018 09:47:21 -0700 Alexei Starovoitov <[email protected]> wrote:
I don't mind to _rename_
for_each_kernel_tracepoint()intotracepoint_find_by_name(), but keeping exported function just to be used by out-of-tree modules would be wrong message for the kernel community in general.
With my patch thefor_each_kernel_tracepoint()will be used by bpf side and out-of-tree can trivially hack their callbacks to keep working. imo that's a better approach then renaming it.
Look, the tracepoint code was written by Mathieu for LTTng, and perf and ftrace were able to benefit because of it, as well as your bpf code. For this, we agreed to keep this function around for his use, as its the only thing he requires. Everyone has been fine with that. Not all out of tree code is evil. In fact, some out of tree modules help the kernel community. You ask why I care. Because PREEMPT_RT has been one of those out of tree modules that has helped the kernel community a lot. Have you noticed that there are "raw_spin_lock()" and "spin_lock()"? There's no difference between the two in the kernel. Why have them? Because they are used by PREEMPT_RT.
Having that function for LTTng does not hurt us. And I will NACK removing it.
-- Stevwe
Mathieu Desnoyers
reviewerRe: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
In reply to Steven RostedtQuoted 27 lines · ----- On Mar 26, 2018, at 12:35 PM, rostedt [email protected] wrote:
Quoted 24 lines · On Mon, 26 Mar 2018 09:25:07 -0700 Alexei Starovoitov <[email protected]> wrote:
commit log of patch 6 states:
"
for_each_tracepoint_range()api has no users inside the kernel. Make it more useful with ability to stopfor_each()loop depending via callback return value.
In such form it's used in subsequent patch."and in patch 7:
(quoted diff) +12
-0+static void *__find_tp(struct tracepoint *tp, void *priv) +{ + char *name = priv; + + if (!strcmp(tp->name, name)) + return tp; + return NULL; +} + struct tracepoint *tp; + tp = for_each_kernel_tracepoint(__find_tp, tp_name); + if (!tp) + return -ENOENT;
Quoted 6 lines
Quoted 1 line
still not obvious?
Please just create a new function called
tracepoint_find_by_name(), and use that. I don't see any benefit in using a for_each* function for such a simple routine. Not to mention, you then don't need to know the internals of a tracepoint inkernel/bpf/syscall.c.
Steven's approach is fine by me, considering there should never be duplicated tracepoint definitions (it emits a __tracepoint_##name symbol which would cause multiple symbols definition errors at link time if there are more than a single definition per tracepoint name in the core kernel). The exported API should probably be named "kernel_tracepoint_find_by_name()" or something similar, thus indicating that it only lookup tracepoints in the core kernel.
Which brings the next question: what are Alexei's plan to handle tracepoints in modules, considering module load/unload scenarios ? The tracepoint API has module notifiers for this, but it does not appear to be used in this patch series.
Thanks,
Mathieu
Quoted 2 lines
-- Steve
Signature · 3 lines
Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com
Re: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 36 lines · Mathieu Desnoyers
Quoted 27 lines · ----- On Mar 26, 2018, at 12:35 PM, rostedt [email protected] wrote:
Quoted 24 lines · On Mon, 26 Mar 2018 09:25:07 -0700 Alexei Starovoitov <[email protected]> wrote:
commit log of patch 6 states:
"
for_each_tracepoint_range()api has no users inside the kernel. Make it more useful with ability to stopfor_each()loop depending via callback return value.
In such form it's used in subsequent patch."and in patch 7:
(quoted diff) +12
-0+static void *__find_tp(struct tracepoint *tp, void *priv) +{ + char *name = priv; + + if (!strcmp(tp->name, name)) + return tp; + return NULL; +} + struct tracepoint *tp; + tp = for_each_kernel_tracepoint(__find_tp, tp_name); + if (!tp) + return -ENOENT;Quoted 6 lines
Quoted 1 line
still not obvious?
Please just create a new function called
tracepoint_find_by_name(), and use that. I don't see any benefit in using a for_each* function for such a simple routine. Not to mention, you then don't need to know the internals of a tracepoint inkernel/bpf/syscall.c.
Quoted 6 lines
Steven's approach is fine by me, considering there should never be duplicated tracepoint definitions (it emits a __tracepoint_##name symbol which would cause multiple symbols definition errors at link time if there are more than a single definition per tracepoint name in the core kernel). The exported API should probably be named "
kernel_tracepoint_find_by_name()" or something similar, thus indicating that it only lookup tracepoints in the core kernel.
An email ago you were ok to s/return/return NULL/ in your out-of-tree module, but now flip flop to add new function approach just to reduce the work you need to do in lttng?
We're not talking about changing __kmalloc signature here. My patch extends for_each_kernel_tracepoint() api similar to other for_each_*() iterators and improves possible uses of it.
It can event help lltng.
lttng-tracepoint.c is doing:
for_each_kernel_tracepoint(lttng_kernel_tracepoint_add, &ret);
to copy kernel tracepoints into its own hash table.
Only to later do:
/*
* Get tracepoint if the tracepoint is present in the tracepoint hash
table.
* Must be called with lttng_tracepoint_mutex held.
* Returns NULL if not present.
*/
static
struct tracepoint_entry *get_tracepoint(const char *name)
{
struct hlist_head *head;
struct tracepoint_entry *e;
u32 hash = jhash(name, strlen(name), 0);
head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
lttng_hlist_for_each_entry(e, head, hlist) {
if (!strcmp(name, e->name))
return e;
}
return NULL;
}this use case potentially can be reimplemented in lttng with this extended for_each_kernel_tracepoint() api. Like I do on bpf side with very similar callback:
+static void *__find_tp(struct tracepoint *tp, void *priv) +{
+ char *name = priv;
+
+ if (!strcmp(tp->name, name))
+ return tp;
+ return NULL;
+}
Quoted 4 lines
Which brings the next question: what are Alexei's plan to handle tracepoints in modules, considering module load/unload scenarios ? The tracepoint API has module notifiers for this, but it does not appear to be used in this patch series.
correct. this set deals with in-kernel tracepoints only. No attempt to do anything with tracepoints inside modules.
but your question brings another question:
why kernel/module.c have this code:
mod->tracepoints_ptrs = section_objs(info, "__tracepoints_ptrs"
sizeof(*mod->tracepoints_ptrs),
&mod->num_tracepoints);and the whole module tracepoint notifier logic
that is only used by out-of-tree ?
I didn't realize so much of kernel code was taken hostage by lttng.
One thing is to be nice to out-of-tree and do not break them for no reason, but arguing that kernel shouldn't add a minor extension to for_each_kernel_tracepoint() api is really taking the whole thing to next level.
Also I hope you noticed that the patch is doing:
+++ b/include/linux/tracepoint-defs.h
@@ -33,6 +33,7 @@ struct tracepoint {
int (*regfunc)(void);
void (*unregfunc)(void);
struct tracepoint_func __rcu *funcs;+ u32 num_args;
};
To make sure that bpf programs are safe I need to do a static check in the verifier that programs don't access arguments beyond those specified by the tracepoint.
That was mentioned in the commit log of patch 6 too:
"
compute number of arguments passed into tracepoint
at compile time and store it as part of 'struct tracepoint'. The number is necessary to check safety of bpf program access that is coming in subsequent patch.
"
I suspect you will have the same objection?
It breaks out-of-tree modules?!
Steven Rostedt
maintainerRe: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 6 lines · On Mon, 26 Mar 2018 10:55:51 -0700 Alexei Starovoitov <[email protected]> wrote:
An email ago you were ok to s/return/return NULL/ in your out-of-tree module, but now flip flop to add new function approach just to reduce the work you need to do in lttng?
We're not talking about changing__kmallocsignature here. My patch extendsfor_each_kernel_tracepoint()api similar to other for_each_*() iterators and improves possible uses of it.
Alexei, do you have another use case for using for_each_kernel_tracepoint() other than the find_tp? If so, then I'm sure Mathieu can handle the change.
But I think it's cleaner to add a tracepoint_find_by_name() function. If you come up with another use case for using the for_each* function then we'll consider changing it then.
Quoted 4 lines
One thing is to be nice to out-of-tree and do not break them for no reason, but arguing that kernel shouldn't add a minor extension to
for_each_kernel_tracepoint()api is really taking the whole thing to next level.
That's not the point. I disagree with the reason for the change, and believe that it would be cleaner to add a find_by_name() function. Which would make your patch set even cleaner.
Instead of having in the bpf code:
static void *__find_tp(struct tracepoint *tp, void *priv)
{
char *name = priv;
if (!strcmp(tp->name, name))
return tp;
return NULL;
}[..]
tp = for_each_kernel_tracepoint(__find_tp, tp_name); if (!tp) return -ENOENT;
You would simply have:
tp = tracepoint_find_by_name(tp_name); if (!tp) return -ENOENT;
That would make the code more obvious to what it is doing. And this does not impede your patch set at all.
-- Steve
Re: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 10 lines · Steven Rostedt
Quoted 6 lines · On Mon, 26 Mar 2018 10:55:51 -0700 Alexei Starovoitov <[email protected]> wrote:
An email ago you were ok to s/return/return NULL/ in your out-of-tree module, but now flip flop to add new function approach just to reduce the work you need to do in lttng?
We're not talking about changing__kmallocsignature here. My patch extendsfor_each_kernel_tracepoint()api similar to other for_each_*() iterators and improves possible uses of it.
Quoted 7 lines
Alexei, do you have another use case for using
for_each_kernel_tracepoint()other than thefind_tp? If so, then I'm sure Mathieu can handle the change.But I think it's cleaner to add a
tracepoint_find_by_name()function. If you come up with another use case for using the for_each* function then we'll consider changing it then.
another use case ?! Frankly such reasoning smells.
I'm fine doing quick followup patch to add tracepoint_find_by_name() and restore 'return void' behavior of for_each_kernel_tracepoint's callback, but I'm struggling to accept the precedent it will create that all exported functions of kernel/tracepoint.c are really lttng extensions and we cannot easily change them.
I'd like to hear Linus take on this.
Steven Rostedt
maintainerRe: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 15 lines · On Mon, 26 Mar 2018 11:39:05 -0700 Alexei Starovoitov <[email protected]> wrote:
Quoted 14 lines · Steven Rostedt
Quoted 6 lines · On Mon, 26 Mar 2018 10:55:51 -0700 Alexei Starovoitov <[email protected]> wrote:
An email ago you were ok to s/return/return NULL/ in your out-of-tree module, but now flip flop to add new function approach just to reduce the work you need to do in lttng?
We're not talking about changing__kmallocsignature here. My patch extendsfor_each_kernel_tracepoint()api similar to other for_each_*() iterators and improves possible uses of it.Alexei, do you have another use case for using
for_each_kernel_tracepoint()other than thefind_tp? If so, then I'm sure Mathieu can handle the change.
Quoted 5 lines
Quoted 3 lines
But I think it's cleaner to add a
tracepoint_find_by_name()function. If you come up with another use case for using the for_each* function then we'll consider changing it then.another use case ?! Frankly such reasoning smells.
WTF is the big deal here?
Quoted 2 lines
I'm fine doing quick followup patch to add
tracepoint_find_by_name()
And BTW, it would actually have to be called tracepoint_core_find_by_name() as it will not deal with modules. Modules would have to have much more work to deal with.
Quoted 1 line
and restore 'return void' behavior of for_each_kernel_tracepoint's
What? you can't rebase now? Just don't touch that function.
Quoted 3 lines
callback, but I'm struggling to accept the precedent it will create that all exported functions of
kernel/tracepoint.care really lttng extensions and we cannot easily change them.
First, my argument about your use case has little to do with LTTng. I have to maintain this code, and this is my preference. Just like I do the silly
/* Comment like this,
* for multiple lines
*/
When I deal with the networking code. Because that's the preference for the networking folks.
Quoted 1 line
I'd like to hear Linus take on this.
I doubt he cares about something this petty.
-- Steve
Mathieu Desnoyers
reviewerRe: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
In reply to Alexei Starovoitov----- On Mar 26, 2018, at 1:55 PM, Alexei Starovoitov [email protected] wrote:
[...]
Quoted 3 lines
correct. this set deals with in-kernel tracepoints only. No attempt to do anything with tracepoints inside modules.
Please endeavor to handle in-module tracepoints properly, then we'll be able to pursue a more constructive discussion.
[...]
Quoted 13 lines
Also I hope you noticed that the patch is doing:
+++b/include/linux/tracepoint-defs.h(quoted diff) +1
-0@@ -33,6 +33,7 @@ struct tracepoint { int (*regfunc)(void); void (*unregfunc)(void); struct tracepoint_func __rcu *funcs; + u32 num_args; };To make sure that bpf programs are safe I need to do a static check in the verifier that programs don't access arguments beyond those specified by the tracepoint.
Quoted 7 lines
That was mentioned in the commit log of patch 6 too:
"
compute number of arguments passed into tracepoint
at compile time and store it as part of 'struct tracepoint'. The number is necessary to check safety of bpf program access that is coming in subsequent patch.
"
This part of the patch and its associated changelog is fine with me. Please submit it as a separate commit from the rest of the tracepoint.{c,h} changes.
[...]
Thanks,
Mathieu
Signature · 3 lines
Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com
Steven Rostedt
maintainerRe: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
In reply to Alexei StarovoitovQuoted 7 lines · On Fri, 23 Mar 2018 19:30:34 -0700 Alexei Starovoitov <[email protected]> wrote:
kernel/tracepoint.c +5
-0+static void *for_each_tracepoint_range (struct tracepoint *const *begin, +struct tracepoint *const *end, +void *(*fct)(struct tracepoint *tp,void *priv), +void *priv) {struct tracepoint *const *iter; +void *ret;
kernel/tracepoint.c static __init int init_tracepoints(void) · line 518
Quoted 10 lines
kernel/tracepoint.c +5
-3if (!begin) -return ; -for (iter = begin; iter < end; iter++) -fct (*iter, priv); +return NULL ; +for (iter = begin; iter < end; iter++) { + ret =fct (*iter, priv); +if (ret) +return ret;
So you just stopped the loop here. You have an inconsistent state. What about the functions that were called before. How do you undo them? Or what about the rest that haven't been touched. This function gives no feedback to the caller.
-- Steve
Quoted 3 lines
kernel/tracepoint.c +2
-0+ } +return NULL ; }
Steven Rostedt
maintainerRe: [PATCH v5 bpf-next 06/10] tracepoint: compute num_args at build time
Quoted 11 lines · On Mon, 26 Mar 2018 11:56:15 -0400 Steven Rostedt <[email protected]> wrote:
Quoted 8 lines · On Fri, 23 Mar 2018 19:30:34 -0700 Alexei Starovoitov <[email protected]> wrote:
kernel/tracepoint.c +5
-0+static void *for_each_tracepoint_range (struct tracepoint *const *begin, +struct tracepoint *const *end, +void *(*fct)(struct tracepoint *tp,void *priv), +void *priv) {struct tracepoint *const *iter; +void *ret;
Quoted 15 lines
kernel/tracepoint.c static __init int init_tracepoints(void) · line 518
Quoted 9 lines
kernel/tracepoint.c +5
-3if (!begin) -return ; -for (iter = begin; iter < end; iter++) -fct (*iter, priv); +return NULL ; +for (iter = begin; iter < end; iter++) { + ret =fct (*iter, priv); +if (ret) +return ret;So you just stopped the loop here. You have an inconsistent state. What about the functions that were called before. How do you undo them? Or what about the rest that haven't been touched. This function gives no feedback to the caller.
OK, I see my confusion with this patch. I much rather have a new function, and this isn't about being nice to out of tree modules. We can keep this function as is (to be nice), but my biggest squabble about this patch is that the function name is inconsistent to what its doing. When I have a function that says "for_each" I expect it to go through each function and not exit out. This is because of what I said above. When you have a "for_each" function that stops in the middle, you have a state that you may need to deal with. How would another use of that function clean up the mess if it expected to fail at some random location.
I see in the next patch that you are using it simply to find a tracepoint with the given name. I'd be much happier to add a new function called:
tracepoint_find_by_name(const char *name)
Because using a "for_each" to implement such a simple function seems more of a hack.
-- Steve
PATCH v5 7/10 bpf: introduce BPF_RAW_TRACEPOINT
In reply to Alexei StarovoitovFrom: Alexei Starovoitov <[email protected]>
Introduce BPF_PROG_TYPE_RAW_TRACEPOINT bpf program type to access kernel internal arguments of the tracepoints in their raw form.
Quoted 1 line
From bpf program point of view the access to the arguments look like:
struct bpf_raw_tracepoint_args {
__u64 args[0];
};int bpf_prog(struct bpf_raw_tracepoint_args *ctx) {
// program can read args[N] where N depends on tracepoint // and statically verified at program load+attach time
}
kprobe+bpf infrastructure allows programs access function arguments. This feature allows programs access raw tracepoint arguments.
Similar to proposed 'dynamic ftrace events' there are no abi guarantees to what the tracepoints arguments are and what their meaning is. The program needs to type cast args properly and use bpf_probe_read() helper to access struct fields when argument is a pointer.
For every tracepoint __bpf_trace_##call function is prepared. In assembler it looks like:
(gdb) disassemble __bpf_trace_xdp_exception
Dump of assembler code for function __bpf_trace_xdp_exception:
0xffffffff81132080 <+0>: mov %ecx,%ecx 0xffffffff81132082 <+2>: jmpq 0xffffffff811231f0 <bpf_trace_run3>
where
TRACE_EVENT(xdp_exception,
TP_PROTO(const struct net_device *dev,
const struct bpf_prog *xdp, u32 act),
The above assembler snippet is casting 32-bit 'act' field into 'u64' to pass into bpf_trace_run3(), while 'dev' and 'xdp' args are passed as-is. All of ~500 of __bpf_trace_*() functions are only 5-10 byte long and in total this approach adds 7k bytes to .text and 8k bytes
to .rodata since the probe funcs need to appear in kallsyms.
The alternative of having __bpf_trace_##call being global in kallsyms could have been to keep them static and add another pointer to these static functions to 'struct trace_event_class' and 'struct trace_event_call', but keeping them global simplifies implementation and keeps it indepedent from the tracing side.
Also such approach gives the lowest possible overhead while calling trace_xdp_exception() from kernel C code and transitioning into bpf land.
Since tracepoint+bpf are used at speeds of 1M+ events per second this is very valuable optimization.
Since ftrace and perf side are not involved the new BPF_RAW_TRACEPOINT_OPEN sys_bpf command is introduced that returns anon_inode FD of 'bpf-raw-tracepoint' object.
The user space looks like:
// load bpf prog with BPF_PROG_TYPE_RAW_TRACEPOINT type prog_fd = bpf_prog_load(...);
// receive anon_inode fd for given bpf_raw_tracepoint with prog attached raw_tp_fd = bpf_raw_tracepoint_open("xdp_exception", prog_fd);
Ctrl-C of tracing daemon or cmdline tool that uses this feature will automatically detach bpf program, unload it and unregister tracepoint probe.
On the kernel side for_each_kernel_tracepoint() is used to find a tracepoint with "xdp_exception" name (that would be __tracepoint_xdp_exception record)
Then kallsyms_lookup_name() is used to find the addr of __bpf_trace_xdp_exception() probe function.
And finally tracepoint_probe_register() is used to connect probe with tracepoint.
Addition of bpf_raw_tracepoint doesn't interfere with ftrace and perf tracepoint mechanisms. perf_event_open() can be used in parallel on the same tracepoint.
Multiple bpf_raw_tracepoint_open("xdp_exception", prog_fd) are permitted. Each with its own bpf program. The kernel will execute
all tracepoint probes and all attached bpf programs.
In the future bpf_raw_tracepoints can be extended with query/introspection logic.
--- include/linux/bpf_types.h | 1 + include/linux/trace_events.h | 37 +++++++++ include/trace/bpf_probe.h | 87 ++++++++++++++++++++ include/trace/define_trace.h | 1 + include/uapi/linux/bpf.h | 11 +++ kernel/bpf/syscall.c | 87 ++++++++++++++++++++ kernel/trace/bpf_trace.c | 188 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 412 insertions(+) create mode 100644 include/trace/bpf_probe.h
include/linux/bpf_types.h +1 -0
@@ -19,6 +19,7 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_SK_MSG, sk_msg) BPF_PROG_TYPE(BPF_PROG_TYPE_KPROBE, kprobe) BPF_PROG_TYPE(BPF_PROG_TYPE_TRACEPOINT, tracepoint) BPF_PROG_TYPE(BPF_PROG_TYPE_PERF_EVENT, perf_event) +BPF_PROG_TYPE(BPF_PROG_TYPE_RAW_TRACEPOINT, raw_tracepoint)#endif #ifdef CONFIG_CGROUP_BPF BPF_PROG_TYPE (BPF_PROG_TYPE_CGROUP_DEVICE , cg_dev)
include/linux/trace_events.h +37 -0
@@ -468,6 +468,8 @@ unsigned int trace_call_bpf(struct trace_event_call *call, void *ctx);int perf_event_attach_bpf_prog (struct perf_event *event,struct bpf_prog *prog);void perf_event_detach_bpf_prog (struct perf_event *event);int perf_event_query_prog_array (struct perf_event *event,void __user *info); +int bpf_probe_register (struct tracepoint *tp,struct bpf_prog *prog); +int bpf_probe_unregister (struct tracepoint *tp,struct bpf_prog *prog);#else static inline unsigned int trace_call_bpf (struct trace_event_call *call,void *ctx) {
@@ -487,6 +489,14 @@ perf_event_query_prog_array(struct perf_event *event, void __user *info) {return -EOPNOTSUPP ; } +static inline int bpf_probe_register (struct tracepoint *tp,struct bpf_prog *p) +{ +return -EOPNOTSUPP ; +} +static inline int bpf_probe_unregister (struct tracepoint *tp,struct bpf_prog *p) +{ +return -EOPNOTSUPP ; +}#endif enum {
@@ -546,6 +556,33 @@ extern void ftrace_profile_free_filter(struct perf_event *event);void perf_trace_buf_update (void *record,u16 type);void *perf_trace_buf_alloc (int size,struct pt_regs **regs,int *rctxp); +void bpf_trace_run1 (struct bpf_prog *prog,u64 arg1); +void bpf_trace_run2 (struct bpf_prog *prog,u64 arg1,u64 arg2); +void bpf_trace_run3 (struct bpf_prog *prog,u64 arg1,u64 arg2, +u64 arg3); +void bpf_trace_run4 (struct bpf_prog *prog,u64 arg1,u64 arg2, +u64 arg3,u64 arg4); +void bpf_trace_run5 (struct bpf_prog *prog,u64 arg1,u64 arg2, +u64 arg3,u64 arg4,u64 arg5); +void bpf_trace_run6 (struct bpf_prog *prog,u64 arg1,u64 arg2, +u64 arg3,u64 arg4,u64 arg5,u64 arg6); +void bpf_trace_run7 (struct bpf_prog *prog,u64 arg1,u64 arg2, +u64 arg3,u64 arg4,u64 arg5,u64 arg6,u64 arg7); +void bpf_trace_run8 (struct bpf_prog *prog,u64 arg1,u64 arg2, +u64 arg3,u64 arg4,u64 arg5,u64 arg6,u64 arg7, +u64 arg8); +void bpf_trace_run9 (struct bpf_prog *prog,u64 arg1,u64 arg2, +u64 arg3,u64 arg4,u64 arg5,u64 arg6,u64 arg7, +u64 arg8,u64 arg9); +void bpf_trace_run10 (struct bpf_prog *prog,u64 arg1,u64 arg2, +u64 arg3,u64 arg4,u64 arg5,u64 arg6,u64 arg7, +u64 arg8,u64 arg9,u64 arg10); +void bpf_trace_run11 (struct bpf_prog *prog,u64 arg1,u64 arg2, +u64 arg3,u64 arg4,u64 arg5,u64 arg6,u64 arg7, +u64 arg8,u64 arg9,u64 arg10,u64 arg11); +void bpf_trace_run12 (struct bpf_prog *prog,u64 arg1,u64 arg2, +u64 arg3,u64 arg4,u64 arg5,u64 arg6,u64 arg7, +u64 arg8,u64 arg9,u64 arg10,u64 arg11,u64 arg12); void perf_trace_run_bpf_submit(void *raw_data, int size, int rctx, struct trace_event_call *call, u64 count, struct pt_regs *regs, struct hlist_head *head,
include/trace/bpf_probe.h new file +87 -0
87 lines not on this page · raw message
include/trace/define_trace.h +1 -0
@@ -95,6 +95,7 @@#ifdef TRACEPOINTS_ENABLED #include <trace/trace_events.h> #include <trace/perf.h> +#include <trace/bpf_probe.h> #endif #undef TRACE_EVENT
include/uapi/linux/bpf.h +11 -0
@@ -94,6 +94,7 @@ enum bpf_cmd {BPF_MAP_GET_FD_BY_ID ,BPF_OBJ_GET_INFO_BY_FD ,BPF_PROG_QUERY , + BPF_RAW_TRACEPOINT_OPEN, }; enum bpf_map_type {
@@ -134,6 +135,7 @@ enum bpf_prog_type {BPF_PROG_TYPE_SK_SKB ,BPF_PROG_TYPE_CGROUP_DEVICE ,BPF_PROG_TYPE_SK_MSG , + BPF_PROG_TYPE_RAW_TRACEPOINT, }; enum bpf_attach_type {
@@ -344,6 +346,11 @@ union bpf_attr {__aligned_u64 prog_ids;__u32 prog_cnt; } query; + +struct { +__u64 name; +__u32 prog_fd; + } raw_tracepoint; } __attribute__((aligned(8)));/* BPF helper function descriptions:
@@ -1152,4 +1159,8 @@ struct bpf_cgroup_dev_ctx { __u32 minor; }; +struct bpf_raw_tracepoint_args { +__u64 args[0 ]; +}; +#endif /* _UAPI__LINUX_BPF_H__ */
kernel/bpf/syscall.c +87 -0
99 lines not on this page · raw message
kernel/trace/bpf_trace.c +188 -0
197 lines not on this page · raw message
Signature · 1 line
2.9.5
PATCH v5 8/10 libbpf: add bpf_raw_tracepoint_open helper
In reply to Alexei StarovoitovFrom: Alexei Starovoitov <[email protected]>
add bpf_raw_tracepoint_open(const char *name, int prog_fd) api to libbpf
--- tools/include/uapi/linux/bpf.h | 11 +++++++++++ tools/lib/bpf/bpf.c | 11 +++++++++++ tools/lib/bpf/bpf.h | 1 + 3 files changed, 23 insertions(+)
tools/include/uapi/linux/bpf.h +11 -0
@@ -94,6 +94,7 @@ enum bpf_cmd {BPF_MAP_GET_FD_BY_ID ,BPF_OBJ_GET_INFO_BY_FD ,BPF_PROG_QUERY , + BPF_RAW_TRACEPOINT_OPEN, }; enum bpf_map_type {
@@ -134,6 +135,7 @@ enum bpf_prog_type {BPF_PROG_TYPE_SK_SKB ,BPF_PROG_TYPE_CGROUP_DEVICE ,BPF_PROG_TYPE_SK_MSG , + BPF_PROG_TYPE_RAW_TRACEPOINT, }; enum bpf_attach_type {
@@ -344,6 +346,11 @@ union bpf_attr {__aligned_u64 prog_ids;__u32 prog_cnt; } query; + +struct { +__u64 name; +__u32 prog_fd; + } raw_tracepoint; } __attribute__((aligned(8)));/* BPF helper function descriptions:
@@ -1151,4 +1158,8 @@ struct bpf_cgroup_dev_ctx { __u32 minor; }; +struct bpf_raw_tracepoint_args { +__u64 args[0 ]; +}; +#endif /* _UAPI__LINUX_BPF_H__ */
tools/lib/bpf/bpf.c +11 -0
@@ -428,6 +428,17 @@ int bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len)return err; } +int bpf_raw_tracepoint_open (const char *name,int prog_fd) +{ +union bpf_attr attr; + +bzero (&attr,sizeof (attr)); + attr.raw_tracepoint.name =ptr_to_u64 (name); + attr.raw_tracepoint.prog_fd = prog_fd; + +return sys_bpf (BPF_RAW_TRACEPOINT_OPEN , &attr,sizeof (attr)); +} +int bpf_set_link_xdp_fd (int ifindex,int fd,__u32 flags) {struct sockaddr_nl sa;
tools/lib/bpf/bpf.h +1 -0
@@ -79,4 +79,5 @@ int bpf_map_get_fd_by_id(__u32 id);int bpf_obj_get_info_by_fd (int prog_fd,void *info,__u32 *info_len);int bpf_prog_query (int target_fd,enum bpf_attach_type type,__u32 query_flags,__u32 *attach_flags,__u32 *prog_ids,__u32 *prog_cnt); +int bpf_raw_tracepoint_open (const char *name,int prog_fd);#endif
Signature · 1 line
2.9.5
PATCH v5 9/10 samples/bpf: raw tracepoint test
In reply to Alexei StarovoitovFrom: Alexei Starovoitov <[email protected]>
add empty raw_tracepoint bpf program to test overhead similar to kprobe and traditional tracepoint tests
--- samples/bpf/Makefile | 1 + samples/bpf/bpf_load.c | 14 ++++++++++++++ samples/bpf/test_overhead_raw_tp_kern.c | 17 +++++++++++++++++ samples/bpf/test_overhead_user.c | 12 ++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 samples/bpf/test_overhead_raw_tp_kern.c
samples/bpf/Makefile +1 -0
@@ -119,6 +119,7 @@ always += offwaketime_kern.o always += spintest_kern.o always += map_perf_test_kern.o always += test_overhead_tp_kern.o +always += test_overhead_raw_tp_kern.o always += test_overhead_kprobe_kern.o always += parse_varlen.o parse_simple.o parse_ldabs.o always += test_cgrp2_tc_kern.o
samples/bpf/bpf_load.c +14 -0
@@ -61,6 +61,7 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)bool is_kprobe =strncmp (event,"kprobe/" ,7 ) ==0 ;bool is_kretprobe =strncmp (event,"kretprobe/" ,10 ) ==0 ;bool is_tracepoint =strncmp (event,"tracepoint/" ,11 ) ==0 ; +bool is_raw_tracepoint =strncmp (event,"raw_tracepoint/" ,15 ) ==0 ;bool is_xdp =strncmp (event,"xdp" ,3 ) ==0 ;bool is_perf_event =strncmp (event,"perf_event" ,10 ) ==0 ;bool is_cgroup_skb =strncmp (event,"cgroup/skb" ,10 ) ==0 ;
@@ -85,6 +86,8 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size) prog_type =BPF_PROG_TYPE_KPROBE ; }else if (is_tracepoint) { prog_type =BPF_PROG_TYPE_TRACEPOINT ; + }else if (is_raw_tracepoint) { + prog_type =BPF_PROG_TYPE_RAW_TRACEPOINT ; }else if (is_xdp) { prog_type =BPF_PROG_TYPE_XDP ; }else if (is_perf_event) {
@@ -131,6 +134,16 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)return populate_prog_array (event, fd); } +if (is_raw_tracepoint) { + efd =bpf_raw_tracepoint_open (event +15 , fd); +if (efd <0 ) { +printf ("tracepoint %s %s\n" , event +15 ,strerror (errno)); +return -1 ; + } + event_fd[prog_cnt -1 ] = efd; +return 0 ; + } +if (is_kprobe || is_kretprobe) {if (is_kprobe) event +=7 ;
@@ -587,6 +600,7 @@ static int do_load_bpf_file(const char *path, fixup_map_cb fixup_map) if (memcmp(shname, "kprobe/", 7) == 0 || memcmp(shname, "kretprobe/", 10) == 0 || memcmp(shname, "tracepoint/", 11) == 0 || + memcmp(shname, "raw_tracepoint/", 15) == 0 || memcmp(shname, "xdp", 3) == 0 || memcmp(shname, "perf_event", 10) == 0 || memcmp(shname, "socket", 6) == 0 ||
samples/bpf/test_overhead_raw_tp_kern.c new file +17 -0
@@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2018 Facebook */ +#include <uapi/linux/bpf.h> +#include "bpf_helpers.h" + +SEC("raw_tracepoint/task_rename") +int prog (struct bpf_raw_tracepoint_args *ctx) +{ +return 0 ; +} + +SEC("raw_tracepoint/urandom_read") +int prog2 (struct bpf_raw_tracepoint_args *ctx) +{ +return 0 ; +} +char _license[] SEC("license") = "GPL";
samples/bpf/test_overhead_user.c +12 -0
@@ -158,5 +158,17 @@ int main(int argc, char **argv)unload_progs (); } +if (test_flags &0xC0 ) { +snprintf (filename,sizeof (filename), +"%s_raw_tp_kern.o" , argv[0 ]); +if (load_bpf_file (filename)) { +printf ("%s" , bpf_log_buf); +return 1 ; + } +printf ("w/RAW_TRACEPOINT\n" ); +run_perf_test (num_cpu, test_flags >>6 ); +unload_progs (); + } +return 0 ; }
Signature · 1 line
2.9.5
PATCH v5 10/10 selftests/bpf: test for bpf_get_stackid() from raw tracepoints
In reply to Alexei StarovoitovFrom: Alexei Starovoitov <[email protected]>
similar to traditional traceopint test add bpf_get_stackid() test from raw tracepoints
and reduce verbosity of existing stackmap test
--- tools/testing/selftests/bpf/test_progs.c | 91 ++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 21 deletions(-)
tools/testing/selftests/bpf/test_progs.c +70 -21
@@ -877,7 +877,7 @@ static void test_stacktrace_map() err =bpf_prog_load (file,BPF_PROG_TYPE_TRACEPOINT , &obj, &prog_fd);if (CHECK (err,"prog_load" ,"err %d errno %d\n" , err, errno)) - goto out; +return ;/* Get the ID for the sched/sched_switch tracepoint */ snprintf(buf, sizeof(buf),
@@ -888,8 +888,7 @@ static void test_stacktrace_map() bytes =read (efd, buf,sizeof (buf));close (efd); -if (CHECK (bytes <=0 || bytes >=sizeof (buf), -"read" ,"bytes %d errno %d\n" , bytes, errno)) +if (bytes <=0 || bytes >=sizeof (buf)) goto close_prog;/* Open the perf event and attach bpf progrram */
@@ -906,29 +905,24 @@ static void test_stacktrace_map() goto close_prog; err =ioctl (pmu_fd,PERF_EVENT_IOC_ENABLE ,0 ); -if (CHECK (err,"perf_event_ioc_enable" ,"err %d errno %d\n" , - err, errno)) - goto close_pmu; +if (err) + goto disable_pmu; err =ioctl (pmu_fd,PERF_EVENT_IOC_SET_BPF , prog_fd); -if (CHECK (err,"perf_event_ioc_set_bpf" ,"err %d errno %d\n" , - err, errno)) +if (err) goto disable_pmu;/* find map fds */ control_map_fd =bpf_find_map (__func__, obj,"control_map" ); -if (CHECK (control_map_fd <0 ,"bpf_find_map control_map" , -"err %d errno %d\n" , err, errno)) +if (control_map_fd <0 ) goto disable_pmu; stackid_hmap_fd =bpf_find_map (__func__, obj,"stackid_hmap" ); -if (CHECK (stackid_hmap_fd <0 ,"bpf_find_map stackid_hmap" , -"err %d errno %d\n" , err, errno)) +if (stackid_hmap_fd <0 ) goto disable_pmu; stackmap_fd =bpf_find_map (__func__, obj,"stackmap" ); -if (CHECK (stackmap_fd <0 ,"bpf_find_map stackmap" ,"err %d errno %d\n" , - err, errno)) +if (stackmap_fd <0 ) goto disable_pmu;/* give some time for bpf program run */
@@ -945,24 +939,78 @@ static void test_stacktrace_map() err =compare_map_keys (stackid_hmap_fd, stackmap_fd);if (CHECK (err,"compare_map_keys stackid_hmap vs. stackmap" ,"err %d errno %d\n" , err, errno)) - goto disable_pmu; + goto disable_pmu_noerr; err =compare_map_keys (stackmap_fd, stackid_hmap_fd);if (CHECK (err,"compare_map_keys stackmap vs. stackid_hmap" ,"err %d errno %d\n" , err, errno)) - ;/* fall through */ + goto disable_pmu_noerr; + goto disable_pmu_noerr; disable_pmu: + error_cnt++; +disable_pmu_noerr:ioctl (pmu_fd,PERF_EVENT_IOC_DISABLE ); - -close_pmu:close (pmu_fd); - close_prog:bpf_object__close (obj); +} -out: -return ; +static void test_stacktrace_map_raw_tp () +{ +int control_map_fd, stackid_hmap_fd, stackmap_fd; +const char *file ="./test_stacktrace_map.o" ; +int efd, err, prog_fd; +__u32 key, val, duration =0 ; +struct bpf_object *obj; + + err =bpf_prog_load (file,BPF_PROG_TYPE_RAW_TRACEPOINT , &obj, &prog_fd); +if (CHECK (err,"prog_load raw tp" ,"err %d errno %d\n" , err, errno)) +return ; + + efd =bpf_raw_tracepoint_open ("sched_switch" , prog_fd); +if (CHECK (efd <0 ,"raw_tp_open" ,"err %d errno %d\n" , efd, errno)) + goto close_prog; + +/* find map fds */ + control_map_fd =bpf_find_map (__func__, obj,"control_map" ); +if (control_map_fd <0 ) + goto close_prog; + + stackid_hmap_fd =bpf_find_map (__func__, obj,"stackid_hmap" ); +if (stackid_hmap_fd <0 ) + goto close_prog; + + stackmap_fd =bpf_find_map (__func__, obj,"stackmap" ); +if (stackmap_fd <0 ) + goto close_prog; + +/* give some time for bpf program run */ +sleep (1 ); + +/* disable stack trace collection */ + key =0 ; + val =1 ; +bpf_map_update_elem (control_map_fd, &key, &val,0 ); + +/* for every element in stackid_hmap, we can find a corresponding one +* in stackmap, and vise versa. +*/ + err =compare_map_keys (stackid_hmap_fd, stackmap_fd); +if (CHECK (err,"compare_map_keys stackid_hmap vs. stackmap" , +"err %d errno %d\n" , err, errno)) + goto close_prog; + + err =compare_map_keys (stackmap_fd, stackid_hmap_fd); +if (CHECK (err,"compare_map_keys stackmap vs. stackid_hmap" , +"err %d errno %d\n" , err, errno)) + goto close_prog; + + goto close_prog_noerr; +close_prog: + error_cnt++; +close_prog_noerr: +bpf_object__close (obj); }static int extract_build_id (char *build_id,size_t size)
@@ -1138,6 +1186,7 @@ int main(void)test_tp_attach_query ();test_stacktrace_map ();test_stacktrace_build_id (); +test_stacktrace_map_raw_tp ();printf ("Summary: %d PASSED, %d FAILED\n" , pass_cnt, error_cnt);return error_cnt ?EXIT_FAILURE :EXIT_SUCCESS ;
Signature · 1 line
2.9.5
Quoted 4 lines · Alexei Starovoitov
From: Alexei Starovoitov <[email protected]>
v4->v5:
- adopted Daniel's fancy REPEAT macro inbpf_trace.cin patch 7
Daniel,
if you don't mind I'd like to land the patch set in this shape and you can follow up with additional macro magic, since I don't understand how the UNPACK part of it works. It sort of looks unnecessary, but if remove it then (,) doesn't get 'unpacked' into single comma.
Yet if __DL_COM is defined as , without ()
then nothing works. My brain is hurting.
Quoted 63 lines · Alexei Starovoitov
From: Alexei Starovoitov <[email protected]>
v4->v5:
- adopted Daniel's fancy REPEAT macro inbpf_trace.cin patch 7
v3->v4:
- adopted Linus'sCAST_TO_U64macro to cast any integer, pointer, or small struct to u64. That nicely reduced the size of patch 1
v2->v3:
- with Linus's suggestion introduced genericCOUNT_ARGSand CONCATENATE macros (or rather moved them from apparmor)
that cleaned up patches 6 and 7
- added patch 4 to refactortrace_iwlwifi_dev_ucode_error()from 17 args to 4 Now any tracepoint with >12 args will have build error
v1->v2:
- simplified api by combingbpf_raw_tp_open(name)+bpf_attach(prog_fd)intobpf_raw_tp_open(name, prog_fd)as suggested by Daniel.
That simplifiesbpf_detachas well which is now simpleclose()of fd.
- fixed memory leak in error path which was spotted by Daniel.
- fixedbpf_get_stackid(),bpf_perf_event_output()called from raw tracepoints
- added more tests
- fixed allyesconfig build caught by buildbotv1:
This patch set is a different way to address the pressing need to accesstask_structpointers in sched tracepoints from bpf programs.The first approach simply added these pointers to sched tracepoints:
https://lkml.org/lkml/2017/12/14/753
which Peter nacked.
Few options were discussed and eventually the discussion converged on doing bpf specifictracepoint_probe_register()probe functions. Details here:
https://lkml.org/lkml/2017/12/20/929Patch 1 is kernel wide cleanup of pass-struct-by-value into pass-struct-by-reference into tracepoints.
Patches 2 and 3 are minor cleanups to address allyesconfig build
Patch 4 refactor
trace_iwlwifi_dev_ucode_errorfrom 17 to 4 argsPatch 5 introduces
COUNT_ARGSmacroPatch 6 minor prep work to expose number of arguments passed into tracepoints.
Patch 7 introduces
BPF_RAW_TRACEPOINTapi.
the auto-cleanup and multiple concurrent users are must have features of tracing api. For bpf raw tracepoints it looks like:
// load bpf prog withBPF_PROG_TYPE_RAW_TRACEPOINTtypeprog_fd=bpf_prog_load(...);// receive
anon_inodefd for givenbpf_raw_tracepoint// and attach bpf program to it
raw_tp_fd=bpf_raw_tracepoint_open("xdp_exception", prog_fd);Ctrl-C of tracing daemon or cmdline tool will automatically detach bpf program, unload it and unregister tracepoint probe. More details in patch 7.
Quoted 8 lines
Patch 8 - trivial support in libbpf
Patches 9, 10 - user space tests
samples/bpf/test_overheadperformance on 1 cpu:tracepoint base kprobe+bpf tracepoint+bpf raw_tracepoint+bpf task_rename 1.1M 769K 947K 1.0M urandom_read 789K 697K 750K 755K
Applied to bpf-next, thanks Alexei!
Steven Rostedt
maintainerQuoted 5 lines · On Mon, 26 Mar 2018 10:28:03 +0200 Daniel Borkmann <[email protected]> wrote:
Quoted 3 lines
tracepoint base kprobe+bpf tracepoint+bpf raw_tracepoint+bpf task_rename 1.1M 769K 947K 1.0M urandom_read 789K 697K 750K 755KApplied to bpf-next, thanks Alexei!
Please wait till you have the proper acks. Some of this affects tracing.
-- Steve
Daniel Borkmann
maintainerQuoted 11 lines · Steven Rostedt
Quoted 5 lines · On Mon, 26 Mar 2018 10:28:03 +0200 Daniel Borkmann <[email protected]> wrote:
Quoted 3 lines
tracepoint base kprobe+bpf tracepoint+bpf raw_tracepoint+bpf task_rename 1.1M 769K 947K 1.0M urandom_read 789K 697K 750K 755KApplied to bpf-next, thanks Alexei!
Please wait till you have the proper acks. Some of this affects tracing.
Ok, I thought time up to v5 was long enough. Anyway, in case there are objections I can still toss out the series from bpf-next tree worst case should e.g. follow-up fixups not be appropriate.
Thanks,
Daniel
Steven Rostedt
maintainerQuoted 8 lines · On Mon, 26 Mar 2018 17:32:02 +0200 Daniel Borkmann <[email protected]> wrote:
Quoted 7 lines · Steven Rostedt
Quoted 4 lines · On Mon, 26 Mar 2018 10:28:03 +0200 Daniel Borkmann <[email protected]> wrote:
Quoted 3 lines
tracepoint base kprobe+bpf tracepoint+bpf raw_tracepoint+bpf task_rename 1.1M 769K 947K 1.0M urandom_read 789K 697K 750K 755K
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
Applied to bpf-next, thanks Alexei!
Please wait till you have the proper acks. Some of this affects tracing.
Ok, I thought time up to v5 was long enough. Anyway, in case there are objections I can still toss out the series from bpf-next tree worst case should e.g. follow-up fixups not be appropriate.
Yeah, I've been traveling a bit which slowed down my review process (trying to catch up). My main concern is with patch 6, as there are external users of those functions. Although, we generally don't cater to out of tree code, we play nice with LTTng, and I don't want to break it.
I also should probably pull in the patches and run them through my tests to make sure they don't have any other side effects.
-- Steve
Quoted 16 lines · Steven Rostedt
Quoted 13 lines · On Mon, 26 Mar 2018 17:32:02 +0200 Daniel Borkmann <[email protected]> wrote:
Quoted 11 lines · Steven Rostedt
Quoted 5 lines · On Mon, 26 Mar 2018 10:28:03 +0200 Daniel Borkmann <[email protected]> wrote:
Quoted 3 lines
tracepoint base kprobe+bpf tracepoint+bpf raw_tracepoint+bpf task_rename 1.1M 769K 947K 1.0M urandom_read 789K 697K 750K 755KApplied to bpf-next, thanks Alexei!
Please wait till you have the proper acks. Some of this affects tracing.
Quoted 6 lines
Quoted 3 lines
Ok, I thought time up to v5 was long enough. Anyway, in case there are objections I can still toss out the series from bpf-next tree worst case should e.g. follow-up fixups not be appropriate.
Yeah, I've been traveling a bit which slowed down my review process (trying to catch up).
v1 of this set was posted Feb 28.
imo one month is not an acceptable delay for maintainer to review the patches. You really need to consider group maintainership as we do with Daniel for bpf tree.
Quoted 4 lines
My main concern is with patch 6, as there are
external users of those functions. Although, we generally don't cater to out of tree code, we play nice with LTTng, and I don't want to break it.
out-of-tree module is out of tree. I'm beyond surprised that you propose to keep for_each_kernel_tracepoint() as-is with zero in-tree users in order to keep lttng working.
Quoted 2 lines
I also should probably pull in the patches and run them through my tests to make sure they don't have any other side effects.
so let me rephrase.
You're saying that a change to a function with zero in-tree users can somehow break your tests?
How is that possible?
Does it mean you also have some out-of-tree modules that will break? and that _is_ the real reason for objection?
Steven Rostedt
maintainerQuoted 18 lines · On Mon, 26 Mar 2018 09:00:33 -0700 Alexei Starovoitov <[email protected]> wrote:
Quoted 17 lines · Steven Rostedt
On Mon, 26 Mar 2018 17:32:02 +0200
Daniel Borkmann <[email protected]>Quoted 13 lines · Steven Rostedt
Quoted 11 lines
Quoted 5 lines · On Mon, 26 Mar 2018 10:28:03 +0200 Daniel Borkmann <[email protected]> wrote:
Quoted 3 lines
tracepoint base kprobe+bpf tracepoint+bpf raw_tracepoint+bpf task_rename 1.1M 769K 947K 1.0M urandom_read 789K 697K 750K 755KApplied to bpf-next, thanks Alexei!
Please wait till you have the proper acks. Some of this affects tracing.
Quoted 8 lines
Quoted 6 lines
Quoted 3 lines
Ok, I thought time up to v5 was long enough. Anyway, in case there are objections I can still toss out the series from bpf-next tree worst case should e.g. follow-up fixups not be appropriate.
Yeah, I've been traveling a bit which slowed down my review process (trying to catch up).
v1 of this set was posted Feb 28.
Yep, Where I traveled to the West coast 2/26 - 3/1 (but due to snow storms, I didn't get home till late 3/2). Then I went back 3/6 and came home 3/8 (again due to another snow storm, it was 3/9). Then I went to ELC from 3/11 to 3/15 (Luckily, the third snow storm hit 3/14, and didn't affect my return trip).
Quoted 3 lines
imo one month is not an acceptable delay for maintainer to review the patches. You really need to consider group maintainership as we do with Daniel for bpf tree.
Perhaps, (which I talked to Masami about, just need to go through logistics). But the tracing code isn't high volume, and the three weeks of traveling for me was a fluke (didn't look at my schedule when I agreed to make that second one).
Quoted 9 lines
Quoted 5 lines
My main concern is with patch 6, as there are
external users of those functions. Although, we generally don't cater to out of tree code, we play nice with LTTng, and I don't want to break it.out-of-tree module is out of tree. I'm beyond surprised that you propose to keep
for_each_kernel_tracepoint()as-is with zero in-tree users in order to keep lttng working.
I'm nice.
Quoted 10 lines
Quoted 3 lines
I also should probably pull in the patches and run them through my tests to make sure they don't have any other side effects.
so let me rephrase.
You're saying that a change to a function with zero in-tree users can somehow break your tests?
How is that possible?
Does it mean you also have some out-of-tree modules that will break? and that _is_ the real reason for objection?
That function isn't what I'm worried about. You changed much more than that.
-- Steve