On Fri, Nov 12, 2021 at 10:44 AM Jens Axboe <axboe@xxxxxxxxx> wrote: > > Alright, give this one a go if you can. Against -git, but will apply to > 5.15 as well. Works. Thank you very much. https://jira.mariadb.org/browse/MDEV-26674?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=205599#comment-205599 Tested-by: Marko Mäkelä <marko.makela@xxxxxxxxxxx> > > > diff --git a/fs/io-wq.c b/fs/io-wq.c > index afd955d53db9..88202de519f6 100644 > --- a/fs/io-wq.c > +++ b/fs/io-wq.c > @@ -423,9 +423,10 @@ static inline unsigned int io_get_work_hash(struct io_wq_work *work) > return work->flags >> IO_WQ_HASH_SHIFT; > } > > -static void io_wait_on_hash(struct io_wqe *wqe, unsigned int hash) > +static bool io_wait_on_hash(struct io_wqe *wqe, unsigned int hash) > { > struct io_wq *wq = wqe->wq; > + bool ret = false; > > spin_lock_irq(&wq->hash->wait.lock); > if (list_empty(&wqe->wait.entry)) { > @@ -433,9 +434,11 @@ static void io_wait_on_hash(struct io_wqe *wqe, unsigned int hash) > if (!test_bit(hash, &wq->hash->map)) { > __set_current_state(TASK_RUNNING); > list_del_init(&wqe->wait.entry); > + ret = true; > } > } > spin_unlock_irq(&wq->hash->wait.lock); > + return ret; > } > > 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, > } > > if (stall_hash != -1U) { > + bool unstalled; > + > /* > * Set this before dropping the lock to avoid racing with new > * work being added and clearing the stalled bit. > */ > set_bit(IO_ACCT_STALLED_BIT, &acct->flags); > raw_spin_unlock(&wqe->lock); > - io_wait_on_hash(wqe, stall_hash); > + unstalled = io_wait_on_hash(wqe, stall_hash); > raw_spin_lock(&wqe->lock); > + if (unstalled) { > + clear_bit(IO_ACCT_STALLED_BIT, &acct->flags); > + if (wq_has_sleeper(&wqe->wq->hash->wait)) > + wake_up(&wqe->wq->hash->wait); > + } > } > > return NULL; > @@ -564,8 +574,11 @@ static void io_worker_handle_work(struct io_worker *worker) > io_wqe_enqueue(wqe, linked); > > if (hash != -1U && !next_hashed) { > + /* serialize hash clear with wake_up() */ > + spin_lock_irq(&wq->hash->wait.lock); > clear_bit(hash, &wq->hash->map); > clear_bit(IO_ACCT_STALLED_BIT, &acct->flags); > + spin_unlock_irq(&wq->hash->wait.lock); > if (wq_has_sleeper(&wq->hash->wait)) > wake_up(&wq->hash->wait); > raw_spin_lock(&wqe->lock); > > -- > Jens Axboe >