gfp_t gfp_mask)
 {
        struct page_frag_cache *nc;
-       unsigned long flags;
        struct sk_buff *skb;
        bool pfmemalloc;
        void *data;
        if (sk_memalloc_socks())
                gfp_mask |= __GFP_MEMALLOC;
 
-       local_irq_save(flags);
-
-       nc = this_cpu_ptr(&netdev_alloc_cache);
-       data = page_frag_alloc(nc, len, gfp_mask);
-       pfmemalloc = nc->pfmemalloc;
-
-       local_irq_restore(flags);
+       if (in_irq() || irqs_disabled()) {
+               nc = this_cpu_ptr(&netdev_alloc_cache);
+               data = page_frag_alloc(nc, len, gfp_mask);
+               pfmemalloc = nc->pfmemalloc;
+       } else {
+               local_bh_disable();
+               nc = this_cpu_ptr(&napi_alloc_cache.page);
+               data = page_frag_alloc(nc, len, gfp_mask);
+               pfmemalloc = nc->pfmemalloc;
+               local_bh_enable();
+       }
 
        if (unlikely(!data))
                return NULL;