Message ID | 20241219150330.3159027-1-edumazet@google.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 05dd04b218f42c57a14e330fd8583995f141ed6b |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net-next] inetpeer: avoid false sharing in inet_peer_xrlim_allow() | expand |
Eric Dumazet wrote: > 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 <edumazet@google.com> Reviewed-by: Willem de Bruijn <willemb@google.com>
Hello: This patch was applied to netdev/net-next.git (main) by Jakub Kicinski <kuba@kernel.org>: On Thu, 19 Dec 2024 15:03:30 +0000 you wrote: > 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. > > [...] Here is the summary with links: - [net-next] inetpeer: avoid false sharing in inet_peer_xrlim_allow() https://git.kernel.org/netdev/net-next/c/05dd04b218f4 You are awesome, thank you!
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index e02484f4d22b8ea47cbaeed46c5fb0a7411462a1..b8b23a77ceb4f0f1a3d3adaacea2a7c59a7da3c9 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -246,23 +246,27 @@ void inet_putpeer(struct inet_peer *p) #define XRLIM_BURST_FACTOR 6 bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout) { - unsigned long now, token; + unsigned long now, token, otoken, delta; bool rc = false; if (!peer) return true; - token = peer->rate_tokens; + token = otoken = READ_ONCE(peer->rate_tokens); now = jiffies; - token += now - peer->rate_last; - peer->rate_last = now; - if (token > XRLIM_BURST_FACTOR * timeout) - token = XRLIM_BURST_FACTOR * timeout; + delta = now - READ_ONCE(peer->rate_last); + if (delta) { + WRITE_ONCE(peer->rate_last, now); + token += delta; + if (token > XRLIM_BURST_FACTOR * timeout) + token = XRLIM_BURST_FACTOR * timeout; + } if (token >= timeout) { token -= timeout; rc = true; } - peer->rate_tokens = token; + if (token != otoken) + WRITE_ONCE(peer->rate_tokens, token); return rc; } EXPORT_SYMBOL(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 <edumazet@google.com> --- net/ipv4/inetpeer.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)