Re: [RFC][PATCH 2/9] deadlock prevention core
From: Thomas Graf <tgraf@suug.ch>
Date: 2006-08-08 21:17:13
Also in:
linux-mm, lkml
* Peter Zijlstra [off-list ref] 2006-08-08 21:33
+struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
+ unsigned length, gfp_t gfp_mask)
+{
+ struct sk_buff *skb;
+
+ if (dev && (dev->flags & IFF_MEMALLOC)) {
+ WARN_ON(gfp_mask & (__GFP_NOMEMALLOC | __GFP_MEMALLOC));
+ gfp_mask &= ~(__GFP_NOMEMALLOC | __GFP_MEMALLOC);
+
+ if ((skb = ___netdev_alloc_skb(dev, length,
+ gfp_mask | __GFP_NOMEMALLOC)))
+ goto done;
+ if (dev_reserve_used(dev) >= dev->rx_reserve)
+ goto out;
+ if (!(skb = ___netdev_alloc_skb(dev, length,
+ gfp_mask | __GFP_MEMALLOC)))
+ goto out;
+ atomic_inc(&dev->rx_reserve_used);
+ } else
+ if (!(skb = ___netdev_alloc_skb(dev, length, gfp_mask)))
+ goto out;
+
+done:
+ skb->dev = dev;
+out:
+ return skb;
+}
+quoted hunk ↗ jump to hunk
void __kfree_skb(struct sk_buff *skb) { + struct net_device *dev = skb->dev; + dst_release(skb->dst); #ifdef CONFIG_XFRM secpath_put(skb->sp);@@ -389,6 +480,8 @@ void __kfree_skb(struct sk_buff *skb) #endif kfree_skbmem(skb); + if (dev && (dev->flags & IFF_MEMALLOC)) + dev_unreserve_skb(dev); }
skb->dev is not guaranteed to still point to the "allocating" device once the skb is freed again so reserve/unreserve isn't symmetric. You'd need skb->alloc_dev or something.