svn commit: r279583 - stable/10/sys/kern
Konstantin Belousov
kib at FreeBSD.org
Wed Mar 4 09:29:26 UTC 2015
Author: kib
Date: Wed Mar 4 09:29:25 2015
New Revision: 279583
URL: https://svnweb.freebsd.org/changeset/base/279583
Log:
MFC r279282:
When unlocking a contested PI pthread mutex, if the queue of waiters
is empty, look up the umtx_pi and disown it if the current thread owns it.
Modified:
stable/10/sys/kern/kern_umtx.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/kern/kern_umtx.c
==============================================================================
--- stable/10/sys/kern/kern_umtx.c Wed Mar 4 09:17:03 2015 (r279582)
+++ stable/10/sys/kern/kern_umtx.c Wed Mar 4 09:29:25 2015 (r279583)
@@ -1810,6 +1810,19 @@ umtx_pi_setowner(struct umtx_pi *pi, str
TAILQ_INSERT_TAIL(&uq_owner->uq_pi_contested, pi, pi_link);
}
+
+/*
+ * Disown a PI mutex, and remove it from the owned list.
+ */
+static void
+umtx_pi_disown(struct umtx_pi *pi)
+{
+
+ mtx_assert(&umtx_lock, MA_OWNED);
+ TAILQ_REMOVE(&pi->pi_owner->td_umtxq->uq_pi_contested, pi, pi_link);
+ pi->pi_owner = NULL;
+}
+
/*
* Claim ownership of a PI mutex.
*/
@@ -2226,8 +2239,7 @@ do_unlock_pi(struct thread *td, struct u
return (EPERM);
}
uq_me = curthread->td_umtxq;
- pi->pi_owner = NULL;
- TAILQ_REMOVE(&uq_me->uq_pi_contested, pi, pi_link);
+ umtx_pi_disown(pi);
/* get highest priority thread which is still sleeping. */
uq_first = TAILQ_FIRST(&pi->pi_blocked);
while (uq_first != NULL &&
@@ -2248,6 +2260,25 @@ do_unlock_pi(struct thread *td, struct u
mtx_unlock_spin(&umtx_lock);
if (uq_first)
umtxq_signal_thread(uq_first);
+ } else {
+ pi = umtx_pi_lookup(&key);
+ /*
+ * A umtx_pi can exist if a signal or timeout removed the
+ * last waiter from the umtxq, but there is still
+ * a thread in do_lock_pi() holding the umtx_pi.
+ */
+ if (pi != NULL) {
+ /*
+ * The umtx_pi can be unowned, such as when a thread
+ * has just entered do_lock_pi(), allocated the
+ * umtx_pi, and unlocked the umtxq.
+ * If the current thread owns it, it must disown it.
+ */
+ mtx_lock_spin(&umtx_lock);
+ if (pi->pi_owner == td)
+ umtx_pi_disown(pi);
+ mtx_unlock_spin(&umtx_lock);
+ }
}
umtxq_unlock(&key);
More information about the svn-src-stable-10
mailing list