Commit 6af3b428 authored by David S. Miller's avatar David S. Miller

Merge branch 'skb-drop-reasons'

Menglong Dong says:

====================
net: dev: add skb drop reasons to net/core/dev.c

In the commit c504e5c2 ("net: skb: introduce kfree_skb_reason()"),
we added the support of reporting the reasons of skb drops to kfree_skb
tracepoint. And in this series patches, reasons for skb drops are added
to the link layer, which means that 'net/core/dev.c' is our target.

Following functions are processed:

sch_handle_egress()
__dev_xmit_skb()
enqueue_to_backlog()
do_xdp_generic()
sch_handle_ingress()
__netif_receive_skb_core()

and following new drop reasons are added (what they mean can be see in
the document of them):

SKB_DROP_REASON_QDISC_EGRESS
SKB_DROP_REASON_QDISC_DROP
SKB_DROP_REASON_CPU_BACKLOG
SKB_DROP_REASON_XDP
SKB_DROP_REASON_QDISC_INGRESS
SKB_DROP_REASON_PTYPE_ABSENT

In order to add skb drop reasons to kfree_skb_list(), the function
kfree_skb_list_reason() is introduced in the 2th patch, which will be
used in __dev_xmit_skb() in the 3th patch.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9f9919f7 6c2728b7
......@@ -394,6 +394,24 @@ enum skb_drop_reason {
* entry is full
*/
SKB_DROP_REASON_NEIGH_DEAD, /* neigh entry is dead */
SKB_DROP_REASON_TC_EGRESS, /* dropped in TC egress HOOK */
SKB_DROP_REASON_QDISC_DROP, /* dropped by qdisc when packet
* outputting (failed to enqueue to
* current qdisc)
*/
SKB_DROP_REASON_CPU_BACKLOG, /* failed to enqueue the skb to
* the per CPU backlog queue. This
* can be caused by backlog queue
* full (see netdev_max_backlog in
* net.rst) or RPS flow limit
*/
SKB_DROP_REASON_XDP, /* dropped by XDP in input path */
SKB_DROP_REASON_TC_INGRESS, /* dropped in TC ingress HOOK */
SKB_DROP_REASON_PTYPE_ABSENT, /* not packet_type found to handle
* the skb. For an etner packet,
* this means that L3 protocol is
* not supported
*/
SKB_DROP_REASON_MAX,
};
......@@ -1201,10 +1219,16 @@ static inline void kfree_skb(struct sk_buff *skb)
}
void skb_release_head_state(struct sk_buff *skb);
void kfree_skb_list(struct sk_buff *segs);
void kfree_skb_list_reason(struct sk_buff *segs,
enum skb_drop_reason reason);
void skb_dump(const char *level, const struct sk_buff *skb, bool full_pkt);
void skb_tx_error(struct sk_buff *skb);
static inline void kfree_skb_list(struct sk_buff *segs)
{
kfree_skb_list_reason(segs, SKB_DROP_REASON_NOT_SPECIFIED);
}
#ifdef CONFIG_TRACEPOINTS
void consume_skb(struct sk_buff *skb);
#else
......
......@@ -45,6 +45,12 @@
EM(SKB_DROP_REASON_NEIGH_FAILED, NEIGH_FAILED) \
EM(SKB_DROP_REASON_NEIGH_QUEUEFULL, NEIGH_QUEUEFULL) \
EM(SKB_DROP_REASON_NEIGH_DEAD, NEIGH_DEAD) \
EM(SKB_DROP_REASON_TC_EGRESS, TC_EGRESS) \
EM(SKB_DROP_REASON_QDISC_DROP, QDISC_DROP) \
EM(SKB_DROP_REASON_CPU_BACKLOG, CPU_BACKLOG) \
EM(SKB_DROP_REASON_XDP, XDP) \
EM(SKB_DROP_REASON_TC_INGRESS, TC_INGRESS) \
EM(SKB_DROP_REASON_PTYPE_ABSENT, PTYPE_ABSENT) \
EMe(SKB_DROP_REASON_MAX, MAX)
#undef EM
......
......@@ -3759,7 +3759,8 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
no_lock_out:
if (unlikely(to_free))
kfree_skb_list(to_free);
kfree_skb_list_reason(to_free,
SKB_DROP_REASON_QDISC_DROP);
return rc;
}
......@@ -3814,7 +3815,7 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
}
spin_unlock(root_lock);
if (unlikely(to_free))
kfree_skb_list(to_free);
kfree_skb_list_reason(to_free, SKB_DROP_REASON_QDISC_DROP);
if (unlikely(contended))
spin_unlock(&q->busylock);
return rc;
......@@ -3889,7 +3890,7 @@ sch_handle_egress(struct sk_buff *skb, int *ret, struct net_device *dev)
case TC_ACT_SHOT:
mini_qdisc_qstats_cpu_drop(miniq);
*ret = NET_XMIT_DROP;
kfree_skb(skb);
kfree_skb_reason(skb, SKB_DROP_REASON_TC_EGRESS);
return NULL;
case TC_ACT_STOLEN:
case TC_ACT_QUEUED:
......@@ -4569,10 +4570,12 @@ static bool skb_flow_limit(struct sk_buff *skb, unsigned int qlen)
static int enqueue_to_backlog(struct sk_buff *skb, int cpu,
unsigned int *qtail)
{
enum skb_drop_reason reason;
struct softnet_data *sd;
unsigned long flags;
unsigned int qlen;
reason = SKB_DROP_REASON_NOT_SPECIFIED;
sd = &per_cpu(softnet_data, cpu);
rps_lock_irqsave(sd, &flags);
......@@ -4595,13 +4598,14 @@ static int enqueue_to_backlog(struct sk_buff *skb, int cpu,
napi_schedule_rps(sd);
goto enqueue;
}
reason = SKB_DROP_REASON_CPU_BACKLOG;
drop:
sd->dropped++;
rps_unlock_irq_restore(sd, &flags);
atomic_long_inc(&skb->dev->rx_dropped);
kfree_skb(skb);
kfree_skb_reason(skb, reason);
return NET_RX_DROP;
}
......@@ -4821,7 +4825,7 @@ int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb)
}
return XDP_PASS;
out_redir:
kfree_skb(skb);
kfree_skb_reason(skb, SKB_DROP_REASON_XDP);
return XDP_DROP;
}
EXPORT_SYMBOL_GPL(do_xdp_generic);
......@@ -5037,7 +5041,7 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret,
break;
case TC_ACT_SHOT:
mini_qdisc_qstats_cpu_drop(miniq);
kfree_skb(skb);
kfree_skb_reason(skb, SKB_DROP_REASON_TC_INGRESS);
return NULL;
case TC_ACT_STOLEN:
case TC_ACT_QUEUED:
......@@ -5354,11 +5358,13 @@ static int __netif_receive_skb_core(struct sk_buff **pskb, bool pfmemalloc,
*ppt_prev = pt_prev;
} else {
drop:
if (!deliver_exact)
if (!deliver_exact) {
atomic_long_inc(&skb->dev->rx_dropped);
else
kfree_skb_reason(skb, SKB_DROP_REASON_PTYPE_ABSENT);
} else {
atomic_long_inc(&skb->dev->rx_nohandler);
kfree_skb(skb);
}
/* Jamal, now you will not able to escape explaining
* me how you were going to use this. :-)
*/
......
......@@ -777,16 +777,17 @@ void kfree_skb_reason(struct sk_buff *skb, enum skb_drop_reason reason)
}
EXPORT_SYMBOL(kfree_skb_reason);
void kfree_skb_list(struct sk_buff *segs)
void kfree_skb_list_reason(struct sk_buff *segs,
enum skb_drop_reason reason)
{
while (segs) {
struct sk_buff *next = segs->next;
kfree_skb(segs);
kfree_skb_reason(segs, reason);
segs = next;
}
}
EXPORT_SYMBOL(kfree_skb_list);
EXPORT_SYMBOL(kfree_skb_list_reason);
/* Dump skb information and contents.
*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment