diff options
Diffstat (limited to 'net/core/dev.c')
| -rw-r--r-- | net/core/dev.c | 16 | 
1 files changed, 10 insertions, 6 deletions
| diff --git a/net/core/dev.c b/net/core/dev.c index 74fd402d26dd..7ee9fecd3aff 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6923,12 +6923,16 @@ EXPORT_SYMBOL(napi_disable);   */  void napi_enable(struct napi_struct *n)  { -	BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state)); -	smp_mb__before_atomic(); -	clear_bit(NAPI_STATE_SCHED, &n->state); -	clear_bit(NAPI_STATE_NPSVC, &n->state); -	if (n->dev->threaded && n->thread) -		set_bit(NAPI_STATE_THREADED, &n->state); +	unsigned long val, new; + +	do { +		val = READ_ONCE(n->state); +		BUG_ON(!test_bit(NAPI_STATE_SCHED, &val)); + +		new = val & ~(NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC); +		if (n->dev->threaded && n->thread) +			new |= NAPIF_STATE_THREADED; +	} while (cmpxchg(&n->state, val, new) != val);  }  EXPORT_SYMBOL(napi_enable); | 
