Skip to content

Commit

Permalink
MFC r350310:
Browse files Browse the repository at this point in the history
Fix the turnstile_lock() KPI.
  • Loading branch information
markjdb committed Jul 27, 2019
1 parent fcbcaeb commit 5a909d9
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 25 deletions.
32 changes: 13 additions & 19 deletions sys/kern/subr_epoch.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,26 +440,20 @@ epoch_block_handler_preempt(struct ck_epoch *global __unused,
*/
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,
Expand Down
12 changes: 7 additions & 5 deletions sys/kern/subr_turnstile.c
Original file line number Diff line number Diff line change
Expand Up @@ -566,24 +566,26 @@ turnstile_trywait(struct lock_object *lock)
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);
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
Expand Down
3 changes: 2 additions & 1 deletion sys/sys/turnstile.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ int turnstile_signal(struct turnstile *, int);
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 */
Expand Down

0 comments on commit 5a909d9

Please sign in to comment.