First example of a layer splitting the list (rather than merely taking
 individual packets off it).

Signed-off-by: Edward Cree <ec...@solarflare.com>
---
 net/core/dev.c | 46 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 38 insertions(+), 8 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 27980c13ad5c..92d78b3de656 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4670,6 +4670,14 @@ int netif_receive_skb_core(struct sk_buff *skb)
 }
 EXPORT_SYMBOL(netif_receive_skb_core);
 
+static void __netif_receive_skb_list_core(struct sk_buff_head *list, bool 
pfmemalloc)
+{
+       struct sk_buff *skb;
+
+       while ((skb = __skb_dequeue(list)) != NULL)
+               __netif_receive_skb_core(skb, pfmemalloc);
+}
+
 static int __netif_receive_skb(struct sk_buff *skb)
 {
        int ret;
@@ -4695,6 +4703,36 @@ static int __netif_receive_skb(struct sk_buff *skb)
        return ret;
 }
 
+static void __netif_receive_skb_list(struct sk_buff_head *list)
+{
+       unsigned long noreclaim_flag = 0;
+       struct sk_buff_head sublist;
+       bool pfmemalloc = false; /* Is current sublist PF_MEMALLOC? */
+       struct sk_buff *skb;
+
+       __skb_queue_head_init(&sublist);
+
+       while ((skb = __skb_dequeue(list)) != NULL) {
+               if ((sk_memalloc_socks() && skb_pfmemalloc(skb)) != pfmemalloc) 
{
+                       /* Handle the previous sublist */
+                       __netif_receive_skb_list_core(&sublist, pfmemalloc);
+                       pfmemalloc = !pfmemalloc;
+                       /* See comments in __netif_receive_skb */
+                       if (pfmemalloc)
+                               noreclaim_flag = memalloc_noreclaim_save();
+                       else
+                               memalloc_noreclaim_restore(noreclaim_flag);
+                       __skb_queue_head_init(&sublist);
+               }
+               __skb_queue_tail(&sublist, skb);
+       }
+       /* Handle the last sublist */
+       __netif_receive_skb_list_core(&sublist, pfmemalloc);
+       /* Restore pflags */
+       if (pfmemalloc)
+               memalloc_noreclaim_restore(noreclaim_flag);
+}
+
 static int generic_xdp_install(struct net_device *dev, struct netdev_bpf *xdp)
 {
        struct bpf_prog *old = rtnl_dereference(dev->xdp_prog);
@@ -4729,14 +4767,6 @@ static int generic_xdp_install(struct net_device *dev, 
struct netdev_bpf *xdp)
        return ret;
 }
 
-static void __netif_receive_skb_list(struct sk_buff_head *list)
-{
-       struct sk_buff *skb;
-
-       while ((skb = __skb_dequeue(list)) != NULL)
-               __netif_receive_skb(skb);
-}
-
 static int netif_receive_skb_internal(struct sk_buff *skb)
 {
        int ret;

Reply via email to