----- On Apr 7, 2017, at 1:26 PM, rostedt [email protected] wrote:

> On Fri, 7 Apr 2017 17:19:05 +0000 (UTC)
> Mathieu Desnoyers <[email protected]> wrote:
> 
[...]
>> > ---
>> > include/linux/tracepoint.h | 2 ++
>> > 1 file changed, 2 insertions(+)
>> > 
>> > diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
>> > index f72fcfe..8baef96 100644
>> > --- a/include/linux/tracepoint.h
>> > +++ b/include/linux/tracepoint.h
>> > @@ -159,6 +159,8 @@ extern void syscall_unregfunc(void);
>> >                            TP_PROTO(data_proto),                   \
>> >                            TP_ARGS(data_args),                     \
>> >                            TP_CONDITION(cond),                     \
>> > +                          if (WARN_ON_ONCE(rcu_irq_enter_disabled())) \
>> > +                                  return;                         \
>> 
>> I must admit that it's a bit odd to have:
>> 
>> if (WARN_ON_ONCE(rcu_irq_enter_disabled()))
>>        return;
>> rcu_irq_enter_irqson()
> 
> Welcome to MACRO MAGIC!
> 
>> 
>> as one argument to the __DO_TRACE() macro. To me it's a bit unexpected
>> coding-style wise. Am I the only one not comfortable with the proposed
>> syntax ?
> 
> The entire TRACE_EVENT()/__DO_TRACE() is special.
> 
> I thought about add yet another parameter, but as it doesn't change
> much, I figured this was good enough. We could beak it up if you like:
> 
> #define RCU_IRQ_ENTER_CHECK \
>       if (WARN_ON_ONCE(rcu_irq_enter_disabled())      \
>               return;                                 \
>       rcu_irq_enter_irqson();
> 
> [..]
>                       __DO_TRACE(&__tracepoint_##name,                \
>                               TP_PROTO(data_proto),                   \
>                               TP_ARGS(data_args),                     \
>                               TP_CONDITION(cond),                     \
>                               PARAMS(RCU_IRQ_ENTER_CHECK),            \
>                               rcu_irq_exit_irqson());                 \
> 
> 
> Would that make you feel more comfortable?

No, it's almost worse and adds still adds a return that apply within 
__DO_TRACE(),
but which is passed as an argument (code as macro argument), which I find really
unsettling.

I would prefer to add a new argument to __DO_TRACE, which we can call
"checkrcu", e.g.:

#define __DO_TRACE(tp, proto, args, cond, checkrcu, prercu, postrcu)    \
        do {                                                            \
                struct tracepoint_func *it_func_ptr;                    \
                void *it_func;                                          \
                void *__data;                                           \
                                                                        \
                if (!((cond) && (checkrcu)))                            \
                        return;                                         \
                prercu;                                                 \
                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();                        \
                postrcu;                                                \
        } while (0)

And use it like this:

#define __DECLARE_TRACE_RCU(name, proto, args, cond, data_proto, data_args)     
\
        static inline void trace_##name##_rcuidle(proto)                \
        {                                                               \
                if (static_key_false(&__tracepoint_##name.key))         \
                        __DO_TRACE(&__tracepoint_##name,                \
                                TP_PROTO(data_proto),                   \
                                TP_ARGS(data_args),                     \
                                TP_CONDITION(cond),                     \
                                !WARN_ON_ONCE(rcu_irq_enter_disabled()),\
                                rcu_irq_enter_irqson(),                 \
                                rcu_irq_exit_irqson());                 \
        }

This way we only pass evaluated expression (not code with "return" that
changes the flow) as arguments to __DO_TRACE, which makes it behave more
like a "sub-function", which is what we usually expect.

Thanks,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com

Reply via email to