| Subject: net: Another local_irq_disable/kmalloc headache |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Wed, 26 Sep 2012 16:21:08 +0200 |
| |
| Replace it by a local lock. Though that's pretty inefficient :( |
| |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| --- |
| net/core/skbuff.c | 6 ++++-- |
| 1 file changed, 4 insertions(+), 2 deletions(-) |
| |
| Index: linux-stable/net/core/skbuff.c |
| =================================================================== |
| --- linux-stable.orig/net/core/skbuff.c |
| +++ linux-stable/net/core/skbuff.c |
| @@ -60,6 +60,7 @@ |
| #include <linux/scatterlist.h> |
| #include <linux/errqueue.h> |
| #include <linux/prefetch.h> |
| +#include <linux/locallock.h> |
| |
| #include <net/protocol.h> |
| #include <net/dst.h> |
| @@ -345,6 +346,7 @@ struct netdev_alloc_cache { |
| unsigned int pagecnt_bias; |
| }; |
| static DEFINE_PER_CPU(struct netdev_alloc_cache, netdev_alloc_cache); |
| +static DEFINE_LOCAL_IRQ_LOCK(netdev_alloc_lock); |
| |
| #define NETDEV_PAGECNT_BIAS (PAGE_SIZE / SMP_CACHE_BYTES) |
| |
| @@ -354,7 +356,7 @@ static void *__netdev_alloc_frag(unsigne |
| void *data = NULL; |
| unsigned long flags; |
| |
| - local_irq_save(flags); |
| + local_lock_irqsave(netdev_alloc_lock, flags); |
| nc = &__get_cpu_var(netdev_alloc_cache); |
| if (unlikely(!nc->page)) { |
| refill: |
| @@ -379,7 +381,7 @@ recycle: |
| nc->offset += fragsz; |
| nc->pagecnt_bias--; |
| end: |
| - local_irq_restore(flags); |
| + local_unlock_irqrestore(netdev_alloc_lock, flags); |
| return data; |
| } |
| |