public inbox for cgroups@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] blk-iocost: Pass gendisk to ioc_refresh_params
@ 2023-02-27 15:12 Breno Leitao
       [not found] ` <20230227151252.1411499-1-leitao-8fiUuRrzOP0dnm+yROfE0A@public.gmane.org>
  0 siblings, 1 reply; 3+ messages in thread
From: Breno Leitao @ 2023-02-27 15:12 UTC (permalink / raw)
  To: axboe-tSWWG44O7X1aa/9Udqfwiw, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA,
	linux-block-u79uwXL29TY76Z2rM5mHXA, hch-jcswGhMUV9g
  Cc: josef-DigfWCa+lFGyeJad7bwFQA, aherrmann-l3A5Bk7waGM,
	mkoutny-IBi9RG/b67k, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	leit-b10kYP2dOMg

Current kernel (d2980d8d826554fa6981d621e569a453787472f8) crashes
when blk_iocost_init for `nvme1` disk.

	BUG: kernel NULL pointer dereference, address: 0000000000000050
	#PF: supervisor read access in kernel mode
	#PF: error_code(0x0000) - not-present page

	blk_iocost_init (include/asm-generic/qspinlock.h:128
			 include/linux/spinlock.h:203
			 include/linux/spinlock_api_smp.h:158
			 include/linux/spinlock.h:400
			 block/blk-iocost.c:2884)
	ioc_qos_write (block/blk-iocost.c:3198)
	? kretprobe_perf_func (kernel/trace/trace_kprobe.c:1566)
	? kernfs_fop_write_iter (include/linux/slab.h:584 fs/kernfs/file.c:311)
	? __kmem_cache_alloc_node (mm/slab.h:? mm/slub.c:3452 mm/slub.c:3491)
	? _copy_from_iter (arch/x86/include/asm/uaccess_64.h:46
			   arch/x86/include/asm/uaccess_64.h:52
			   lib/iov_iter.c:183 lib/iov_iter.c:628)
	? kretprobe_dispatcher (kernel/trace/trace_kprobe.c:1693)
	cgroup_file_write (kernel/cgroup/cgroup.c:4061)
	kernfs_fop_write_iter (fs/kernfs/file.c:334)
	vfs_write (include/linux/fs.h:1849 fs/read_write.c:491
		   fs/read_write.c:584)
	ksys_write (fs/read_write.c:637)
	do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80)
	entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120)

This happens because ioc_refresh_params() is being called without
a properly initialized ioc->rqos, which is happening later in the callee
side.

ioc_refresh_params() -> ioc_autop_idx() tries to access
ioc->rqos.disk->queue but ioc->rqos.disk is NULL, causing the BUG above.

Create a function that is similar to ioc_refresh_params() but where the
"struct gendisk" could be passed as an explicit argument. This
function will be called when ioc->rqos.disk could not be trusted.

Fixes: ce57b558604e ("blk-rq-qos: make rq_qos_add and rq_qos_del more useful")

Signed-off-by: Breno Leitao <leitao-8fiUuRrzOP0dnm+yROfE0A@public.gmane.org>
---
 block/blk-iocost.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

---
Changelog
v1->v2: Pass the struct request_queue explictly to ioc_refresh_params()
v2->v3: Use struct gendisk instead of struct request_queue

diff --git a/block/blk-iocost.c b/block/blk-iocost.c
index ff534e9d92dc..9d24ddaf301d 100644
--- a/block/blk-iocost.c
+++ b/block/blk-iocost.c
@@ -800,7 +800,7 @@ static void ioc_refresh_period_us(struct ioc *ioc)
 	ioc_refresh_margins(ioc);
 }
 
-static int ioc_autop_idx(struct ioc *ioc)
+static int ioc_autop_idx(struct ioc *ioc, struct gendisk *disk)
 {
 	int idx = ioc->autop_idx;
 	const struct ioc_params *p = &autop[idx];
@@ -808,11 +808,11 @@ static int ioc_autop_idx(struct ioc *ioc)
 	u64 now_ns;
 
 	/* rotational? */
-	if (!blk_queue_nonrot(ioc->rqos.disk->queue))
+	if (!blk_queue_nonrot(disk->queue))
 		return AUTOP_HDD;
 
 	/* handle SATA SSDs w/ broken NCQ */
-	if (blk_queue_depth(ioc->rqos.disk->queue) == 1)
+	if (blk_queue_depth(disk->queue) == 1)
 		return AUTOP_SSD_QD1;
 
 	/* use one of the normal ssd sets */
@@ -901,14 +901,19 @@ static void ioc_refresh_lcoefs(struct ioc *ioc)
 		    &c[LCOEF_WPAGE], &c[LCOEF_WSEQIO], &c[LCOEF_WRANDIO]);
 }
 
-static bool ioc_refresh_params(struct ioc *ioc, bool force)
+/*
+ * struct gendisk is required as an argument because ioc->rqos.disk
+ * might not be properly initialized
+ */
+static bool _ioc_refresh_params(struct ioc *ioc, bool force,
+				struct gendisk *disk)
 {
 	const struct ioc_params *p;
 	int idx;
 
 	lockdep_assert_held(&ioc->lock);
 
-	idx = ioc_autop_idx(ioc);
+	idx = ioc_autop_idx(ioc, disk);
 	p = &autop[idx];
 
 	if (idx == ioc->autop_idx && !force)
@@ -939,6 +944,11 @@ static bool ioc_refresh_params(struct ioc *ioc, bool force)
 	return true;
 }
 
+static bool ioc_refresh_params(struct ioc *ioc, bool force)
+{
+	return _ioc_refresh_params(ioc, force, ioc->rqos.disk);
+}
+
 /*
  * When an iocg accumulates too much vtime or gets deactivated, we throw away
  * some vtime, which lowers the overall device utilization. As the exact amount
@@ -2880,7 +2890,7 @@ static int blk_iocost_init(struct gendisk *disk)
 
 	spin_lock_irq(&ioc->lock);
 	ioc->autop_idx = AUTOP_INVALID;
-	ioc_refresh_params(ioc, true);
+	_ioc_refresh_params(ioc, true, disk);
 	spin_unlock_irq(&ioc->lock);
 
 	/*
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v3] blk-iocost: Pass gendisk to ioc_refresh_params
       [not found] ` <20230227151252.1411499-1-leitao-8fiUuRrzOP0dnm+yROfE0A@public.gmane.org>
@ 2023-02-27 15:19   ` Christoph Hellwig
  2023-02-27 18:27   ` Tejun Heo
  1 sibling, 0 replies; 3+ messages in thread
From: Christoph Hellwig @ 2023-02-27 15:19 UTC (permalink / raw)
  To: Breno Leitao
  Cc: axboe-tSWWG44O7X1aa/9Udqfwiw, tj-DgEjT+Ai2ygdnm+yROfE0A,
	cgroups-u79uwXL29TY76Z2rM5mHXA,
	linux-block-u79uwXL29TY76Z2rM5mHXA, hch-jcswGhMUV9g,
	josef-DigfWCa+lFGyeJad7bwFQA, aherrmann-l3A5Bk7waGM,
	mkoutny-IBi9RG/b67k, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	leit-b10kYP2dOMg

Looks good:

Reviewed-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v3] blk-iocost: Pass gendisk to ioc_refresh_params
       [not found] ` <20230227151252.1411499-1-leitao-8fiUuRrzOP0dnm+yROfE0A@public.gmane.org>
  2023-02-27 15:19   ` Christoph Hellwig
@ 2023-02-27 18:27   ` Tejun Heo
  1 sibling, 0 replies; 3+ messages in thread
From: Tejun Heo @ 2023-02-27 18:27 UTC (permalink / raw)
  To: Breno Leitao
  Cc: axboe-tSWWG44O7X1aa/9Udqfwiw, cgroups-u79uwXL29TY76Z2rM5mHXA,
	linux-block-u79uwXL29TY76Z2rM5mHXA, hch-jcswGhMUV9g,
	josef-DigfWCa+lFGyeJad7bwFQA, aherrmann-l3A5Bk7waGM,
	mkoutny-IBi9RG/b67k, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	leit-b10kYP2dOMg

Hello,

A couple minor nitpicks:

Can you please add a short comment here too saying that @ioc->rqos.disk
isn't initialized yet when this function is called from the init path?

> +static int ioc_autop_idx(struct ioc *ioc, struct gendisk *disk)
>  {
>  	int idx = ioc->autop_idx;
>  	const struct ioc_params *p = &autop[idx];
> @@ -808,11 +808,11 @@ static int ioc_autop_idx(struct ioc *ioc)
>  	u64 now_ns;
>  
>  	/* rotational? */
> -	if (!blk_queue_nonrot(ioc->rqos.disk->queue))
> +	if (!blk_queue_nonrot(disk->queue))
>  		return AUTOP_HDD;
>  
>  	/* handle SATA SSDs w/ broken NCQ */
> -	if (blk_queue_depth(ioc->rqos.disk->queue) == 1)
> +	if (blk_queue_depth(disk->queue) == 1)
>  		return AUTOP_SSD_QD1;
>  
>  	/* use one of the normal ssd sets */
> @@ -901,14 +901,19 @@ static void ioc_refresh_lcoefs(struct ioc *ioc)
>  		    &c[LCOEF_WPAGE], &c[LCOEF_WSEQIO], &c[LCOEF_WRANDIO]);
>  }
>  
> -static bool ioc_refresh_params(struct ioc *ioc, bool force)
> +/*
> + * struct gendisk is required as an argument because ioc->rqos.disk
> + * might not be properly initialized
> + */

Here too, let's explicitly say when it's not initialized.

> +static bool _ioc_refresh_params(struct ioc *ioc, bool force,
> +				struct gendisk *disk)

Given that __ are about an order of magnitude more common in the kernel,
would you mind renaming it to __ioc_refresh_params() or e.g.
ioc_refresh_params_disk()?

Please feel free to add

 Acked-by: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-02-27 18:27 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-27 15:12 [PATCH v3] blk-iocost: Pass gendisk to ioc_refresh_params Breno Leitao
     [not found] ` <20230227151252.1411499-1-leitao-8fiUuRrzOP0dnm+yROfE0A@public.gmane.org>
2023-02-27 15:19   ` Christoph Hellwig
2023-02-27 18:27   ` Tejun Heo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox