Skip to content

Commit 2b7196a

Browse files
committed
Merge tag 'io_uring-5.16-2021-11-13' of git://git.kernel.dk/linux-block
Pull io_uring fix from Jens Axboe: "Just a single fix here for a buffered write hash stall, which is also affecting stable" * tag 'io_uring-5.16-2021-11-13' of git://git.kernel.dk/linux-block: io-wq: serialize hash clear with wakeup
2 parents c8103c2 + d3e3c10 commit 2b7196a

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

fs/io-wq.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,19 +423,22 @@ static inline unsigned int io_get_work_hash(struct io_wq_work *work)
423423
return work->flags >> IO_WQ_HASH_SHIFT;
424424
}
425425

426-
static void io_wait_on_hash(struct io_wqe *wqe, unsigned int hash)
426+
static bool io_wait_on_hash(struct io_wqe *wqe, unsigned int hash)
427427
{
428428
struct io_wq *wq = wqe->wq;
429+
bool ret = false;
429430

430431
spin_lock_irq(&wq->hash->wait.lock);
431432
if (list_empty(&wqe->wait.entry)) {
432433
__add_wait_queue(&wq->hash->wait, &wqe->wait);
433434
if (!test_bit(hash, &wq->hash->map)) {
434435
__set_current_state(TASK_RUNNING);
435436
list_del_init(&wqe->wait.entry);
437+
ret = true;
436438
}
437439
}
438440
spin_unlock_irq(&wq->hash->wait.lock);
441+
return ret;
439442
}
440443

441444
static struct io_wq_work *io_get_next_work(struct io_wqe_acct *acct,
@@ -475,14 +478,21 @@ static struct io_wq_work *io_get_next_work(struct io_wqe_acct *acct,
475478
}
476479

477480
if (stall_hash != -1U) {
481+
bool unstalled;
482+
478483
/*
479484
* Set this before dropping the lock to avoid racing with new
480485
* work being added and clearing the stalled bit.
481486
*/
482487
set_bit(IO_ACCT_STALLED_BIT, &acct->flags);
483488
raw_spin_unlock(&wqe->lock);
484-
io_wait_on_hash(wqe, stall_hash);
489+
unstalled = io_wait_on_hash(wqe, stall_hash);
485490
raw_spin_lock(&wqe->lock);
491+
if (unstalled) {
492+
clear_bit(IO_ACCT_STALLED_BIT, &acct->flags);
493+
if (wq_has_sleeper(&wqe->wq->hash->wait))
494+
wake_up(&wqe->wq->hash->wait);
495+
}
486496
}
487497

488498
return NULL;
@@ -564,8 +574,11 @@ static void io_worker_handle_work(struct io_worker *worker)
564574
io_wqe_enqueue(wqe, linked);
565575

566576
if (hash != -1U && !next_hashed) {
577+
/* serialize hash clear with wake_up() */
578+
spin_lock_irq(&wq->hash->wait.lock);
567579
clear_bit(hash, &wq->hash->map);
568580
clear_bit(IO_ACCT_STALLED_BIT, &acct->flags);
581+
spin_unlock_irq(&wq->hash->wait.lock);
569582
if (wq_has_sleeper(&wq->hash->wait))
570583
wake_up(&wq->hash->wait);
571584
raw_spin_lock(&wqe->lock);

0 commit comments

Comments
 (0)