net: add skb_queue_purge_reason and __skb_queue_purge_reason
authorEric Dumazet <edumazet@google.com>
Fri, 18 Aug 2023 09:40:39 +0000 (09:40 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sat, 19 Aug 2023 14:30:15 +0000 (15:30 +0100)
skb_queue_purge() and __skb_queue_purge() become wrappers
around the new generic functions.

New SKB_DROP_REASON_QUEUE_PURGE drop reason is added,
but users can start adding more specific reasons.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/skbuff.h
include/net/dropreason-core.h
net/core/skbuff.c

index aa57e2e..9aec136 100644 (file)
@@ -3149,20 +3149,35 @@ static inline int skb_orphan_frags_rx(struct sk_buff *skb, gfp_t gfp_mask)
 }
 
 /**
- *     __skb_queue_purge - empty a list
+ *     __skb_queue_purge_reason - empty a list
  *     @list: list to empty
+ *     @reason: drop reason
  *
  *     Delete all buffers on an &sk_buff list. Each buffer is removed from
  *     the list and one reference dropped. This function does not take the
  *     list lock and the caller must hold the relevant locks to use it.
  */
-static inline void __skb_queue_purge(struct sk_buff_head *list)
+static inline void __skb_queue_purge_reason(struct sk_buff_head *list,
+                                           enum skb_drop_reason reason)
 {
        struct sk_buff *skb;
+
        while ((skb = __skb_dequeue(list)) != NULL)
-               kfree_skb(skb);
+               kfree_skb_reason(skb, reason);
+}
+
+static inline void __skb_queue_purge(struct sk_buff_head *list)
+{
+       __skb_queue_purge_reason(list, SKB_DROP_REASON_QUEUE_PURGE);
+}
+
+void skb_queue_purge_reason(struct sk_buff_head *list,
+                           enum skb_drop_reason reason);
+
+static inline void skb_queue_purge(struct sk_buff_head *list)
+{
+       skb_queue_purge_reason(list, SKB_DROP_REASON_QUEUE_PURGE);
 }
-void skb_queue_purge(struct sk_buff_head *list);
 
 unsigned int skb_rbtree_purge(struct rb_root *root);
 
index f291a3b..a587e83 100644 (file)
@@ -79,6 +79,7 @@
        FN(IPV6_NDISC_BAD_CODE)         \
        FN(IPV6_NDISC_BAD_OPTIONS)      \
        FN(IPV6_NDISC_NS_OTHERHOST)     \
+       FN(QUEUE_PURGE)                 \
        FNe(MAX)
 
 /**
@@ -342,6 +343,8 @@ enum skb_drop_reason {
         * for another host.
         */
        SKB_DROP_REASON_IPV6_NDISC_NS_OTHERHOST,
+       /** @SKB_DROP_REASON_QUEUE_PURGE: bulk free. */
+       SKB_DROP_REASON_QUEUE_PURGE,
        /**
         * @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which
         * shouldn't be used as a real 'reason' - only for tracing code gen
index 9b5bc62..117d36b 100644 (file)
@@ -3701,20 +3701,23 @@ struct sk_buff *skb_dequeue_tail(struct sk_buff_head *list)
 EXPORT_SYMBOL(skb_dequeue_tail);
 
 /**
- *     skb_queue_purge - empty a list
+ *     skb_queue_purge_reason - empty a list
  *     @list: list to empty
+ *     @reason: drop reason
  *
  *     Delete all buffers on an &sk_buff list. Each buffer is removed from
  *     the list and one reference dropped. This function takes the list
  *     lock and is atomic with respect to other list locking functions.
  */
-void skb_queue_purge(struct sk_buff_head *list)
+void skb_queue_purge_reason(struct sk_buff_head *list,
+                           enum skb_drop_reason reason)
 {
        struct sk_buff *skb;
+
        while ((skb = skb_dequeue(list)) != NULL)
-               kfree_skb(skb);
+               kfree_skb_reason(skb, reason);
 }
-EXPORT_SYMBOL(skb_queue_purge);
+EXPORT_SYMBOL(skb_queue_purge_reason);
 
 /**
  *     skb_rbtree_purge - empty a skb rbtree