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.
_______________________________________________
Kernelnewbies mailing list
[email protected]
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies