12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- From: Felix Fietkau <[email protected]>
- Date: Sat, 23 Mar 2019 18:26:10 +0100
- Subject: [PATCH] net: use bulk free in kfree_skb_list
- Since we're freeing multiple skbs, we might as well use bulk free to save a
- few cycles. Use the same conditions for bulk free as in napi_consume_skb.
- Signed-off-by: Felix Fietkau <[email protected]>
- ---
- --- a/net/core/skbuff.c
- +++ b/net/core/skbuff.c
- @@ -666,12 +666,44 @@ EXPORT_SYMBOL(kfree_skb);
-
- void kfree_skb_list(struct sk_buff *segs)
- {
- - while (segs) {
- - struct sk_buff *next = segs->next;
- + struct sk_buff *next = segs;
- + void *skbs[16];
- + int n_skbs = 0;
-
- - kfree_skb(segs);
- - segs = next;
- + while ((segs = next) != NULL) {
- + next = segs->next;
- +
- + if (segs->fclone != SKB_FCLONE_UNAVAILABLE) {
- + kfree_skb(segs);
- + continue;
- + }
- +
- + if (!skb_unref(segs))
- + continue;
- +
- + trace_kfree_skb(segs, __builtin_return_address(0));
- +
- + /* drop skb->head and call any destructors for packet */
- + skb_release_all(segs);
- +
- +#ifdef CONFIG_SLUB
- + /* SLUB writes into objects when freeing */
- + prefetchw(segs);
- +#endif
- +
- + skbs[n_skbs++] = segs;
- +
- + if (n_skbs < ARRAY_SIZE(skbs))
- + continue;
- +
- + kmem_cache_free_bulk(skbuff_head_cache, n_skbs, skbs);
- + n_skbs = 0;
- }
- +
- + if (!n_skbs)
- + return;
- +
- + kmem_cache_free_bulk(skbuff_head_cache, n_skbs, skbs);
- }
- EXPORT_SYMBOL(kfree_skb_list);
-
|