87 lines
2.6 KiB
Diff
87 lines
2.6 KiB
Diff
--- sys/kern/subr_epoch.c.orig
|
|
+++ sys/kern/subr_epoch.c
|
|
@@ -325,24 +325,20 @@
|
|
*/
|
|
critical_enter();
|
|
thread_unlock(td);
|
|
- owner = turnstile_lock(ts, &lock);
|
|
- /*
|
|
- * The owner pointer indicates that the lock succeeded. Only
|
|
- * in case we hold the lock and the turnstile we locked is still
|
|
- * the one that curwaittd is blocked on can we continue. Otherwise
|
|
- * The turnstile pointer has been changed out from underneath
|
|
- * us, as in the case where the lock holder has signalled curwaittd,
|
|
- * and we need to continue.
|
|
- */
|
|
- if (owner != NULL && ts == curwaittd->td_blocked) {
|
|
- MPASS(TD_IS_INHIBITED(curwaittd) && TD_ON_LOCK(curwaittd));
|
|
- critical_exit();
|
|
- turnstile_wait(ts, owner, curwaittd->td_tsqueue);
|
|
- counter_u64_add(turnstile_count, 1);
|
|
- thread_lock(td);
|
|
- return;
|
|
- } else if (owner != NULL)
|
|
+
|
|
+ if (turnstile_lock(ts, &lock, &owner)) {
|
|
+ if (ts == curwaittd->td_blocked) {
|
|
+ MPASS(TD_IS_INHIBITED(curwaittd) &&
|
|
+ TD_ON_LOCK(curwaittd));
|
|
+ critical_exit();
|
|
+ turnstile_wait(ts, owner,
|
|
+ curwaittd->td_tsqueue);
|
|
+ counter_u64_add(turnstile_count, 1);
|
|
+ thread_lock(td);
|
|
+ return;
|
|
+ }
|
|
turnstile_unlock(ts, lock);
|
|
+ }
|
|
thread_lock(td);
|
|
critical_exit();
|
|
KASSERT(td->td_locks == locksheld,
|
|
--- sys/kern/subr_turnstile.c.orig
|
|
+++ sys/kern/subr_turnstile.c
|
|
@@ -566,14 +566,15 @@
|
|
return (ts);
|
|
}
|
|
|
|
-struct thread *
|
|
-turnstile_lock(struct turnstile *ts, struct lock_object **lockp)
|
|
+bool
|
|
+turnstile_lock(struct turnstile *ts, struct lock_object **lockp,
|
|
+ struct thread **tdp)
|
|
{
|
|
struct turnstile_chain *tc;
|
|
struct lock_object *lock;
|
|
|
|
if ((lock = ts->ts_lockobj) == NULL)
|
|
- return (NULL);
|
|
+ return (false);
|
|
tc = TC_LOOKUP(lock);
|
|
mtx_lock_spin(&tc->tc_lock);
|
|
mtx_lock_spin(&ts->ts_lock);
|
|
@@ -580,10 +581,11 @@
|
|
if (__predict_false(lock != ts->ts_lockobj)) {
|
|
mtx_unlock_spin(&tc->tc_lock);
|
|
mtx_unlock_spin(&ts->ts_lock);
|
|
- return (NULL);
|
|
+ return (false);
|
|
}
|
|
*lockp = lock;
|
|
- return (ts->ts_owner);
|
|
+ *tdp = ts->ts_owner;
|
|
+ return (true);
|
|
}
|
|
|
|
void
|
|
--- sys/sys/turnstile.h.orig
|
|
+++ sys/sys/turnstile.h
|
|
@@ -100,7 +100,8 @@
|
|
struct turnstile *turnstile_trywait(struct lock_object *);
|
|
void turnstile_unpend(struct turnstile *);
|
|
void turnstile_wait(struct turnstile *, struct thread *, int);
|
|
-struct thread *turnstile_lock(struct turnstile *, struct lock_object **);
|
|
+bool turnstile_lock(struct turnstile *, struct lock_object **,
|
|
+ struct thread **);
|
|
void turnstile_unlock(struct turnstile *, struct lock_object *);
|
|
void turnstile_assert(struct turnstile *);
|
|
#endif /* _KERNEL */
|