Skip to content

Commit

Permalink
qdisc: add tracepoint qdisc:qdisc_dequeue for dequeued SKBs
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
netoptimizer authored and davem330 committed Aug 16, 2017
1 parent 7440ccc commit e543002
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 2 deletions.
50 changes: 50 additions & 0 deletions include/trace/events/qdisc.h
Original file line number Diff line number Diff line change
@@ -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>
1 change: 1 addition & 0 deletions net/core/net-traces.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 6 additions & 2 deletions net/sched/sch_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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))
Expand All @@ -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;
}

Expand Down

0 comments on commit e543002

Please sign in to comment.