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;