mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-11-01 09:13:37 +00:00 
			
		
		
		
	futex: add double_unlock_hb()
Impact: cleanup The futex code uses double_lock_hb() which locks the hb->lock's in pointer value order. There is no parallel unlock routine, and the code unlocks them in name order, ignoring pointer value. This patch adds double_unlock_hb() to refactor the duplicated code segments. Build and boot tested on a 4 way Intel x86_64 workstation. Passes basic pthread_mutex and PI tests out of ltp/testcases/realtime. Signed-off-by: Darren Hart <dvhltc@us.ibm.com> Acked-by: Peter Zijlstra <peterz@infradead.org> Cc: Rusty Russell <rusty@rustcorp.com.au> LKML-Reference: <20090312075552.9856.48021.stgit@Aeon> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
		
							parent
							
								
									de87fcc124
								
							
						
					
					
						commit
						5eb3dc62fc
					
				
					 1 changed files with 17 additions and 12 deletions
				
			
		| 
						 | 
				
			
			@ -690,6 +690,19 @@ double_lock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
double_unlock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2)
 | 
			
		||||
{
 | 
			
		||||
	if (hb1 <= hb2) {
 | 
			
		||||
		spin_unlock(&hb2->lock);
 | 
			
		||||
		if (hb1 < hb2)
 | 
			
		||||
			spin_unlock(&hb1->lock);
 | 
			
		||||
	} else { /* hb1 > hb2 */
 | 
			
		||||
		spin_unlock(&hb1->lock);
 | 
			
		||||
		spin_unlock(&hb2->lock);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Wake up waiters matching bitset queued on this futex (uaddr).
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -767,9 +780,7 @@ retry:
 | 
			
		|||
	if (unlikely(op_ret < 0)) {
 | 
			
		||||
		u32 dummy;
 | 
			
		||||
 | 
			
		||||
		spin_unlock(&hb1->lock);
 | 
			
		||||
		if (hb1 != hb2)
 | 
			
		||||
			spin_unlock(&hb2->lock);
 | 
			
		||||
		double_unlock_hb(hb1, hb2);
 | 
			
		||||
 | 
			
		||||
#ifndef CONFIG_MMU
 | 
			
		||||
		/*
 | 
			
		||||
| 
						 | 
				
			
			@ -833,9 +844,7 @@ retry:
 | 
			
		|||
		ret += op_ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	spin_unlock(&hb1->lock);
 | 
			
		||||
	if (hb1 != hb2)
 | 
			
		||||
		spin_unlock(&hb2->lock);
 | 
			
		||||
	double_unlock_hb(hb1, hb2);
 | 
			
		||||
out_put_keys:
 | 
			
		||||
	put_futex_key(fshared, &key2);
 | 
			
		||||
out_put_key1:
 | 
			
		||||
| 
						 | 
				
			
			@ -876,9 +885,7 @@ retry:
 | 
			
		|||
		ret = get_futex_value_locked(&curval, uaddr1);
 | 
			
		||||
 | 
			
		||||
		if (unlikely(ret)) {
 | 
			
		||||
			spin_unlock(&hb1->lock);
 | 
			
		||||
			if (hb1 != hb2)
 | 
			
		||||
				spin_unlock(&hb2->lock);
 | 
			
		||||
			double_unlock_hb(hb1, hb2);
 | 
			
		||||
 | 
			
		||||
			put_futex_key(fshared, &key2);
 | 
			
		||||
			put_futex_key(fshared, &key1);
 | 
			
		||||
| 
						 | 
				
			
			@ -925,9 +932,7 @@ retry:
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
out_unlock:
 | 
			
		||||
	spin_unlock(&hb1->lock);
 | 
			
		||||
	if (hb1 != hb2)
 | 
			
		||||
		spin_unlock(&hb2->lock);
 | 
			
		||||
	double_unlock_hb(hb1, hb2);
 | 
			
		||||
 | 
			
		||||
	/* drop_futex_key_refs() must be called outside the spinlocks. */
 | 
			
		||||
	while (--drop_count >= 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue