| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Wed, 26 Sep 2012 16:21:08 +0200 |
| Subject: net: Another local_irq_disable/kmalloc headache |
| |
| Replace it by a local lock. Though that's pretty inefficient :( |
| |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| --- |
| net/core/skbuff.c | 10 ++++++---- |
| 1 file changed, 6 insertions(+), 4 deletions(-) |
| |
| --- a/net/core/skbuff.c |
| +++ b/net/core/skbuff.c |
| @@ -64,6 +64,7 @@ |
| #include <linux/errqueue.h> |
| #include <linux/prefetch.h> |
| #include <linux/if_vlan.h> |
| +#include <linux/locallock.h> |
| |
| #include <net/protocol.h> |
| #include <net/dst.h> |
| @@ -359,6 +360,7 @@ struct napi_alloc_cache { |
| |
| static DEFINE_PER_CPU(struct page_frag_cache, netdev_alloc_cache); |
| static DEFINE_PER_CPU(struct napi_alloc_cache, napi_alloc_cache); |
| +static DEFINE_LOCAL_IRQ_LOCK(netdev_alloc_lock); |
| |
| static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) |
| { |
| @@ -366,10 +368,10 @@ static void *__netdev_alloc_frag(unsigne |
| unsigned long flags; |
| void *data; |
| |
| - local_irq_save(flags); |
| + local_lock_irqsave(netdev_alloc_lock, flags); |
| nc = this_cpu_ptr(&netdev_alloc_cache); |
| data = page_frag_alloc(nc, fragsz, gfp_mask); |
| - local_irq_restore(flags); |
| + local_unlock_irqrestore(netdev_alloc_lock, flags); |
| return data; |
| } |
| |
| @@ -437,13 +439,13 @@ struct sk_buff *__netdev_alloc_skb(struc |
| if (sk_memalloc_socks()) |
| gfp_mask |= __GFP_MEMALLOC; |
| |
| - local_irq_save(flags); |
| + local_lock_irqsave(netdev_alloc_lock, flags); |
| |
| nc = this_cpu_ptr(&netdev_alloc_cache); |
| data = page_frag_alloc(nc, len, gfp_mask); |
| pfmemalloc = nc->pfmemalloc; |
| |
| - local_irq_restore(flags); |
| + local_unlock_irqrestore(netdev_alloc_lock, flags); |
| |
| if (unlikely(!data)) |
| return NULL; |