Allow sleepq_signal() to drop the lock.
Introduce SLEEPQ_DROP sleepq_signal() flag, allowing one to drop the sleep queue chain lock before returning. Reduced lock scope allows significantly reduce lock contention inside taskqueue_enqueue() for ZFS worker threads doing ~350K disk reads/s on 40-thread system. MFC after: 2 weeks Sponsored by: iXsystems, Inc.
This commit is contained in:
parent
520a2401a6
commit
6df35af4d8
@ -366,8 +366,7 @@ wakeup_one(const void *ident)
|
||||
int wakeup_swapper;
|
||||
|
||||
sleepq_lock(ident);
|
||||
wakeup_swapper = sleepq_signal(ident, SLEEPQ_SLEEP, 0, 0);
|
||||
sleepq_release(ident);
|
||||
wakeup_swapper = sleepq_signal(ident, SLEEPQ_SLEEP | SLEEPQ_DROP, 0, 0);
|
||||
if (wakeup_swapper)
|
||||
kick_proc0();
|
||||
}
|
||||
@ -378,9 +377,8 @@ wakeup_any(const void *ident)
|
||||
int wakeup_swapper;
|
||||
|
||||
sleepq_lock(ident);
|
||||
wakeup_swapper = sleepq_signal(ident, SLEEPQ_SLEEP | SLEEPQ_UNFAIR,
|
||||
0, 0);
|
||||
sleepq_release(ident);
|
||||
wakeup_swapper = sleepq_signal(ident, SLEEPQ_SLEEP | SLEEPQ_UNFAIR |
|
||||
SLEEPQ_DROP, 0, 0);
|
||||
if (wakeup_swapper)
|
||||
kick_proc0();
|
||||
}
|
||||
|
@ -927,8 +927,11 @@ sleepq_signal(const void *wchan, int flags, int pri, int queue)
|
||||
KASSERT(wchan != NULL, ("%s: invalid NULL wait channel", __func__));
|
||||
MPASS((queue >= 0) && (queue < NR_SLEEPQS));
|
||||
sq = sleepq_lookup(wchan);
|
||||
if (sq == NULL)
|
||||
if (sq == NULL) {
|
||||
if (flags & SLEEPQ_DROP)
|
||||
sleepq_release(wchan);
|
||||
return (0);
|
||||
}
|
||||
KASSERT(sq->sq_type == (flags & SLEEPQ_TYPE),
|
||||
("%s: mismatch between sleep/wakeup and cv_*", __func__));
|
||||
|
||||
@ -961,7 +964,8 @@ sleepq_signal(const void *wchan, int flags, int pri, int queue)
|
||||
}
|
||||
}
|
||||
MPASS(besttd != NULL);
|
||||
wakeup_swapper = sleepq_resume_thread(sq, besttd, pri, SRQ_HOLD);
|
||||
wakeup_swapper = sleepq_resume_thread(sq, besttd, pri,
|
||||
(flags & SLEEPQ_DROP) ? 0 : SRQ_HOLD);
|
||||
return (wakeup_swapper);
|
||||
}
|
||||
|
||||
|
@ -85,6 +85,7 @@ struct thread;
|
||||
#define SLEEPQ_LK 0x04 /* Used by a lockmgr. */
|
||||
#define SLEEPQ_INTERRUPTIBLE 0x100 /* Sleep is interruptible. */
|
||||
#define SLEEPQ_UNFAIR 0x200 /* Unfair wakeup order. */
|
||||
#define SLEEPQ_DROP 0x400 /* Return without lock held. */
|
||||
|
||||
void init_sleepqueues(void);
|
||||
int sleepq_abort(struct thread *td, int intrval);
|
||||
|
Loading…
Reference in New Issue
Block a user