hc
2023-11-06 9df731a176aab8e03b984b681b1bea01ccff6644
kernel/net/core/skbuff.c
....@@ -63,6 +63,7 @@
6363 #include <linux/errqueue.h>
6464 #include <linux/prefetch.h>
6565 #include <linux/if_vlan.h>
66
+#include <linux/locallock.h>
6667
6768 #include <net/protocol.h>
6869 #include <net/dst.h>
....@@ -330,6 +331,8 @@
330331
331332 static DEFINE_PER_CPU(struct page_frag_cache, netdev_alloc_cache);
332333 static DEFINE_PER_CPU(struct napi_alloc_cache, napi_alloc_cache);
334
+static DEFINE_LOCAL_IRQ_LOCK(netdev_alloc_lock);
335
+static DEFINE_LOCAL_IRQ_LOCK(napi_alloc_cache_lock);
333336
334337 static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
335338 {
....@@ -337,10 +340,10 @@
337340 unsigned long flags;
338341 void *data;
339342
340
- local_irq_save(flags);
343
+ local_lock_irqsave(netdev_alloc_lock, flags);
341344 nc = this_cpu_ptr(&netdev_alloc_cache);
342345 data = page_frag_alloc(nc, fragsz, gfp_mask);
343
- local_irq_restore(flags);
346
+ local_unlock_irqrestore(netdev_alloc_lock, flags);
344347 return data;
345348 }
346349
....@@ -361,9 +364,13 @@
361364
362365 static void *__napi_alloc_frag(unsigned int fragsz, gfp_t gfp_mask)
363366 {
364
- struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache);
367
+ struct napi_alloc_cache *nc;
368
+ void *data;
365369
366
- return page_frag_alloc(&nc->page, fragsz, gfp_mask);
370
+ nc = &get_locked_var(napi_alloc_cache_lock, napi_alloc_cache);
371
+ data = page_frag_alloc(&nc->page, fragsz, gfp_mask);
372
+ put_locked_var(napi_alloc_cache_lock, napi_alloc_cache);
373
+ return data;
367374 }
368375
369376 void *napi_alloc_frag(unsigned int fragsz)
....@@ -416,13 +423,13 @@
416423 if (sk_memalloc_socks())
417424 gfp_mask |= __GFP_MEMALLOC;
418425
419
- local_irq_save(flags);
426
+ local_lock_irqsave(netdev_alloc_lock, flags);
420427
421428 nc = this_cpu_ptr(&netdev_alloc_cache);
422429 data = page_frag_alloc(nc, len, gfp_mask);
423430 pfmemalloc = nc->pfmemalloc;
424431
425
- local_irq_restore(flags);
432
+ local_unlock_irqrestore(netdev_alloc_lock, flags);
426433
427434 if (unlikely(!data))
428435 return NULL;
....@@ -466,6 +473,7 @@
466473 struct napi_alloc_cache *nc;
467474 struct sk_buff *skb;
468475 void *data;
476
+ bool pfmemalloc;
469477
470478 len += NET_SKB_PAD + NET_IP_ALIGN;
471479
....@@ -488,7 +496,10 @@
488496 if (sk_memalloc_socks())
489497 gfp_mask |= __GFP_MEMALLOC;
490498
499
+ nc = &get_locked_var(napi_alloc_cache_lock, napi_alloc_cache);
491500 data = page_frag_alloc(&nc->page, len, gfp_mask);
501
+ pfmemalloc = nc->page.pfmemalloc;
502
+ put_locked_var(napi_alloc_cache_lock, napi_alloc_cache);
492503 if (unlikely(!data))
493504 return NULL;
494505
....@@ -499,7 +510,7 @@
499510 }
500511
501512 /* use OR instead of assignment to avoid clearing of bits in mask */
502
- if (nc->page.pfmemalloc)
513
+ if (pfmemalloc)
503514 skb->pfmemalloc = 1;
504515 skb->head_frag = 1;
505516
....@@ -731,23 +742,26 @@
731742
732743 void __kfree_skb_flush(void)
733744 {
734
- struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache);
745
+ struct napi_alloc_cache *nc;
735746
747
+ nc = &get_locked_var(napi_alloc_cache_lock, napi_alloc_cache);
736748 /* flush skb_cache if containing objects */
737749 if (nc->skb_count) {
738750 kmem_cache_free_bulk(skbuff_head_cache, nc->skb_count,
739751 nc->skb_cache);
740752 nc->skb_count = 0;
741753 }
754
+ put_locked_var(napi_alloc_cache_lock, napi_alloc_cache);
742755 }
743756
744757 static inline void _kfree_skb_defer(struct sk_buff *skb)
745758 {
746
- struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache);
759
+ struct napi_alloc_cache *nc;
747760
748761 /* drop skb->head and call any destructors for packet */
749762 skb_release_all(skb);
750763
764
+ nc = &get_locked_var(napi_alloc_cache_lock, napi_alloc_cache);
751765 /* record skb to CPU local list */
752766 nc->skb_cache[nc->skb_count++] = skb;
753767
....@@ -762,6 +776,7 @@
762776 nc->skb_cache);
763777 nc->skb_count = 0;
764778 }
779
+ put_locked_var(napi_alloc_cache_lock, napi_alloc_cache);
765780 }
766781 void __kfree_skb_defer(struct sk_buff *skb)
767782 {