diff options
author | David S. Miller <davem@davemloft.net> | 2016-09-23 06:46:57 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-09-23 06:46:57 -0400 |
commit | d6989d4bbe6c4d1c2a76696833a07f044e85694d (patch) | |
tree | 2d9a70d0feee4d4a20568be1b39a961fa0d27d81 /net/ipv4/route.c | |
parent | 0364a8824c020f12e2d5e9fad963685b58f7574e (diff) | |
parent | b1f2beb87bb034bb209773807994279f90cace78 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r-- | net/ipv4/route.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index b52496fd5107..654a9af20136 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -476,12 +476,18 @@ u32 ip_idents_reserve(u32 hash, int segs) atomic_t *p_id = ip_idents + hash % IP_IDENTS_SZ; u32 old = ACCESS_ONCE(*p_tstamp); u32 now = (u32)jiffies; - u32 delta = 0; + u32 new, delta = 0; if (old != now && cmpxchg(p_tstamp, old, now) == old) delta = prandom_u32_max(now - old); - return atomic_add_return(segs + delta, p_id) - segs; + /* Do not use atomic_add_return() as it makes UBSAN unhappy */ + do { + old = (u32)atomic_read(p_id); + new = old + delta + segs; + } while (atomic_cmpxchg(p_id, old, new) != old); + + return new - segs; } EXPORT_SYMBOL(ip_idents_reserve); |