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

Commit 5d7f5ce1 authored by Jens Axboe's avatar Jens Axboe
Browse files

cfq-iosched: don't call wbt_disable_default() with IRQs disabled



wbt_disable_default() calls del_timer_sync() to wait for the wbt
timer to finish before disabling throttling. We can't do this with
IRQs disable. This fixes a lockdep splat on boot, if non-root
cgroups are used.

Reported-by: default avatarGabriel C <nix.or.die@gmail.com>
Fixes: 87760e5e ("block: hook up writeback throttling")
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent eeeefd41
Loading
Loading
Loading
Loading
+13 −12
Original line number Original line Diff line number Diff line
@@ -3758,7 +3758,7 @@ static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
}
}


#ifdef CONFIG_CFQ_GROUP_IOSCHED
#ifdef CONFIG_CFQ_GROUP_IOSCHED
static void check_blkcg_changed(struct cfq_io_cq *cic, struct bio *bio)
static bool check_blkcg_changed(struct cfq_io_cq *cic, struct bio *bio)
{
{
	struct cfq_data *cfqd = cic_to_cfqd(cic);
	struct cfq_data *cfqd = cic_to_cfqd(cic);
	struct cfq_queue *cfqq;
	struct cfq_queue *cfqq;
@@ -3775,15 +3775,7 @@ static void check_blkcg_changed(struct cfq_io_cq *cic, struct bio *bio)
	 * spuriously on a newly created cic but there's no harm.
	 * spuriously on a newly created cic but there's no harm.
	 */
	 */
	if (unlikely(!cfqd) || likely(cic->blkcg_serial_nr == serial_nr))
	if (unlikely(!cfqd) || likely(cic->blkcg_serial_nr == serial_nr))
		return;
		return nonroot_cg;

	/*
	 * If we have a non-root cgroup, we can depend on that to
	 * do proper throttling of writes. Turn off wbt for that
	 * case, if it was enabled by default.
	 */
	if (nonroot_cg)
		wbt_disable_default(cfqd->queue);


	/*
	/*
	 * Drop reference to queues.  New queues will be assigned in new
	 * Drop reference to queues.  New queues will be assigned in new
@@ -3804,9 +3796,13 @@ static void check_blkcg_changed(struct cfq_io_cq *cic, struct bio *bio)
	}
	}


	cic->blkcg_serial_nr = serial_nr;
	cic->blkcg_serial_nr = serial_nr;
	return nonroot_cg;
}
}
#else
#else
static inline void check_blkcg_changed(struct cfq_io_cq *cic, struct bio *bio) { }
static inline bool check_blkcg_changed(struct cfq_io_cq *cic, struct bio *bio)
{
	return false;
}
#endif  /* CONFIG_CFQ_GROUP_IOSCHED */
#endif  /* CONFIG_CFQ_GROUP_IOSCHED */


static struct cfq_queue **
static struct cfq_queue **
@@ -4448,11 +4444,12 @@ cfq_set_request(struct request_queue *q, struct request *rq, struct bio *bio,
	const int rw = rq_data_dir(rq);
	const int rw = rq_data_dir(rq);
	const bool is_sync = rq_is_sync(rq);
	const bool is_sync = rq_is_sync(rq);
	struct cfq_queue *cfqq;
	struct cfq_queue *cfqq;
	bool disable_wbt;


	spin_lock_irq(q->queue_lock);
	spin_lock_irq(q->queue_lock);


	check_ioprio_changed(cic, bio);
	check_ioprio_changed(cic, bio);
	check_blkcg_changed(cic, bio);
	disable_wbt = check_blkcg_changed(cic, bio);
new_queue:
new_queue:
	cfqq = cic_to_cfqq(cic, is_sync);
	cfqq = cic_to_cfqq(cic, is_sync);
	if (!cfqq || cfqq == &cfqd->oom_cfqq) {
	if (!cfqq || cfqq == &cfqd->oom_cfqq) {
@@ -4488,6 +4485,10 @@ cfq_set_request(struct request_queue *q, struct request *rq, struct bio *bio,
	rq->elv.priv[0] = cfqq;
	rq->elv.priv[0] = cfqq;
	rq->elv.priv[1] = cfqq->cfqg;
	rq->elv.priv[1] = cfqq->cfqg;
	spin_unlock_irq(q->queue_lock);
	spin_unlock_irq(q->queue_lock);

	if (disable_wbt)
		wbt_disable_default(q);

	return 0;
	return 0;
}
}