From mboxrd@z Thu Jan 1 00:00:00 1970 From: nhorman@tuxdriver.com (Neil Horman) Date: Wed, 3 Dec 2008 11:01:34 -0500 Subject: [ltt-dev] [PATCH] add tracepoints to track change in napi states on network receive In-Reply-To: <20081202200150.GA27282@Krystal> References: <20081202195129.GA30042@hmsreliant.think-freely.org> <20081202200150.GA27282@Krystal> Message-ID: <20081203160134.GA6549@hmsreliant.think-freely.org> On Tue, Dec 02, 2008 at 03:01:50PM -0500, Mathieu Desnoyers wrote: > * Neil Horman (nhorman at tuxdriver.com) wrote: > > Hey there- > > I thought it would be handy to track the napi receive state of different > > network devices using ltt. This patch adds trace points to indicate when a napi > > instance has been scheduled, when its serviced and when it completes. > > > > Sounds great, see comments below, Hey, New patch, with previous comments taken into account. Patch to track the napi receive stat of different network devices using ltt. Adds trace points to indicate when a napi instance has been scheduled, when its serviced and when it completes Regards Neil Signed-off-by: Neil Horman include/linux/netdevice.h | 5 +++++ include/trace/netdevice.h | 30 ++++++++++++++++++++++++++++++ ltt/probes/net-trace.c | 22 ++++++++++++++++++++++ net/core/dev.c | 7 ++++++- 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 488c56e..7da71eb 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -43,6 +43,9 @@ #include +struct napi_struct; +#include + struct vlan_group; struct ethtool_ops; struct netpoll_info; @@ -386,6 +389,7 @@ static inline void napi_complete(struct napi_struct *n) local_irq_save(flags); __napi_complete(n); local_irq_restore(flags); + trace_napi_complete(n); } /** @@ -1726,6 +1730,7 @@ static inline int skb_bond_should_drop(struct sk_buff *skb) return 0; } + #endif /* __KERNEL__ */ #endif /* _LINUX_DEV_H */ diff --git a/include/trace/netdevice.h b/include/trace/netdevice.h new file mode 100644 index 0000000..ba48f6c --- /dev/null +++ b/include/trace/netdevice.h @@ -0,0 +1,30 @@ +#ifndef _INCLUDE_NETDEVICE_H_ +#define _INCLUDE_NETDEVICE_H_ + +#include + +/* Tracepoints */ + +/* + * Note these first 2 traces are actually in __napi_schedule and net_rx_action + * respectively. The former is in __napi_schedule because it uses at-most-once + * logic and placing it in the calling routine (napi_schedule) would produce + * countless trace events that were effectively no-ops. napi_poll is + * implemented in net_rx_action, because thats where we do our polling on + * devices. The last trace point is in napi_complete, right where you would + * think it would be. + */ +DEFINE_TRACE(napi_schedule, + TPPROTO(struct napi_struct *n), + TPARGS(n)); + +DEFINE_TRACE(napi_poll, + TPPROTO(struct napi_struct *n), + TPARGS(n)); + +DEFINE_TRACE(napi_complete, + TPPROTO(struct napi_struct *n), + TPARGS(n)); + +#endif + diff --git a/ltt/probes/net-trace.c b/ltt/probes/net-trace.c index bac2b21..bd4e621 100644 --- a/ltt/probes/net-trace.c +++ b/ltt/probes/net-trace.c @@ -9,6 +9,7 @@ #include #include #include +#include void probe_net_dev_xmit(struct sk_buff *skb) { @@ -104,6 +105,27 @@ void probe_socket_call(int call, unsigned long a0) "call %d a0 %lu", call, a0); } +void probe_napi_schedule(struct napi_struct *n) +{ + trace_mark_tp(net_napi_schedule, napi_schedule, probe_napi_schedule, + "schedule napi_struct %p name %s", + n, n->dev->name); +} + +void probe_napi_poll(struct napi_struct *n) +{ + trace_mark_tp(net_napi_poll, napi_poll, probe_napi_poll, + "service napi_struct %p name %s", + n, n->dev->name); +} + +void probe_napi_complete(struct napi_struct *n) +{ + trace_mark_tp(net_napi_complete, napi_complete, probe_napi_complete, + "complete napi_struct %p name %s", + n, n->dev->name); +} + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Mathieu Desnoyers"); MODULE_DESCRIPTION("Net Tracepoint Probes"); diff --git a/net/core/dev.c b/net/core/dev.c index 836fe6e..0c55c0f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -128,6 +128,7 @@ #include #include #include +#include #include "net-sysfs.h" @@ -2329,6 +2330,8 @@ void __napi_schedule(struct napi_struct *n) { unsigned long flags; + trace_napi_poll(n); + local_irq_save(flags); list_add_tail(&n->poll_list, &__get_cpu_var(softnet_data).poll_list); __raise_softirq_irqoff(NET_RX_SOFTIRQ); @@ -2380,8 +2383,10 @@ static void net_rx_action(struct softirq_action *h) * accidently calling ->poll() when NAPI is not scheduled. */ work = 0; - if (test_bit(NAPI_STATE_SCHED, &n->state)) + if (test_bit(NAPI_STATE_SCHED, &n->state)) { + trace_napi_poll(n); work = n->poll(n, weight); + } WARN_ON_ONCE(work > weight); -- /**************************************************** * Neil Horman * Software Engineer, Red Hat ****************************************************/