* [PATCH] qdisc: add tracepoint qdisc:qdisc_dequeue for dequeued SKBs
@ 2017-08-15 19:11 Jesper Dangaard Brouer
2017-08-16 2:31 ` David Ahern
2017-08-16 21:09 ` David Miller
0 siblings, 2 replies; 4+ messages in thread
From: Jesper Dangaard Brouer @ 2017-08-15 19:11 UTC (permalink / raw)
To: netdev; +Cc: pstaszewski, Jesper Dangaard Brouer
The main purpose of this tracepoint is to monitor bulk dequeue
in the network qdisc layer, as it cannot be deducted from the
existing qdisc stats.
The txq_state can be used for determining the reason for zero packet
dequeues, see enum netdev_queue_state_t.
Notice all packets doesn't necessary activate this tracepoint. As
qdiscs with flag TCQ_F_CAN_BYPASS, can directly invoke
sch_direct_xmit() when qdisc_qlen is zero.
Remember that perf record supports filters like:
perf record -e qdisc:qdisc_dequeue \
--filter 'ifindex == 4 && (packets > 1 || txq_state > 0)'
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
include/trace/events/qdisc.h | 50 ++++++++++++++++++++++++++++++++++++++++++
net/core/net-traces.c | 1 +
net/sched/sch_generic.c | 8 +++++--
3 files changed, 57 insertions(+), 2 deletions(-)
create mode 100644 include/trace/events/qdisc.h
diff --git a/include/trace/events/qdisc.h b/include/trace/events/qdisc.h
new file mode 100644
index 000000000000..60d0d8bd336d
--- /dev/null
+++ b/include/trace/events/qdisc.h
@@ -0,0 +1,50 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM qdisc
+
+#if !defined(_TRACE_QDISC_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_QDISC_H_
+
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/tracepoint.h>
+#include <linux/ftrace.h>
+
+TRACE_EVENT(qdisc_dequeue,
+
+ TP_PROTO(struct Qdisc *qdisc, const struct netdev_queue *txq,
+ int packets, struct sk_buff *skb),
+
+ TP_ARGS(qdisc, txq, packets, skb),
+
+ TP_STRUCT__entry(
+ __field( struct Qdisc *, qdisc )
+ __field(const struct netdev_queue *, txq )
+ __field( int, packets )
+ __field( void *, skbaddr )
+ __field( int, ifindex )
+ __field( u32, handle )
+ __field( u32, parent )
+ __field( unsigned long, txq_state)
+ ),
+
+ /* skb==NULL indicate packets dequeued was 0, even when packets==1 */
+ TP_fast_assign(
+ __entry->qdisc = qdisc;
+ __entry->txq = txq;
+ __entry->packets = skb ? packets : 0;
+ __entry->skbaddr = skb;
+ __entry->ifindex = txq->dev ? txq->dev->ifindex : 0;
+ __entry->handle = qdisc->handle;
+ __entry->parent = qdisc->parent;
+ __entry->txq_state = txq->state;
+ ),
+
+ TP_printk("dequeue ifindex=%d qdisc handle=0x%X parent=0x%X txq_state=0x%lX packets=%d skbaddr=%p",
+ __entry->ifindex, __entry->handle, __entry->parent,
+ __entry->txq_state, __entry->packets, __entry->skbaddr )
+);
+
+#endif /* _TRACE_QDISC_H_ */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/net/core/net-traces.c b/net/core/net-traces.c
index 92da5e4ceb4f..4f1468ccd056 100644
--- a/net/core/net-traces.c
+++ b/net/core/net-traces.c
@@ -32,6 +32,7 @@
#include <trace/events/sock.h>
#include <trace/events/udp.h>
#include <trace/events/fib.h>
+#include <trace/events/qdisc.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <trace/events/fib6.h>
EXPORT_TRACEPOINT_SYMBOL_GPL(fib6_table_lookup);
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 57ba406f1437..c6b89a34e8d2 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -29,6 +29,7 @@
#include <net/sch_generic.h>
#include <net/pkt_sched.h>
#include <net/dst.h>
+#include <trace/events/qdisc.h>
/* Qdisc to use by default */
const struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops;
@@ -126,7 +127,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
q->q.qlen--;
} else
skb = NULL;
- return skb;
+ goto trace;
}
*validate = true;
skb = q->skb_bad_txq;
@@ -139,7 +140,8 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
q->q.qlen--;
goto bulk;
}
- return NULL;
+ skb = NULL;
+ goto trace;
}
if (!(q->flags & TCQ_F_ONETXQUEUE) ||
!netif_xmit_frozen_or_stopped(txq))
@@ -151,6 +153,8 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
else
try_bulk_dequeue_skb_slow(q, skb, packets);
}
+trace:
+ trace_qdisc_dequeue(q, txq, *packets, skb);
return skb;
}
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] qdisc: add tracepoint qdisc:qdisc_dequeue for dequeued SKBs
2017-08-15 19:11 [PATCH] qdisc: add tracepoint qdisc:qdisc_dequeue for dequeued SKBs Jesper Dangaard Brouer
@ 2017-08-16 2:31 ` David Ahern
2017-08-16 5:15 ` Jesper Dangaard Brouer
2017-08-16 21:09 ` David Miller
1 sibling, 1 reply; 4+ messages in thread
From: David Ahern @ 2017-08-16 2:31 UTC (permalink / raw)
To: Jesper Dangaard Brouer, netdev; +Cc: pstaszewski
On 8/15/17 1:11 PM, Jesper Dangaard Brouer wrote:
> diff --git a/include/trace/events/qdisc.h b/include/trace/events/qdisc.h
> new file mode 100644
> index 000000000000..60d0d8bd336d
> --- /dev/null
> +++ b/include/trace/events/qdisc.h
> @@ -0,0 +1,50 @@
> +#undef TRACE_SYSTEM
> +#define TRACE_SYSTEM qdisc
> +
> +#if !defined(_TRACE_QDISC_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_QDISC_H_
> +
> +#include <linux/skbuff.h>
> +#include <linux/netdevice.h>
> +#include <linux/tracepoint.h>
> +#include <linux/ftrace.h>
> +
> +TRACE_EVENT(qdisc_dequeue,
> +
> + TP_PROTO(struct Qdisc *qdisc, const struct netdev_queue *txq,
> + int packets, struct sk_buff *skb),
> +
> + TP_ARGS(qdisc, txq, packets, skb),
> +
> + TP_STRUCT__entry(
> + __field( struct Qdisc *, qdisc )
> + __field(const struct netdev_queue *, txq )
Why save qdisc and txq pointers in the tracepoint data?
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] qdisc: add tracepoint qdisc:qdisc_dequeue for dequeued SKBs
2017-08-16 2:31 ` David Ahern
@ 2017-08-16 5:15 ` Jesper Dangaard Brouer
0 siblings, 0 replies; 4+ messages in thread
From: Jesper Dangaard Brouer @ 2017-08-16 5:15 UTC (permalink / raw)
To: David Ahern; +Cc: netdev, pstaszewski, brouer
On Tue, 15 Aug 2017 20:31:44 -0600
David Ahern <dsahern@gmail.com> wrote:
> On 8/15/17 1:11 PM, Jesper Dangaard Brouer wrote:
> > diff --git a/include/trace/events/qdisc.h b/include/trace/events/qdisc.h
> > new file mode 100644
> > index 000000000000..60d0d8bd336d
> > --- /dev/null
> > +++ b/include/trace/events/qdisc.h
> > @@ -0,0 +1,50 @@
> > +#undef TRACE_SYSTEM
> > +#define TRACE_SYSTEM qdisc
> > +
> > +#if !defined(_TRACE_QDISC_H) || defined(TRACE_HEADER_MULTI_READ)
> > +#define _TRACE_QDISC_H_
> > +
> > +#include <linux/skbuff.h>
> > +#include <linux/netdevice.h>
> > +#include <linux/tracepoint.h>
> > +#include <linux/ftrace.h>
> > +
> > +TRACE_EVENT(qdisc_dequeue,
> > +
> > + TP_PROTO(struct Qdisc *qdisc, const struct netdev_queue *txq,
> > + int packets, struct sk_buff *skb),
> > +
> > + TP_ARGS(qdisc, txq, packets, skb),
> > +
> > + TP_STRUCT__entry(
> > + __field( struct Qdisc *, qdisc )
> > + __field(const struct netdev_queue *, txq )
>
> Why save qdisc and txq pointers in the tracepoint data?
I wanted to attach a BPF program, and allow it to dereference these
pointers. Which is done via bpf_probe_read like:
unsigned int qdisc_flags;
bpf_probe_read(&qdisc_flags, sizeof(qdisc_flags), &ctx->qdisc->flags);
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] qdisc: add tracepoint qdisc:qdisc_dequeue for dequeued SKBs
2017-08-15 19:11 [PATCH] qdisc: add tracepoint qdisc:qdisc_dequeue for dequeued SKBs Jesper Dangaard Brouer
2017-08-16 2:31 ` David Ahern
@ 2017-08-16 21:09 ` David Miller
1 sibling, 0 replies; 4+ messages in thread
From: David Miller @ 2017-08-16 21:09 UTC (permalink / raw)
To: brouer; +Cc: netdev, pstaszewski
From: Jesper Dangaard Brouer <brouer@redhat.com>
Date: Tue, 15 Aug 2017 21:11:03 +0200
> The main purpose of this tracepoint is to monitor bulk dequeue
> in the network qdisc layer, as it cannot be deducted from the
> existing qdisc stats.
>
> The txq_state can be used for determining the reason for zero packet
> dequeues, see enum netdev_queue_state_t.
>
> Notice all packets doesn't necessary activate this tracepoint. As
> qdiscs with flag TCQ_F_CAN_BYPASS, can directly invoke
> sch_direct_xmit() when qdisc_qlen is zero.
>
> Remember that perf record supports filters like:
>
> perf record -e qdisc:qdisc_dequeue \
> --filter 'ifindex == 4 && (packets > 1 || txq_state > 0)'
>
> Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
I'll apply this to net-next, thanks Jesper.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-08-16 21:09 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-15 19:11 [PATCH] qdisc: add tracepoint qdisc:qdisc_dequeue for dequeued SKBs Jesper Dangaard Brouer
2017-08-16 2:31 ` David Ahern
2017-08-16 5:15 ` Jesper Dangaard Brouer
2017-08-16 21:09 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).