Skip to content

Commit a9b204d

Browse files
edumazetdavem330
authored andcommitted
tcp: tsq: avoid one atomic in tcp_wfree()
Under high load, tcp_wfree() has an atomic operation trying to schedule a tasklet over and over. We can schedule it only if our per cpu list was empty. Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b223feb commit a9b204d

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

net/ipv4/tcp_output.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,7 @@ void tcp_wfree(struct sk_buff *skb)
880880

881881
for (oval = READ_ONCE(tp->tsq_flags);; oval = nval) {
882882
struct tsq_tasklet *tsq;
883+
bool empty;
883884

884885
if (!(oval & TSQF_THROTTLED) || (oval & TSQF_QUEUED))
885886
goto out;
@@ -892,8 +893,10 @@ void tcp_wfree(struct sk_buff *skb)
892893
/* queue this socket to tasklet queue */
893894
local_irq_save(flags);
894895
tsq = this_cpu_ptr(&tsq_tasklet);
896+
empty = list_empty(&tsq->head);
895897
list_add(&tp->tsq_node, &tsq->head);
896-
tasklet_schedule(&tsq->tasklet);
898+
if (empty)
899+
tasklet_schedule(&tsq->tasklet);
897900
local_irq_restore(flags);
898901
return;
899902
}

0 commit comments

Comments
 (0)