* [PATCH 0/3] tracing: introduce TRACE_EVENT_NONE and use it
@ 2019-03-26 1:40 Yafang Shao
2019-03-26 1:40 ` [PATCH 1/3] tracing: introduce TRACE_EVENT_NONE() Yafang Shao
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Yafang Shao @ 2019-03-26 1:40 UTC (permalink / raw)
To: rostedt, mingo, peterz, paulmck, josh, mathieu.desnoyers,
jiangshanlai, joel
Cc: shaoyafang, linux-kernel, Yafang Shao
In this patchset, I introduce a new macro TRACE_EVENT_NONE(), which will
define a tracepoint as a do-nothing inline function.
#define TRACE_EVENT_NONE(name, proto) \
static inline void trace_##name(proto) \
{ } \
static inline bool trace_##name##_enabled(void) \
{ \
return false; \
}
Let's take some example for why this macro is needed.
- sched
The tracepoints trace_sched_stat_{iowait, blocked, wait, sleep} should
be not exposed to user if CONFIG_SCHEDSTATS is not set.
We can place #ifdef in the kernel/sched/fair.c to fix it, but we don't want
to sprinkle #ifdef.
So with TRACE_EVENT_NONE(), we can fix it in include/trace/events/sched.h.
- rcu
When CONFIG_RCU_TRACE is not set, some rcu tracepoints are define as
do-nothing macro without validating arguments, that is not proper.
We should validate the arguments.
Yafang Shao (3):
tracing: introduce TRACE_EVENT_NONE()
sched/fair: do not expose some tracepoints to user if
CONFIG_SCHEDSTATS is not set
rcu: validate arguments for rcu tracepoints
include/linux/tracepoint.h | 8 +++++
include/trace/define_trace.h | 4 +++
include/trace/events/rcu.h | 84 ++++++++++++++++++++++++++++----------------
include/trace/events/sched.h | 14 ++++++++
kernel/rcu/rcu.h | 9 ++---
kernel/rcu/tree.c | 8 ++---
6 files changed, 86 insertions(+), 41 deletions(-)
--
1.8.3.1
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 1/3] tracing: introduce TRACE_EVENT_NONE() 2019-03-26 1:40 [PATCH 0/3] tracing: introduce TRACE_EVENT_NONE and use it Yafang Shao @ 2019-03-26 1:40 ` Yafang Shao 2019-03-26 1:40 ` [PATCH 2/3] sched/fair: do not expose some tracepoints to user if CONFIG_SCHEDSTATS is not set Yafang Shao ` (2 subsequent siblings) 3 siblings, 0 replies; 9+ messages in thread From: Yafang Shao @ 2019-03-26 1:40 UTC (permalink / raw) To: rostedt, mingo, peterz, paulmck, josh, mathieu.desnoyers, jiangshanlai, joel Cc: shaoyafang, linux-kernel, Yafang Shao Sometimes we want define a tracepoint as a do-nothing function. So I introduce this TRACE_EVENT_NONE() for this kind of usage. Signed-off-by: Yafang Shao <laoar.shao@gmail.com> --- include/linux/tracepoint.h | 8 ++++++++ include/trace/define_trace.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 9c31865..d00c5e6 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -548,4 +548,12 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) #define TRACE_EVENT_PERF_PERM(event, expr...) +#define TRACE_EVENT_NONE(name, proto) \ + static inline void trace_##name(proto) \ + { } \ + static inline bool trace_##name##_enabled(void) \ + { \ + return false; \ + } + #endif /* ifdef TRACE_EVENT (see note above) */ diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h index cb30c55..a833b6f 100644 --- a/include/trace/define_trace.h +++ b/include/trace/define_trace.h @@ -46,6 +46,9 @@ assign, print, reg, unreg) \ DEFINE_TRACE_FN(name, reg, unreg) +#undef TRACE_EVENT_NONE +#define TRACE_EVENT_NONE(name, proto) + #undef DEFINE_EVENT #define DEFINE_EVENT(template, name, proto, args) \ DEFINE_TRACE(name) @@ -102,6 +105,7 @@ #undef TRACE_EVENT_FN #undef TRACE_EVENT_FN_COND #undef TRACE_EVENT_CONDITION +#undef TRACE_EVENT_NONE #undef DECLARE_EVENT_CLASS #undef DEFINE_EVENT #undef DEFINE_EVENT_FN -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/3] sched/fair: do not expose some tracepoints to user if CONFIG_SCHEDSTATS is not set 2019-03-26 1:40 [PATCH 0/3] tracing: introduce TRACE_EVENT_NONE and use it Yafang Shao 2019-03-26 1:40 ` [PATCH 1/3] tracing: introduce TRACE_EVENT_NONE() Yafang Shao @ 2019-03-26 1:40 ` Yafang Shao 2019-03-26 2:21 ` Steven Rostedt 2019-03-26 1:40 ` [PATCH 3/3] rcu: validate arguments for rcu tracepoints Yafang Shao 2019-03-26 2:17 ` [PATCH 0/3] tracing: introduce TRACE_EVENT_NONE and use it Steven Rostedt 3 siblings, 1 reply; 9+ messages in thread From: Yafang Shao @ 2019-03-26 1:40 UTC (permalink / raw) To: rostedt, mingo, peterz, paulmck, josh, mathieu.desnoyers, jiangshanlai, joel Cc: shaoyafang, linux-kernel, Yafang Shao The tracepoints trace_sched_stat_{iowait, blocked, wait, sleep} should be not exposed to user if CONFIG_SCHEDSTATS is not set. Signed-off-by: Yafang Shao <laoar.shao@gmail.com> --- include/trace/events/sched.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h index 9a4bdfa..4686c7f 100644 --- a/include/trace/events/sched.h +++ b/include/trace/events/sched.h @@ -336,6 +336,7 @@ static inline long __trace_sched_switch_state(bool preempt, struct task_struct * __entry->pid, __entry->old_pid) ); +#ifdef CONFIG_SCHEDSTATS /* * XXX the below sched_stat tracepoints only apply to SCHED_OTHER/BATCH/IDLE * adding sched_stat support to SCHED_FIFO/RR would be welcome. @@ -395,6 +396,19 @@ static inline long __trace_sched_switch_state(bool preempt, struct task_struct * TP_PROTO(struct task_struct *tsk, u64 delay), TP_ARGS(tsk, delay)); +#else /* CONFIG_SCHEDSTATS */ + +TRACE_EVENT_NONE(sched_stat_wait, + TP_PROTO(struct task_struct *tsk, u64 delay)); +TRACE_EVENT_NONE(sched_stat_sleep, + TP_PROTO(struct task_struct *tsk, u64 delay)); +TRACE_EVENT_NONE(sched_stat_iowait, + TP_PROTO(struct task_struct *tsk, u64 delay)); +TRACE_EVENT_NONE(sched_stat_blocked, + TP_PROTO(struct task_struct *tsk, u64 delay)); + +#endif /* CONFIG_SCHEDSTATS */ + /* * Tracepoint for accounting runtime (time the task is executing * on a CPU). -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/3] sched/fair: do not expose some tracepoints to user if CONFIG_SCHEDSTATS is not set 2019-03-26 1:40 ` [PATCH 2/3] sched/fair: do not expose some tracepoints to user if CONFIG_SCHEDSTATS is not set Yafang Shao @ 2019-03-26 2:21 ` Steven Rostedt 2019-03-26 2:23 ` Yafang Shao 0 siblings, 1 reply; 9+ messages in thread From: Steven Rostedt @ 2019-03-26 2:21 UTC (permalink / raw) To: Yafang Shao Cc: mingo, peterz, paulmck, josh, mathieu.desnoyers, jiangshanlai, joel, shaoyafang, linux-kernel On Tue, 26 Mar 2019 09:40:06 +0800 Yafang Shao <laoar.shao@gmail.com> wrote: > The tracepoints trace_sched_stat_{iowait, blocked, wait, sleep} should > be not exposed to user if CONFIG_SCHEDSTATS is not set. > > Signed-off-by: Yafang Shao <laoar.shao@gmail.com> > --- > include/trace/events/sched.h | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > > diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h > index 9a4bdfa..4686c7f 100644 > --- a/include/trace/events/sched.h > +++ b/include/trace/events/sched.h > @@ -336,6 +336,7 @@ static inline long __trace_sched_switch_state(bool preempt, struct task_struct * > __entry->pid, __entry->old_pid) > ); > > +#ifdef CONFIG_SCHEDSTATS Instead of doing this #ifdef here, perhaps we should have at the top of the file: #ifdef CONFIG_SCHEDSTATS # define TRACE_EVENT_SCHEDSTAT TRACE_EVENT #else # define TRACE_EVENT_SCHEDSTAT TRACE_EVENT_NOP #endif And then switch the sched stat tracepoints from TRACE_EVENT to use TRACE_EVENT_SCHEDSTAT. And if my magic macro hat is working while sitting on the shelf (don't have time to put it on), then the TRACE_EVENT_SCHEDSTAT will work like a TRACE_EVENT when enabled, and a TRACE_EVENT_NOP when not. Can you give that a try? If this works, you don't need to duplicate all the parameters again. -- Steve > /* > * XXX the below sched_stat tracepoints only apply to > SCHED_OTHER/BATCH/IDLE > * adding sched_stat support to SCHED_FIFO/RR would be welcome. > @@ -395,6 +396,19 @@ static inline long > __trace_sched_switch_state(bool preempt, struct task_struct * > TP_PROTO(struct task_struct *tsk, u64 delay), TP_ARGS(tsk, delay)); > > +#else /* CONFIG_SCHEDSTATS */ > + > +TRACE_EVENT_NONE(sched_stat_wait, > + TP_PROTO(struct task_struct *tsk, u64 delay)); > +TRACE_EVENT_NONE(sched_stat_sleep, > + TP_PROTO(struct task_struct *tsk, u64 delay)); > +TRACE_EVENT_NONE(sched_stat_iowait, > + TP_PROTO(struct task_struct *tsk, u64 delay)); > +TRACE_EVENT_NONE(sched_stat_blocked, > + TP_PROTO(struct task_struct *tsk, u64 delay)); > + > +#endif /* CONFIG_SCHEDSTATS */ > + > /* > * Tracepoint for accounting runtime (time the task is executing > * on a CPU). ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/3] sched/fair: do not expose some tracepoints to user if CONFIG_SCHEDSTATS is not set 2019-03-26 2:21 ` Steven Rostedt @ 2019-03-26 2:23 ` Yafang Shao 0 siblings, 0 replies; 9+ messages in thread From: Yafang Shao @ 2019-03-26 2:23 UTC (permalink / raw) To: Steven Rostedt Cc: mingo, Peter Zijlstra, Paul McKenney, josh, Mathieu Desnoyers, jiangshanlai, joel, shaoyafang, LKML On Tue, Mar 26, 2019 at 10:21 AM Steven Rostedt <rostedt@goodmis.org> wrote: > > On Tue, 26 Mar 2019 09:40:06 +0800 > Yafang Shao <laoar.shao@gmail.com> wrote: > > > The tracepoints trace_sched_stat_{iowait, blocked, wait, sleep} should > > be not exposed to user if CONFIG_SCHEDSTATS is not set. > > > > Signed-off-by: Yafang Shao <laoar.shao@gmail.com> > > --- > > include/trace/events/sched.h | 14 ++++++++++++++ > > 1 file changed, 14 insertions(+) > > > > diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h > > index 9a4bdfa..4686c7f 100644 > > --- a/include/trace/events/sched.h > > +++ b/include/trace/events/sched.h > > @@ -336,6 +336,7 @@ static inline long __trace_sched_switch_state(bool preempt, struct task_struct * > > __entry->pid, __entry->old_pid) > > ); > > > > +#ifdef CONFIG_SCHEDSTATS > > Instead of doing this #ifdef here, perhaps we should have at the top of the file: > > #ifdef CONFIG_SCHEDSTATS > # define TRACE_EVENT_SCHEDSTAT TRACE_EVENT > #else > # define TRACE_EVENT_SCHEDSTAT TRACE_EVENT_NOP > #endif > > And then switch the sched stat tracepoints from TRACE_EVENT to > use TRACE_EVENT_SCHEDSTAT. > > And if my magic macro hat is working while sitting on the shelf (don't > have time to put it on), then the TRACE_EVENT_SCHEDSTAT will work like > a TRACE_EVENT when enabled, and a TRACE_EVENT_NOP when not. > > Can you give that a try? > > If this works, you don't need to duplicate all the parameters again. > You proposal seems like a better solution. I will have a try. Thanks for your suggestion. -Yafang > > > /* > > * XXX the below sched_stat tracepoints only apply to > > SCHED_OTHER/BATCH/IDLE > > * adding sched_stat support to SCHED_FIFO/RR would be welcome. > > @@ -395,6 +396,19 @@ static inline long > > __trace_sched_switch_state(bool preempt, struct task_struct * > > TP_PROTO(struct task_struct *tsk, u64 delay), TP_ARGS(tsk, delay)); > > > > +#else /* CONFIG_SCHEDSTATS */ > > + > > +TRACE_EVENT_NONE(sched_stat_wait, > > + TP_PROTO(struct task_struct *tsk, u64 delay)); > > +TRACE_EVENT_NONE(sched_stat_sleep, > > + TP_PROTO(struct task_struct *tsk, u64 delay)); > > +TRACE_EVENT_NONE(sched_stat_iowait, > > + TP_PROTO(struct task_struct *tsk, u64 delay)); > > +TRACE_EVENT_NONE(sched_stat_blocked, > > + TP_PROTO(struct task_struct *tsk, u64 delay)); > > + > > +#endif /* CONFIG_SCHEDSTATS */ > > + > > /* > > * Tracepoint for accounting runtime (time the task is executing > > * on a CPU). > ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/3] rcu: validate arguments for rcu tracepoints 2019-03-26 1:40 [PATCH 0/3] tracing: introduce TRACE_EVENT_NONE and use it Yafang Shao 2019-03-26 1:40 ` [PATCH 1/3] tracing: introduce TRACE_EVENT_NONE() Yafang Shao 2019-03-26 1:40 ` [PATCH 2/3] sched/fair: do not expose some tracepoints to user if CONFIG_SCHEDSTATS is not set Yafang Shao @ 2019-03-26 1:40 ` Yafang Shao 2019-03-26 14:32 ` Paul E. McKenney 2019-03-26 2:17 ` [PATCH 0/3] tracing: introduce TRACE_EVENT_NONE and use it Steven Rostedt 3 siblings, 1 reply; 9+ messages in thread From: Yafang Shao @ 2019-03-26 1:40 UTC (permalink / raw) To: rostedt, mingo, peterz, paulmck, josh, mathieu.desnoyers, jiangshanlai, joel Cc: shaoyafang, linux-kernel, Yafang Shao When CONFIG_RCU_TRACE is not set, all these tracepoints are define as do-nothing macro. We'd better make those inline functions that take proper arguments. As RCU_TRACE() is defined as do-nothing marco as well when CONFIG_RCU_TRACE is not set, so we can clean it up. Signed-off-by: Yafang Shao <laoar.shao@gmail.com> --- include/trace/events/rcu.h | 84 +++++++++++++++++++++++++++++----------------- kernel/rcu/rcu.h | 9 ++--- kernel/rcu/tree.c | 8 ++--- 3 files changed, 60 insertions(+), 41 deletions(-) diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h index f0c4d10..357e1b6 100644 --- a/include/trace/events/rcu.h +++ b/include/trace/events/rcu.h @@ -750,36 +750,60 @@ #else /* #ifdef CONFIG_RCU_TRACE */ -#define trace_rcu_grace_period(rcuname, gp_seq, gpevent) do { } while (0) -#define trace_rcu_future_grace_period(rcuname, gp_seq, gp_seq_req, \ - level, grplo, grphi, event) \ - do { } while (0) -#define trace_rcu_grace_period_init(rcuname, gp_seq, level, grplo, grphi, \ - qsmask) do { } while (0) -#define trace_rcu_exp_grace_period(rcuname, gqseq, gpevent) \ - do { } while (0) -#define trace_rcu_exp_funnel_lock(rcuname, level, grplo, grphi, gpevent) \ - do { } while (0) -#define trace_rcu_nocb_wake(rcuname, cpu, reason) do { } while (0) -#define trace_rcu_preempt_task(rcuname, pid, gp_seq) do { } while (0) -#define trace_rcu_unlock_preempted_task(rcuname, gp_seq, pid) do { } while (0) -#define trace_rcu_quiescent_state_report(rcuname, gp_seq, mask, qsmask, level, \ - grplo, grphi, gp_tasks) do { } \ - while (0) -#define trace_rcu_fqs(rcuname, gp_seq, cpu, qsevent) do { } while (0) -#define trace_rcu_dyntick(polarity, oldnesting, newnesting, dyntick) do { } while (0) -#define trace_rcu_callback(rcuname, rhp, qlen_lazy, qlen) do { } while (0) -#define trace_rcu_kfree_callback(rcuname, rhp, offset, qlen_lazy, qlen) \ - do { } while (0) -#define trace_rcu_batch_start(rcuname, qlen_lazy, qlen, blimit) \ - do { } while (0) -#define trace_rcu_invoke_callback(rcuname, rhp) do { } while (0) -#define trace_rcu_invoke_kfree_callback(rcuname, rhp, offset) do { } while (0) -#define trace_rcu_batch_end(rcuname, callbacks_invoked, cb, nr, iit, risk) \ - do { } while (0) -#define trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c) \ - do { } while (0) -#define trace_rcu_barrier(name, s, cpu, cnt, done) do { } while (0) +TRACE_EVENT_NONE(rcu_grace_period, + TP_PROTO(const char *rcuname, unsigned long gp_seq, + const char *gpevent)); +TRACE_EVENT_NONE(rcu_future_grace_period, + TP_PROTO(const char *rcuname, unsigned long gp_seq, + unsigned long gp_seq_req, u8 level, int grplo, + int grphi, const char *gpevent)); +TRACE_EVENT_NONE(rcu_grace_period_init, + TP_PROTO(const char *rcuname, unsigned long gp_seq, u8 level, + int grplo, int grphi, unsigned long qsmask)); +TRACE_EVENT_NONE(rcu_exp_grace_period, + TP_PROTO(const char *rcuname, unsigned long gpseq, + const char *gpevent)); +TRACE_EVENT_NONE(rcu_exp_funnel_lock, + TP_PROTO(const char *rcuname, u8 level, int grplo, int grphi, + const char *gpevent)); +TRACE_EVENT_NONE(rcu_nocb_wake, + TP_PROTO(const char *rcuname, int cpu, const char *reason)); +TRACE_EVENT_NONE(rcu_preempt_task, + TP_PROTO(const char *rcuname, int pid, unsigned long gp_seq)); +TRACE_EVENT_NONE(rcu_unlock_preempted_task, + TP_PROTO(const char *rcuname, unsigned long gp_seq, int pid)); +TRACE_EVENT_NONE(rcu_quiescent_state_report, + TP_PROTO(const char *rcuname, unsigned long gp_seq, + unsigned long mask, unsigned long qsmask, + u8 level, int grplo, int grphi, int gp_tasks)); +TRACE_EVENT_NONE(rcu_fqs, + TP_PROTO(const char *rcuname, unsigned long gp_seq, int cpu, + const char *qsevent)); +TRACE_EVENT_NONE(rcu_dyntick, + TP_PROTO(const char *polarity, long oldnesting, long newnesting, + atomic_t dynticks)); +TRACE_EVENT_NONE(rcu_callback, + TP_PROTO(const char *rcuname, struct rcu_head *rhp, long qlen_lazy, + long qlen)); +TRACE_EVENT_NONE(rcu_kfree_callback, + TP_PROTO(const char *rcuname, struct rcu_head *rhp, + unsigned long offset, long qlen_lazy, long qlen)); +TRACE_EVENT_NONE(rcu_batch_start, + TP_PROTO(const char *rcuname, long qlen_lazy, long qlen, long blimit)); +TRACE_EVENT_NONE(rcu_invoke_callback, + TP_PROTO(const char *rcuname, struct rcu_head *rhp)); +TRACE_EVENT_NONE(rcu_invoke_kfree_callback, + TP_PROTO(const char *rcuname, struct rcu_head *rhp, + unsigned long offset)); +TRACE_EVENT_NONE(rcu_batch_end, + TP_PROTO(const char *rcuname, int callbacks_invoked, + char cb, char nr, char iit, char risk)); +TRACE_EVENT_NONE(rcu_torture_read, + TP_PROTO(const char *rcutorturename, struct rcu_head *rhp, + unsigned long secs, unsigned long c_old, unsigned long c)); +TRACE_EVENT_NONE(rcu_barrier, + TP_PROTO(const char *rcuname, const char *s, int cpu, int cnt, + unsigned long done)); #endif /* #else #ifdef CONFIG_RCU_TRACE */ diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h index a393e24..2778e44 100644 --- a/kernel/rcu/rcu.h +++ b/kernel/rcu/rcu.h @@ -24,11 +24,6 @@ #define __LINUX_RCU_H #include <trace/events/rcu.h> -#ifdef CONFIG_RCU_TRACE -#define RCU_TRACE(stmt) stmt -#else /* #ifdef CONFIG_RCU_TRACE */ -#define RCU_TRACE(stmt) -#endif /* #else #ifdef CONFIG_RCU_TRACE */ /* Offset to allow for unmatched rcu_irq_{enter,exit}(). */ #define DYNTICK_IRQ_NONIDLE ((LONG_MAX / 2) + 1) @@ -229,12 +224,12 @@ static inline bool __rcu_reclaim(const char *rn, struct rcu_head *head) rcu_lock_acquire(&rcu_callback_map); if (__is_kfree_rcu_offset(offset)) { - RCU_TRACE(trace_rcu_invoke_kfree_callback(rn, head, offset);) + trace_rcu_invoke_kfree_callback(rn, head, offset); kfree((void *)head - offset); rcu_lock_release(&rcu_callback_map); return true; } else { - RCU_TRACE(trace_rcu_invoke_callback(rn, head);) + trace_rcu_invoke_callback(rn, head); f = head->func; WRITE_ONCE(head->func, (rcu_callback_t)0L); f(head); diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 9180158..d2ad39f 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -2329,14 +2329,14 @@ static void rcu_report_qs_rnp(unsigned long mask, struct rcu_node *rnp, */ int rcutree_dying_cpu(unsigned int cpu) { - RCU_TRACE(bool blkd;) - RCU_TRACE(struct rcu_data *rdp = this_cpu_ptr(&rcu_data);) - RCU_TRACE(struct rcu_node *rnp = rdp->mynode;) + bool blkd; + struct rcu_data *rdp = this_cpu_ptr(&rcu_data); + struct rcu_node *rnp = rdp->mynode; if (!IS_ENABLED(CONFIG_HOTPLUG_CPU)) return 0; - RCU_TRACE(blkd = !!(rnp->qsmask & rdp->grpmask);) + blkd = !!(rnp->qsmask & rdp->grpmask); trace_rcu_grace_period(rcu_state.name, rnp->gp_seq, blkd ? TPS("cpuofl") : TPS("cpuofl-bgp")); return 0; -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] rcu: validate arguments for rcu tracepoints 2019-03-26 1:40 ` [PATCH 3/3] rcu: validate arguments for rcu tracepoints Yafang Shao @ 2019-03-26 14:32 ` Paul E. McKenney 0 siblings, 0 replies; 9+ messages in thread From: Paul E. McKenney @ 2019-03-26 14:32 UTC (permalink / raw) To: Yafang Shao Cc: rostedt, mingo, peterz, josh, mathieu.desnoyers, jiangshanlai, joel, shaoyafang, linux-kernel On Tue, Mar 26, 2019 at 09:40:07AM +0800, Yafang Shao wrote: > When CONFIG_RCU_TRACE is not set, all these tracepoints are define as > do-nothing macro. > We'd better make those inline functions that take proper arguments. > > As RCU_TRACE() is defined as do-nothing marco as well when > CONFIG_RCU_TRACE is not set, so we can clean it up. > > Signed-off-by: Yafang Shao <laoar.shao@gmail.com> With the naming changes suggested by Steven: Acked-by: Paul E. McKenney <paulmck@linux.ibm.com> This area of the code should be relatively free from conflicts, so please feel free to take it with the tracing updates. > --- > include/trace/events/rcu.h | 84 +++++++++++++++++++++++++++++----------------- > kernel/rcu/rcu.h | 9 ++--- > kernel/rcu/tree.c | 8 ++--- > 3 files changed, 60 insertions(+), 41 deletions(-) > > diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h > index f0c4d10..357e1b6 100644 > --- a/include/trace/events/rcu.h > +++ b/include/trace/events/rcu.h > @@ -750,36 +750,60 @@ > > #else /* #ifdef CONFIG_RCU_TRACE */ > > -#define trace_rcu_grace_period(rcuname, gp_seq, gpevent) do { } while (0) > -#define trace_rcu_future_grace_period(rcuname, gp_seq, gp_seq_req, \ > - level, grplo, grphi, event) \ > - do { } while (0) > -#define trace_rcu_grace_period_init(rcuname, gp_seq, level, grplo, grphi, \ > - qsmask) do { } while (0) > -#define trace_rcu_exp_grace_period(rcuname, gqseq, gpevent) \ > - do { } while (0) > -#define trace_rcu_exp_funnel_lock(rcuname, level, grplo, grphi, gpevent) \ > - do { } while (0) > -#define trace_rcu_nocb_wake(rcuname, cpu, reason) do { } while (0) > -#define trace_rcu_preempt_task(rcuname, pid, gp_seq) do { } while (0) > -#define trace_rcu_unlock_preempted_task(rcuname, gp_seq, pid) do { } while (0) > -#define trace_rcu_quiescent_state_report(rcuname, gp_seq, mask, qsmask, level, \ > - grplo, grphi, gp_tasks) do { } \ > - while (0) > -#define trace_rcu_fqs(rcuname, gp_seq, cpu, qsevent) do { } while (0) > -#define trace_rcu_dyntick(polarity, oldnesting, newnesting, dyntick) do { } while (0) > -#define trace_rcu_callback(rcuname, rhp, qlen_lazy, qlen) do { } while (0) > -#define trace_rcu_kfree_callback(rcuname, rhp, offset, qlen_lazy, qlen) \ > - do { } while (0) > -#define trace_rcu_batch_start(rcuname, qlen_lazy, qlen, blimit) \ > - do { } while (0) > -#define trace_rcu_invoke_callback(rcuname, rhp) do { } while (0) > -#define trace_rcu_invoke_kfree_callback(rcuname, rhp, offset) do { } while (0) > -#define trace_rcu_batch_end(rcuname, callbacks_invoked, cb, nr, iit, risk) \ > - do { } while (0) > -#define trace_rcu_torture_read(rcutorturename, rhp, secs, c_old, c) \ > - do { } while (0) > -#define trace_rcu_barrier(name, s, cpu, cnt, done) do { } while (0) > +TRACE_EVENT_NONE(rcu_grace_period, > + TP_PROTO(const char *rcuname, unsigned long gp_seq, > + const char *gpevent)); > +TRACE_EVENT_NONE(rcu_future_grace_period, > + TP_PROTO(const char *rcuname, unsigned long gp_seq, > + unsigned long gp_seq_req, u8 level, int grplo, > + int grphi, const char *gpevent)); > +TRACE_EVENT_NONE(rcu_grace_period_init, > + TP_PROTO(const char *rcuname, unsigned long gp_seq, u8 level, > + int grplo, int grphi, unsigned long qsmask)); > +TRACE_EVENT_NONE(rcu_exp_grace_period, > + TP_PROTO(const char *rcuname, unsigned long gpseq, > + const char *gpevent)); > +TRACE_EVENT_NONE(rcu_exp_funnel_lock, > + TP_PROTO(const char *rcuname, u8 level, int grplo, int grphi, > + const char *gpevent)); > +TRACE_EVENT_NONE(rcu_nocb_wake, > + TP_PROTO(const char *rcuname, int cpu, const char *reason)); > +TRACE_EVENT_NONE(rcu_preempt_task, > + TP_PROTO(const char *rcuname, int pid, unsigned long gp_seq)); > +TRACE_EVENT_NONE(rcu_unlock_preempted_task, > + TP_PROTO(const char *rcuname, unsigned long gp_seq, int pid)); > +TRACE_EVENT_NONE(rcu_quiescent_state_report, > + TP_PROTO(const char *rcuname, unsigned long gp_seq, > + unsigned long mask, unsigned long qsmask, > + u8 level, int grplo, int grphi, int gp_tasks)); > +TRACE_EVENT_NONE(rcu_fqs, > + TP_PROTO(const char *rcuname, unsigned long gp_seq, int cpu, > + const char *qsevent)); > +TRACE_EVENT_NONE(rcu_dyntick, > + TP_PROTO(const char *polarity, long oldnesting, long newnesting, > + atomic_t dynticks)); > +TRACE_EVENT_NONE(rcu_callback, > + TP_PROTO(const char *rcuname, struct rcu_head *rhp, long qlen_lazy, > + long qlen)); > +TRACE_EVENT_NONE(rcu_kfree_callback, > + TP_PROTO(const char *rcuname, struct rcu_head *rhp, > + unsigned long offset, long qlen_lazy, long qlen)); > +TRACE_EVENT_NONE(rcu_batch_start, > + TP_PROTO(const char *rcuname, long qlen_lazy, long qlen, long blimit)); > +TRACE_EVENT_NONE(rcu_invoke_callback, > + TP_PROTO(const char *rcuname, struct rcu_head *rhp)); > +TRACE_EVENT_NONE(rcu_invoke_kfree_callback, > + TP_PROTO(const char *rcuname, struct rcu_head *rhp, > + unsigned long offset)); > +TRACE_EVENT_NONE(rcu_batch_end, > + TP_PROTO(const char *rcuname, int callbacks_invoked, > + char cb, char nr, char iit, char risk)); > +TRACE_EVENT_NONE(rcu_torture_read, > + TP_PROTO(const char *rcutorturename, struct rcu_head *rhp, > + unsigned long secs, unsigned long c_old, unsigned long c)); > +TRACE_EVENT_NONE(rcu_barrier, > + TP_PROTO(const char *rcuname, const char *s, int cpu, int cnt, > + unsigned long done)); > > #endif /* #else #ifdef CONFIG_RCU_TRACE */ > > diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h > index a393e24..2778e44 100644 > --- a/kernel/rcu/rcu.h > +++ b/kernel/rcu/rcu.h > @@ -24,11 +24,6 @@ > #define __LINUX_RCU_H > > #include <trace/events/rcu.h> > -#ifdef CONFIG_RCU_TRACE > -#define RCU_TRACE(stmt) stmt > -#else /* #ifdef CONFIG_RCU_TRACE */ > -#define RCU_TRACE(stmt) > -#endif /* #else #ifdef CONFIG_RCU_TRACE */ > > /* Offset to allow for unmatched rcu_irq_{enter,exit}(). */ > #define DYNTICK_IRQ_NONIDLE ((LONG_MAX / 2) + 1) > @@ -229,12 +224,12 @@ static inline bool __rcu_reclaim(const char *rn, struct rcu_head *head) > > rcu_lock_acquire(&rcu_callback_map); > if (__is_kfree_rcu_offset(offset)) { > - RCU_TRACE(trace_rcu_invoke_kfree_callback(rn, head, offset);) > + trace_rcu_invoke_kfree_callback(rn, head, offset); > kfree((void *)head - offset); > rcu_lock_release(&rcu_callback_map); > return true; > } else { > - RCU_TRACE(trace_rcu_invoke_callback(rn, head);) > + trace_rcu_invoke_callback(rn, head); > f = head->func; > WRITE_ONCE(head->func, (rcu_callback_t)0L); > f(head); > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c > index 9180158..d2ad39f 100644 > --- a/kernel/rcu/tree.c > +++ b/kernel/rcu/tree.c > @@ -2329,14 +2329,14 @@ static void rcu_report_qs_rnp(unsigned long mask, struct rcu_node *rnp, > */ > int rcutree_dying_cpu(unsigned int cpu) > { > - RCU_TRACE(bool blkd;) > - RCU_TRACE(struct rcu_data *rdp = this_cpu_ptr(&rcu_data);) > - RCU_TRACE(struct rcu_node *rnp = rdp->mynode;) > + bool blkd; > + struct rcu_data *rdp = this_cpu_ptr(&rcu_data); > + struct rcu_node *rnp = rdp->mynode; > > if (!IS_ENABLED(CONFIG_HOTPLUG_CPU)) > return 0; > > - RCU_TRACE(blkd = !!(rnp->qsmask & rdp->grpmask);) > + blkd = !!(rnp->qsmask & rdp->grpmask); > trace_rcu_grace_period(rcu_state.name, rnp->gp_seq, > blkd ? TPS("cpuofl") : TPS("cpuofl-bgp")); > return 0; > -- > 1.8.3.1 > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/3] tracing: introduce TRACE_EVENT_NONE and use it 2019-03-26 1:40 [PATCH 0/3] tracing: introduce TRACE_EVENT_NONE and use it Yafang Shao ` (2 preceding siblings ...) 2019-03-26 1:40 ` [PATCH 3/3] rcu: validate arguments for rcu tracepoints Yafang Shao @ 2019-03-26 2:17 ` Steven Rostedt 2019-03-26 2:24 ` Yafang Shao 3 siblings, 1 reply; 9+ messages in thread From: Steven Rostedt @ 2019-03-26 2:17 UTC (permalink / raw) To: Yafang Shao Cc: mingo, peterz, paulmck, josh, mathieu.desnoyers, jiangshanlai, joel, shaoyafang, linux-kernel On Tue, 26 Mar 2019 09:40:04 +0800 Yafang Shao <laoar.shao@gmail.com> wrote: > In this patchset, I introduce a new macro TRACE_EVENT_NONE(), which will > define a tracepoint as a do-nothing inline function. > #define TRACE_EVENT_NONE(name, proto) \ > static inline void trace_##name(proto) \ > { } \ > static inline bool trace_##name##_enabled(void) \ > { \ > return false; \ > } > BTW, I prefer a name of TRACE_EVENT_DISABLED() Which shows that it is disabled, or TRACE_EVENT_UNDEF(), or TRACE_EVENT_NOP(). Something that states it is turned off. When I first saw NONE() I thought it was another attempt to introduce zero parameter trace events. > Let's take some example for why this macro is needed. > > - sched > The tracepoints trace_sched_stat_{iowait, blocked, wait, sleep} should > be not exposed to user if CONFIG_SCHEDSTATS is not set. > We can place #ifdef in the kernel/sched/fair.c to fix it, but we > don't want to sprinkle #ifdef. But you still sprinkle #ifdef in the header, but the part I don't like is the need to duplicate the prototypes and the like. > So with TRACE_EVENT_NONE(), we can fix it in > include/trace/events/sched.h. > > - rcu > When CONFIG_RCU_TRACE is not set, some rcu tracepoints are define as > do-nothing macro without validating arguments, that is not proper. > We should validate the arguments. > > Yafang Shao (3): > tracing: introduce TRACE_EVENT_NONE() > sched/fair: do not expose some tracepoints to user if > CONFIG_SCHEDSTATS is not set > rcu: validate arguments for rcu tracepoints > See my reply in the next patch. -- Steve ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/3] tracing: introduce TRACE_EVENT_NONE and use it 2019-03-26 2:17 ` [PATCH 0/3] tracing: introduce TRACE_EVENT_NONE and use it Steven Rostedt @ 2019-03-26 2:24 ` Yafang Shao 0 siblings, 0 replies; 9+ messages in thread From: Yafang Shao @ 2019-03-26 2:24 UTC (permalink / raw) To: Steven Rostedt Cc: mingo, Peter Zijlstra, Paul McKenney, josh, Mathieu Desnoyers, jiangshanlai, joel, shaoyafang, LKML On Tue, Mar 26, 2019 at 10:17 AM Steven Rostedt <rostedt@goodmis.org> wrote: > > On Tue, 26 Mar 2019 09:40:04 +0800 > Yafang Shao <laoar.shao@gmail.com> wrote: > > > In this patchset, I introduce a new macro TRACE_EVENT_NONE(), which will > > define a tracepoint as a do-nothing inline function. > > #define TRACE_EVENT_NONE(name, proto) \ > > static inline void trace_##name(proto) \ > > { } \ > > static inline bool trace_##name##_enabled(void) \ > > { \ > > return false; \ > > } > > > > BTW, I prefer a name of TRACE_EVENT_DISABLED() > > Which shows that it is disabled, or TRACE_EVENT_UNDEF(), or > TRACE_EVENT_NOP(). Something that states it is turned off. When I first > saw NONE() I thought it was another attempt to introduce zero parameter > trace events. > I prefer TRACE_EVENT_NOP. I will change it. Thanks Yafang > > > Let's take some example for why this macro is needed. > > > > - sched > > The tracepoints trace_sched_stat_{iowait, blocked, wait, sleep} should > > be not exposed to user if CONFIG_SCHEDSTATS is not set. > > We can place #ifdef in the kernel/sched/fair.c to fix it, but we > > don't want to sprinkle #ifdef. > > But you still sprinkle #ifdef in the header, but the part I don't like > is the need to duplicate the prototypes and the like. > > > > So with TRACE_EVENT_NONE(), we can fix it in > > include/trace/events/sched.h. > > > > - rcu > > When CONFIG_RCU_TRACE is not set, some rcu tracepoints are define as > > do-nothing macro without validating arguments, that is not proper. > > We should validate the arguments. > > > > Yafang Shao (3): > > tracing: introduce TRACE_EVENT_NONE() > > sched/fair: do not expose some tracepoints to user if > > CONFIG_SCHEDSTATS is not set > > rcu: validate arguments for rcu tracepoints > > > > See my reply in the next patch. > > -- Steve ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2019-03-26 14:33 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-03-26 1:40 [PATCH 0/3] tracing: introduce TRACE_EVENT_NONE and use it Yafang Shao 2019-03-26 1:40 ` [PATCH 1/3] tracing: introduce TRACE_EVENT_NONE() Yafang Shao 2019-03-26 1:40 ` [PATCH 2/3] sched/fair: do not expose some tracepoints to user if CONFIG_SCHEDSTATS is not set Yafang Shao 2019-03-26 2:21 ` Steven Rostedt 2019-03-26 2:23 ` Yafang Shao 2019-03-26 1:40 ` [PATCH 3/3] rcu: validate arguments for rcu tracepoints Yafang Shao 2019-03-26 14:32 ` Paul E. McKenney 2019-03-26 2:17 ` [PATCH 0/3] tracing: introduce TRACE_EVENT_NONE and use it Steven Rostedt 2019-03-26 2:24 ` Yafang Shao
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox