Commit 9c94ae6b authored by Eric Dumazet's avatar Eric Dumazet Committed by Paolo Abeni
Browse files

net: make softnet_data.defer_count an atomic



This is preparation work to remove the softnet_data.defer_lock,
as it is contended on hosts with large number of cores.

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarJason Xing <kerneljasonxing@gmail.com>
Reviewed-by: default avatarKuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250928084934.3266948-2-edumazet@google.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 2c0592bd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3538,7 +3538,7 @@ struct softnet_data {

	/* Another possibly contended cache line */
	spinlock_t		defer_lock ____cacheline_aligned_in_smp;
	int			defer_count;
	atomic_t		defer_count;
	int			defer_ipi_scheduled;
	struct sk_buff		*defer_list;
	call_single_data_t	defer_csd;
+1 −1
Original line number Diff line number Diff line
@@ -6726,7 +6726,7 @@ static void skb_defer_free_flush(struct softnet_data *sd)
	spin_lock(&sd->defer_lock);
	skb = sd->defer_list;
	sd->defer_list = NULL;
	sd->defer_count = 0;
	atomic_set(&sd->defer_count, 0);
	spin_unlock(&sd->defer_lock);

	while (skb != NULL) {
+2 −4
Original line number Diff line number Diff line
@@ -7202,14 +7202,12 @@ nodefer: kfree_skb_napi_cache(skb);

	sd = &per_cpu(softnet_data, cpu);
	defer_max = READ_ONCE(net_hotdata.sysctl_skb_defer_max);
	if (READ_ONCE(sd->defer_count) >= defer_max)
	if (atomic_read(&sd->defer_count) >= defer_max)
		goto nodefer;

	spin_lock_bh(&sd->defer_lock);
	/* Send an IPI every time queue reaches half capacity. */
	kick = sd->defer_count == (defer_max >> 1);
	/* Paired with the READ_ONCE() few lines above */
	WRITE_ONCE(sd->defer_count, sd->defer_count + 1);
	kick = (atomic_inc_return(&sd->defer_count) - 1) == (defer_max >> 1);

	skb->next = sd->defer_list;
	/* Paired with READ_ONCE() in skb_defer_free_flush() */