650-net-use-bulk-free-in-kfree_skb_list.patch 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. From: Felix Fietkau <[email protected]>
  2. Date: Sat, 23 Mar 2019 18:26:10 +0100
  3. Subject: [PATCH] net: use bulk free in kfree_skb_list
  4. Since we're freeing multiple skbs, we might as well use bulk free to save a
  5. few cycles. Use the same conditions for bulk free as in napi_consume_skb.
  6. Signed-off-by: Felix Fietkau <[email protected]>
  7. ---
  8. --- a/net/core/skbuff.c
  9. +++ b/net/core/skbuff.c
  10. @@ -666,12 +666,44 @@ EXPORT_SYMBOL(kfree_skb);
  11. void kfree_skb_list(struct sk_buff *segs)
  12. {
  13. - while (segs) {
  14. - struct sk_buff *next = segs->next;
  15. + struct sk_buff *next = segs;
  16. + void *skbs[16];
  17. + int n_skbs = 0;
  18. - kfree_skb(segs);
  19. - segs = next;
  20. + while ((segs = next) != NULL) {
  21. + next = segs->next;
  22. +
  23. + if (segs->fclone != SKB_FCLONE_UNAVAILABLE) {
  24. + kfree_skb(segs);
  25. + continue;
  26. + }
  27. +
  28. + if (!skb_unref(segs))
  29. + continue;
  30. +
  31. + trace_kfree_skb(segs, __builtin_return_address(0));
  32. +
  33. + /* drop skb->head and call any destructors for packet */
  34. + skb_release_all(segs);
  35. +
  36. +#ifdef CONFIG_SLUB
  37. + /* SLUB writes into objects when freeing */
  38. + prefetchw(segs);
  39. +#endif
  40. +
  41. + skbs[n_skbs++] = segs;
  42. +
  43. + if (n_skbs < ARRAY_SIZE(skbs))
  44. + continue;
  45. +
  46. + kmem_cache_free_bulk(skbuff_head_cache, n_skbs, skbs);
  47. + n_skbs = 0;
  48. }
  49. +
  50. + if (!n_skbs)
  51. + return;
  52. +
  53. + kmem_cache_free_bulk(skbuff_head_cache, n_skbs, skbs);
  54. }
  55. EXPORT_SYMBOL(kfree_skb_list);