Merge branch 'skb-drop-reasons'
Menglong Dong says:
====================
net: dev: add skb drop reasons to net/core/dev.c
In the commit c504e5c2f9 ("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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
6af3b428cd
4 changed files with 50 additions and 13 deletions
|
|
@ -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 @@ no_lock_out:
|
|||
}
|
||||
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 @@ enqueue:
|
|||
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 @@ check_vlan_id:
|
|||
*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);
|
||||
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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue