mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-16 11:32:41 +00:00
sbitmap: optimize wakeup check
Even if we have no waiters on any of the sbitmap_queue wait states, we still have to loop every entry to check. We do this for every IO, so the cost adds up. Shift a bit of the cost to the slow path, when we actually have waiters. Wrap prepare_to_wait_exclusive() and finish_wait(), so we can maintain an internal count of how many are currently active. Then we can simply check this count in sbq_wake_ptr() and not have to loop if we don't have any sleepers. Convert the two users of sbitmap with waiting, blk-mq-tag and iSCSI. Reviewed-by: Omar Sandoval <osandov@fb.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
ea86ea2cdc
commit
5d2ee7122c
4 changed files with 74 additions and 11 deletions
|
@ -394,6 +394,7 @@ int sbitmap_queue_init_node(struct sbitmap_queue *sbq, unsigned int depth,
|
|||
sbq->min_shallow_depth = UINT_MAX;
|
||||
sbq->wake_batch = sbq_calc_wake_batch(sbq, depth);
|
||||
atomic_set(&sbq->wake_index, 0);
|
||||
atomic_set(&sbq->ws_active, 0);
|
||||
|
||||
sbq->ws = kzalloc_node(SBQ_WAIT_QUEUES * sizeof(*sbq->ws), flags, node);
|
||||
if (!sbq->ws) {
|
||||
|
@ -509,6 +510,9 @@ static struct sbq_wait_state *sbq_wake_ptr(struct sbitmap_queue *sbq)
|
|||
{
|
||||
int i, wake_index;
|
||||
|
||||
if (!atomic_read(&sbq->ws_active))
|
||||
return NULL;
|
||||
|
||||
wake_index = atomic_read(&sbq->wake_index);
|
||||
for (i = 0; i < SBQ_WAIT_QUEUES; i++) {
|
||||
struct sbq_wait_state *ws = &sbq->ws[wake_index];
|
||||
|
@ -634,6 +638,7 @@ void sbitmap_queue_show(struct sbitmap_queue *sbq, struct seq_file *m)
|
|||
|
||||
seq_printf(m, "wake_batch=%u\n", sbq->wake_batch);
|
||||
seq_printf(m, "wake_index=%d\n", atomic_read(&sbq->wake_index));
|
||||
seq_printf(m, "ws_active=%d\n", atomic_read(&sbq->ws_active));
|
||||
|
||||
seq_puts(m, "ws={\n");
|
||||
for (i = 0; i < SBQ_WAIT_QUEUES; i++) {
|
||||
|
@ -649,3 +654,26 @@ void sbitmap_queue_show(struct sbitmap_queue *sbq, struct seq_file *m)
|
|||
seq_printf(m, "min_shallow_depth=%u\n", sbq->min_shallow_depth);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sbitmap_queue_show);
|
||||
|
||||
void sbitmap_prepare_to_wait(struct sbitmap_queue *sbq,
|
||||
struct sbq_wait_state *ws,
|
||||
struct sbq_wait *sbq_wait, int state)
|
||||
{
|
||||
if (!sbq_wait->accounted) {
|
||||
atomic_inc(&sbq->ws_active);
|
||||
sbq_wait->accounted = 1;
|
||||
}
|
||||
prepare_to_wait_exclusive(&ws->wait, &sbq_wait->wait, state);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sbitmap_prepare_to_wait);
|
||||
|
||||
void sbitmap_finish_wait(struct sbitmap_queue *sbq, struct sbq_wait_state *ws,
|
||||
struct sbq_wait *sbq_wait)
|
||||
{
|
||||
finish_wait(&ws->wait, &sbq_wait->wait);
|
||||
if (sbq_wait->accounted) {
|
||||
atomic_dec(&sbq->ws_active);
|
||||
sbq_wait->accounted = 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sbitmap_finish_wait);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue