Skip to content

Commit 7da517a

Browse files
ecree-solarflaredavem330
authored andcommitted
net: core: Another step of skb receive list processing
netif_receive_skb_list_internal() now processes a list and hands it on to the next function. Signed-off-by: Edward Cree <ecree@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 920572b commit 7da517a

File tree

1 file changed

+56
-5
lines changed

1 file changed

+56
-5
lines changed

net/core/dev.c

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4843,6 +4843,14 @@ static int generic_xdp_install(struct net_device *dev, struct netdev_bpf *xdp)
48434843
return ret;
48444844
}
48454845

4846+
static void __netif_receive_skb_list(struct list_head *head)
4847+
{
4848+
struct sk_buff *skb, *next;
4849+
4850+
list_for_each_entry_safe(skb, next, head, list)
4851+
__netif_receive_skb(skb);
4852+
}
4853+
48464854
static int netif_receive_skb_internal(struct sk_buff *skb)
48474855
{
48484856
int ret;
@@ -4883,6 +4891,50 @@ static int netif_receive_skb_internal(struct sk_buff *skb)
48834891
return ret;
48844892
}
48854893

4894+
static void netif_receive_skb_list_internal(struct list_head *head)
4895+
{
4896+
struct bpf_prog *xdp_prog = NULL;
4897+
struct sk_buff *skb, *next;
4898+
4899+
list_for_each_entry_safe(skb, next, head, list) {
4900+
net_timestamp_check(netdev_tstamp_prequeue, skb);
4901+
if (skb_defer_rx_timestamp(skb))
4902+
/* Handled, remove from list */
4903+
list_del(&skb->list);
4904+
}
4905+
4906+
if (static_branch_unlikely(&generic_xdp_needed_key)) {
4907+
preempt_disable();
4908+
rcu_read_lock();
4909+
list_for_each_entry_safe(skb, next, head, list) {
4910+
xdp_prog = rcu_dereference(skb->dev->xdp_prog);
4911+
if (do_xdp_generic(xdp_prog, skb) != XDP_PASS)
4912+
/* Dropped, remove from list */
4913+
list_del(&skb->list);
4914+
}
4915+
rcu_read_unlock();
4916+
preempt_enable();
4917+
}
4918+
4919+
rcu_read_lock();
4920+
#ifdef CONFIG_RPS
4921+
if (static_key_false(&rps_needed)) {
4922+
list_for_each_entry_safe(skb, next, head, list) {
4923+
struct rps_dev_flow voidflow, *rflow = &voidflow;
4924+
int cpu = get_rps_cpu(skb->dev, skb, &rflow);
4925+
4926+
if (cpu >= 0) {
4927+
enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
4928+
/* Handled, remove from list */
4929+
list_del(&skb->list);
4930+
}
4931+
}
4932+
}
4933+
#endif
4934+
__netif_receive_skb_list(head);
4935+
rcu_read_unlock();
4936+
}
4937+
48864938
/**
48874939
* netif_receive_skb - process receive buffer from network
48884940
* @skb: buffer to process
@@ -4910,20 +4962,19 @@ EXPORT_SYMBOL(netif_receive_skb);
49104962
* netif_receive_skb_list - process many receive buffers from network
49114963
* @head: list of skbs to process.
49124964
*
4913-
* For now, just calls netif_receive_skb() in a loop, ignoring the
4914-
* return value.
4965+
* Since return value of netif_receive_skb() is normally ignored, and
4966+
* wouldn't be meaningful for a list, this function returns void.
49154967
*
49164968
* This function may only be called from softirq context and interrupts
49174969
* should be enabled.
49184970
*/
49194971
void netif_receive_skb_list(struct list_head *head)
49204972
{
4921-
struct sk_buff *skb, *next;
4973+
struct sk_buff *skb;
49224974

49234975
list_for_each_entry(skb, head, list)
49244976
trace_netif_receive_skb_list_entry(skb);
4925-
list_for_each_entry_safe(skb, next, head, list)
4926-
netif_receive_skb_internal(skb);
4977+
netif_receive_skb_list_internal(head);
49274978
}
49284979
EXPORT_SYMBOL(netif_receive_skb_list);
49294980

0 commit comments

Comments
 (0)