[RFC PATCH v2 net-next 05/12] net: core: another layer of lists, around PF_MEMALLOC skb handling
From: Edward Cree <hidden>
Date: 2018-06-26 18:19:32
Subsystem:
networking [general], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
First example of a layer splitting the list (rather than merely taking individual packets off it). Signed-off-by: Edward Cree <redacted> --- 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;