Skip to content

Commit 05dd04b

Browse files
edumazetkuba-moo
authored andcommitted
inetpeer: avoid false sharing in inet_peer_xrlim_allow()
Under DOS, inet_peer_xrlim_allow() might be called millions of times per second from different cpus. Make sure to write over peer->rate_tokens and peer->rate_last only when really needed. Note the inherent races of this function are still there, we do not care of precise ICMP rate limiting. Signed-off-by: Eric Dumazet <[email protected]> Reviewed-by: Willem de Bruijn <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 710aebd commit 05dd04b

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

net/ipv4/inetpeer.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -246,23 +246,27 @@ void inet_putpeer(struct inet_peer *p)
246246
#define XRLIM_BURST_FACTOR 6
247247
bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout)
248248
{
249-
unsigned long now, token;
249+
unsigned long now, token, otoken, delta;
250250
bool rc = false;
251251

252252
if (!peer)
253253
return true;
254254

255-
token = peer->rate_tokens;
255+
token = otoken = READ_ONCE(peer->rate_tokens);
256256
now = jiffies;
257-
token += now - peer->rate_last;
258-
peer->rate_last = now;
259-
if (token > XRLIM_BURST_FACTOR * timeout)
260-
token = XRLIM_BURST_FACTOR * timeout;
257+
delta = now - READ_ONCE(peer->rate_last);
258+
if (delta) {
259+
WRITE_ONCE(peer->rate_last, now);
260+
token += delta;
261+
if (token > XRLIM_BURST_FACTOR * timeout)
262+
token = XRLIM_BURST_FACTOR * timeout;
263+
}
261264
if (token >= timeout) {
262265
token -= timeout;
263266
rc = true;
264267
}
265-
peer->rate_tokens = token;
268+
if (token != otoken)
269+
WRITE_ONCE(peer->rate_tokens, token);
266270
return rc;
267271
}
268272
EXPORT_SYMBOL(inet_peer_xrlim_allow);

0 commit comments

Comments
 (0)