rwsem: skip initial trylock in rwsem_down_write_failed
We can skip the initial trylock in rwsem_down_write_failed() if there are known active lockers already, thus saving one likely-to-fail cmpxchg. Signed-off-by: Michel Lespinasse <walken@google.com> Reviewed-by: Peter Hurley <peter@hurleysoftware.com> Acked-by: Davidlohr Bueso <davidlohr.bueso@hp.com> Acked-by: Rik van Riel <riel@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
					parent
					
						
							
								a7d2c573ae
							
						
					
				
			
			
				commit
				
					
						9b0fc9c09f
					
				
			
		
					 1 changed files with 9 additions and 8 deletions
				
			
		
							
								
								
									
										17
									
								
								lib/rwsem.c
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								lib/rwsem.c
									
										
									
									
									
								
							|  | @ -216,14 +216,15 @@ struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem) | ||||||
| 	/* wait until we successfully acquire the lock */ | 	/* wait until we successfully acquire the lock */ | ||||||
| 	set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 	set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||||||
| 	while (true) { | 	while (true) { | ||||||
| 
 | 		if (!(count & RWSEM_ACTIVE_MASK)) { | ||||||
| 		/* Try acquiring the write lock. */ | 			/* Try acquiring the write lock. */ | ||||||
| 		count = RWSEM_ACTIVE_WRITE_BIAS; | 			count = RWSEM_ACTIVE_WRITE_BIAS; | ||||||
| 		if (!list_is_singular(&sem->wait_list)) | 			if (!list_is_singular(&sem->wait_list)) | ||||||
| 			count += RWSEM_WAITING_BIAS; | 				count += RWSEM_WAITING_BIAS; | ||||||
| 		if (cmpxchg(&sem->count, RWSEM_WAITING_BIAS, count) == | 			if (cmpxchg(&sem->count, RWSEM_WAITING_BIAS, count) == | ||||||
| 							RWSEM_WAITING_BIAS) | 							RWSEM_WAITING_BIAS) | ||||||
| 			break; | 				break; | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		raw_spin_unlock_irq(&sem->wait_lock); | 		raw_spin_unlock_irq(&sem->wait_lock); | ||||||
| 
 | 
 | ||||||
|  | @ -231,7 +232,7 @@ struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem) | ||||||
| 		do { | 		do { | ||||||
| 			schedule(); | 			schedule(); | ||||||
| 			set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 			set_task_state(tsk, TASK_UNINTERRUPTIBLE); | ||||||
| 		} while (sem->count & RWSEM_ACTIVE_MASK); | 		} while ((count = sem->count) & RWSEM_ACTIVE_MASK); | ||||||
| 
 | 
 | ||||||
| 		raw_spin_lock_irq(&sem->wait_lock); | 		raw_spin_lock_irq(&sem->wait_lock); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Michel Lespinasse
				Michel Lespinasse