Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3d492c2e authored by Omar Sandoval's avatar Omar Sandoval Committed by Jens Axboe
Browse files

blk-mq-sched: don't hold queue_lock when calling exit_icq



None of the other blk-mq elevator hooks are called with this lock held.
Additionally, it can lead to circular locking dependencies between
queue_lock and the private scheduler lock.

Reported-by: default avatarPaolo Valente <paolo.valente@linaro.org>
Signed-off-by: default avatarOmar Sandoval <osandov@fb.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent f6f94300
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -35,7 +35,10 @@ static void icq_free_icq_rcu(struct rcu_head *head)
	kmem_cache_free(icq->__rcu_icq_cache, icq);
}

/* Exit an icq. Called with both ioc and q locked. */
/*
 * Exit an icq. Called with both ioc and q locked for sq, only ioc locked for
 * mq.
 */
static void ioc_exit_icq(struct io_cq *icq)
{
	struct elevator_type *et = icq->q->elevator->type;
@@ -166,6 +169,7 @@ EXPORT_SYMBOL(put_io_context);
 */
void put_io_context_active(struct io_context *ioc)
{
	struct elevator_type *et;
	unsigned long flags;
	struct io_cq *icq;

@@ -184,6 +188,11 @@ void put_io_context_active(struct io_context *ioc)
	hlist_for_each_entry(icq, &ioc->icq_list, ioc_node) {
		if (icq->flags & ICQ_EXITED)
			continue;

		et = icq->q->elevator->type;
		if (et->uses_mq) {
			ioc_exit_icq(icq);
		} else {
			if (spin_trylock(icq->q->queue_lock)) {
				ioc_exit_icq(icq);
				spin_unlock(icq->q->queue_lock);
@@ -193,6 +202,7 @@ void put_io_context_active(struct io_context *ioc)
				goto retry;
			}
		}
	}
	spin_unlock_irqrestore(&ioc->lock, flags);

	put_io_context(ioc);