[lkml]   [2005]   [Aug]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
SubjectRe: [RFC] RT-patch update to remove the global pi_lock
OK, I'm looking for a second set of eyes (or third or more :-) to see if
there's a danger of a deadlock here.

The task->pi_lock is dependent on the order of locking, which I said was
proven to be true, otherwise there would be a deadlock.


Where lock L1 is owned by P1 which is blocked on L2 and so on.

The problem comes when we have to deal with this BKL. This lock is
special in that it can be grabbed and released and break this chain.
Mainly with semaphores, since BKL shouldn't be released when scheduling
where the old spin_locks were replaced. But since we replaced
semaphores with mutexes, the BKL starts to change the rules.

(Ingo, my last patch is flawed since it only covers the case of
semaphores, so please don't apply it, yet).

Now we can have:


Where there's a loop. The good news is that this only happens when P1
is about to release the BKL, otherwise it would be a real deadlock in
the kernel and not with the PI.

My fear of a deadlock is in the __up code. Where we have the locking
order of:


Is there someplace that can cause this to deadlock?

To deadlock, we need another process on another CPU to lock in the
following order:


Which I guess can happen and we would get a deadlock. This task could
be holding P1 and L1 and be waiting on P2 while the __up could have P2
and BKL and be waiting on P1.

So would this solve the problem with this deadlock? This would be in
pick_new_owner where the caller is the __up. (the P2->BKL-P1 side) This
is not a patch, but I put +'s at the added code.

trace_special_pid(waiter->ti->task->pid, waiter->ti->task->prio, 0);

check_pi_list_present(lock, waiter, old_owner);
new_owner = waiter->ti;
* The new owner is still blocked on this lock, so we
* must release the lock->wait_lock before grabing
* the new_owner lock.
* In this split second of releasing the lock, a high priority
* process could have come along and blocked as well.
waiter = plist_first_entry(&lock->wait_list, struct rt_mutex_waiter, list);
if (unlikely(waiter->ti != new_owner)) {
goto try_again;
+ /*
+ * Once again the BKL comes to play. Since the BKL can be grabbed and released
+ * out of the normal P1->L1->P2 order, there's a chance that someone has the
+ * BKL owner's lock and is waiting on the new owner lock.
+ */
+ if (unlikely(lock == &kernel_sem.lock)) {
+ if (!__raw_spin_trylock(&old_owner->task->pi_lock)) {
+ __raw_spin_unlock(&lock->wait_lock);
+ __raw_spin_unlock(&new_owner->task->pi_lock);
+ goto try_again;
+ }
+ } else

-- Steve

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at
Please read the FAQ at

 \ /
  Last update: 2005-08-30 17:03    [W:0.151 / U:1.496 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site