Re: question about macro __DO_TRACE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux