diff options
| author | David S. Miller <davem@davemloft.net> | 2012-11-10 18:32:51 -0500 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2012-11-10 18:32:51 -0500 | 
| commit | d4185bbf62a5d8d777ee445db1581beb17882a07 (patch) | |
| tree | 024b0badbd7c970b1983be6d8c345cc4a290cb31 /include/linux/percpu-rwsem.h | |
| parent | c075b13098b399dc565b4d53f42047a8d40ed3ba (diff) | |
| parent | a375413311b39005ef281bfd71ae8f4e3df22e97 (diff) | |
| download | olio-linux-3.10-d4185bbf62a5d8d777ee445db1581beb17882a07.tar.xz olio-linux-3.10-d4185bbf62a5d8d777ee445db1581beb17882a07.zip  | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
	drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
Minor conflict between the BCM_CNIC define removal in net-next
and a bug fix added to net.  Based upon a conflict resolution
patch posted by Stephen Rothwell.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/percpu-rwsem.h')
| -rw-r--r-- | include/linux/percpu-rwsem.h | 28 | 
1 files changed, 11 insertions, 17 deletions
diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h index cf80f7e5277..250a4acddb2 100644 --- a/include/linux/percpu-rwsem.h +++ b/include/linux/percpu-rwsem.h @@ -12,34 +12,27 @@ struct percpu_rw_semaphore {  	struct mutex mtx;  }; +#define light_mb()	barrier() +#define heavy_mb()	synchronize_sched() +  static inline void percpu_down_read(struct percpu_rw_semaphore *p)  { -	rcu_read_lock(); +	rcu_read_lock_sched();  	if (unlikely(p->locked)) { -		rcu_read_unlock(); +		rcu_read_unlock_sched();  		mutex_lock(&p->mtx);  		this_cpu_inc(*p->counters);  		mutex_unlock(&p->mtx);  		return;  	}  	this_cpu_inc(*p->counters); -	rcu_read_unlock(); +	rcu_read_unlock_sched(); +	light_mb(); /* A, between read of p->locked and read of data, paired with D */  }  static inline void percpu_up_read(struct percpu_rw_semaphore *p)  { -	/* -	 * On X86, write operation in this_cpu_dec serves as a memory unlock -	 * barrier (i.e. memory accesses may be moved before the write, but -	 * no memory accesses are moved past the write). -	 * On other architectures this may not be the case, so we need smp_mb() -	 * there. -	 */ -#if defined(CONFIG_X86) && (!defined(CONFIG_X86_PPRO_FENCE) && !defined(CONFIG_X86_OOSTORE)) -	barrier(); -#else -	smp_mb(); -#endif +	light_mb(); /* B, between read of the data and write to p->counter, paired with C */  	this_cpu_dec(*p->counters);  } @@ -58,14 +51,15 @@ static inline void percpu_down_write(struct percpu_rw_semaphore *p)  {  	mutex_lock(&p->mtx);  	p->locked = true; -	synchronize_rcu(); +	synchronize_sched(); /* make sure that all readers exit the rcu_read_lock_sched region */  	while (__percpu_count(p->counters))  		msleep(1); -	smp_rmb(); /* paired with smp_mb() in percpu_sem_up_read() */ +	heavy_mb(); /* C, between read of p->counter and write to data, paired with B */  }  static inline void percpu_up_write(struct percpu_rw_semaphore *p)  { +	heavy_mb(); /* D, between write to data and write to p->locked, paired with A */  	p->locked = false;  	mutex_unlock(&p->mtx);  }  |