diff options
| -rw-r--r-- | net/ipv4/inetpeer.c | 14 | 
1 files changed, 9 insertions, 5 deletions
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index dafbf2c98b2..90c5f0d1bcf 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -373,11 +373,14 @@ static int inet_peer_gc(struct inet_peer_base *base,  	while (stackptr > stack) {  		stackptr--;  		p = rcu_deref_locked(**stackptr, base); -		delta = (__u32)jiffies - p->dtime; -		if (atomic_read(&p->refcnt) == 0 && delta >= ttl && -		    atomic_cmpxchg(&p->refcnt, 0, -1) == 0) { -			p->gc_next = gchead; -			gchead = p; +		if (atomic_read(&p->refcnt) == 0) { +			smp_rmb(); +			delta = (__u32)jiffies - p->dtime; +			if (delta >= ttl && +			    atomic_cmpxchg(&p->refcnt, 0, -1) == 0) { +				p->gc_next = gchead; +				gchead = p; +			}  		}  	}  	while ((p = gchead) != NULL) { @@ -456,6 +459,7 @@ EXPORT_SYMBOL_GPL(inet_getpeer);  void inet_putpeer(struct inet_peer *p)  {  	p->dtime = (__u32)jiffies; +	smp_mb__before_atomic_dec();  	atomic_dec(&p->refcnt);  }  EXPORT_SYMBOL_GPL(inet_putpeer);  |