* question about macro __DO_TRACE
@ 2011-02-26 2:40 zhao bao
2011-02-26 4:37 ` Frederic Weisbecker
0 siblings, 1 reply; 3+ messages in thread
From: zhao bao @ 2011-02-26 2:40 UTC (permalink / raw)
To: kernelnewbies
Hello,everybody. When I read tracepoint code, I find variable __data
never used. Am I missing something?
#define __DO_TRACE(tp, proto, args, cond) \
do { \
struct tracepoint_func *it_func_ptr; \
void *it_func; \
void *__data; \
\
if (!(cond)) \
return; \
rcu_read_lock_sched_notrace(); \
it_func_ptr = rcu_dereference_sched((tp)->funcs); \
if (it_func_ptr) { \
do { \
it_func = (it_func_ptr)->func; \
__data = (it_func_ptr)->data; \
((void(*)(proto))(it_func))(args); \
} while ((++it_func_ptr)->func); \
} \
rcu_read_unlock_sched_notrace(); \
} while (0)
^ permalink raw reply [flat|nested] 3+ messages in thread* question about macro __DO_TRACE 2011-02-26 2:40 question about macro __DO_TRACE zhao bao @ 2011-02-26 4:37 ` Frederic Weisbecker 2011-02-26 4:54 ` Mulyadi Santosa 0 siblings, 1 reply; 3+ messages in thread From: Frederic Weisbecker @ 2011-02-26 4:37 UTC (permalink / raw) To: kernelnewbies On Sat, Feb 26, 2011 at 10:40:32AM +0800, zhao bao wrote: > Hello,everybody. When I read tracepoint code, I find variable __data > never used. Am I missing something? > > #define __DO_TRACE(tp, proto, args, cond) \ > do { \ > struct tracepoint_func *it_func_ptr; \ > void *it_func; \ > void *__data; \ > \ > if (!(cond)) \ > return; \ > rcu_read_lock_sched_notrace(); \ > it_func_ptr = rcu_dereference_sched((tp)->funcs); \ > if (it_func_ptr) { \ > do { \ > it_func = (it_func_ptr)->func; \ > __data = (it_func_ptr)->data; \ > ((void(*)(proto))(it_func))(args); \ > } while ((++it_func_ptr)->func); \ > } \ > rcu_read_unlock_sched_notrace(); \ > } while (0) Yeah that's a quite tricky part. So what we want with tracepoints is to have them passing something specific as a first parameter. Always the same thing for a given func. So you register a probe with tracepoint_probe_register() and the third argument of this func, data, is the first parameter that will always been passed to your probe function. This is that "__data". We declare a tracepoint with DECLARE_TRACE(): DECLARE_TRACE(my_trace, int myarg, myarg). The CPP engine will translate that too: __DECLARE_TRACE(mytrace, (int myarg), (myarg), 1 (void *__data, int myarg), (__data, myarg)) ^^ Look, that where is the trick. DECLARE_TRACE is cheating by adding this __data argument. Further, __DO_TRACE will be called with these arguments: __DO_TRACE(&__tracepoint_mytrace, (void *__data, int myarg), (__data, myarg), (cond)) And then it makes the trick inside __DO_TRACE(), we end up having: void *__data; __data = (it_func_ptr)->data; ((void(*)(proto))(it_func))(__data, myarg); See? That's a kind of ghost argument we inject in our CPP macros and in the end we cheat in order to pass that constant tracepoint data as a first argument of the probe. In practice we use that to pass the ftrace event (struct ftrace_event_call *) structure as a first argument of the probe. It's a shame we needed to get something so unreadable and quick to generate headaches but IIRC we didn't have the choice in order to pass that specific data argument. ^ permalink raw reply [flat|nested] 3+ messages in thread
* question about macro __DO_TRACE 2011-02-26 4:37 ` Frederic Weisbecker @ 2011-02-26 4:54 ` Mulyadi Santosa 0 siblings, 0 replies; 3+ messages in thread From: Mulyadi Santosa @ 2011-02-26 4:54 UTC (permalink / raw) To: kernelnewbies On Sat, Feb 26, 2011 at 11:37, Frederic Weisbecker <fweisbec@gmail.com> wrote: > And then it makes the trick inside __DO_TRACE(), we end up having: > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?void *__data; > > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?__data = (it_func_ptr)->data; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?((void(*)(proto))(it_func))(__data, myarg); > > See? That's a kind of ghost argument we inject in our CPP macros > and in the end we cheat in order to pass that constant tracepoint data > as a first argument of the probe. Great tricks! well, sometimes we can't avoid doing such slick trick, but all in all it's there. Perhaps what we all need here is better and better code documentation. Or at the very least, self documenting code PS: Is that a specific gcc trick? -- regards, Mulyadi Santosa Freelance Linux trainer and consultant blog: the-hydra.blogspot.com training: mulyaditraining.blogspot.com ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-02-26 4:54 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-02-26 2:40 question about macro __DO_TRACE zhao bao 2011-02-26 4:37 ` Frederic Weisbecker 2011-02-26 4:54 ` Mulyadi Santosa
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).