block/mq-deadline.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
in dd_finish_request(), per_prio points to a rq->elv.priv[0], which could be
free memory if an in-flight requests completes after its associated scheduler
has been freed
Signed-off-by: Elijah Wright <git@elijahs.space>
---
block/mq-deadline.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/block/mq-deadline.c b/block/mq-deadline.c
index 2edf1cac06d5..4d7b21b144d3 100644
--- a/block/mq-deadline.c
+++ b/block/mq-deadline.c
@@ -751,13 +751,15 @@ static void dd_finish_request(struct request *rq)
{
struct dd_per_prio *per_prio = rq->elv.priv[0];
- /*
- * The block layer core may call dd_finish_request() without having
- * called dd_insert_requests(). Skip requests that bypassed I/O
- * scheduling. See also blk_mq_request_bypass_insert().
- */
- if (per_prio)
- atomic_inc(&per_prio->stats.completed);
+ if (rq->q->elevator) {
+ /*
+ * The block layer core may call dd_finish_request() without having
+ * called dd_insert_requests(). Skip requests that bypassed I/O
+ * scheduling. See also blk_mq_request_bypass_insert().
+ */
+ if (per_prio)
+ atomic_inc(&per_prio->stats.completed);
+ }
}
static bool dd_has_work_for_prio(struct dd_per_prio *per_prio)
--
2.43.0
On 6/17/25 1:56 PM, Elijah Wright wrote: > in dd_finish_request(), per_prio points to a rq->elv.priv[0], which could be > free memory if an in-flight requests completes after its associated scheduler > has been freed > > Signed-off-by: Elijah Wright <git@elijahs.space> > --- > block/mq-deadline.c | 16 +++++++++------- > 1 file changed, 9 insertions(+), 7 deletions(-) > > diff --git a/block/mq-deadline.c b/block/mq-deadline.c > index 2edf1cac06d5..4d7b21b144d3 100644 > --- a/block/mq-deadline.c > +++ b/block/mq-deadline.c > @@ -751,13 +751,15 @@ static void dd_finish_request(struct request *rq) > { > struct dd_per_prio *per_prio = rq->elv.priv[0]; > > - /* > - * The block layer core may call dd_finish_request() without having > - * called dd_insert_requests(). Skip requests that bypassed I/O > - * scheduling. See also blk_mq_request_bypass_insert(). > - */ > - if (per_prio) > - atomic_inc(&per_prio->stats.completed); > + if (rq->q->elevator) { > + /* > + * The block layer core may call dd_finish_request() without having > + * called dd_insert_requests(). Skip requests that bypassed I/O > + * scheduling. See also blk_mq_request_bypass_insert(). > + */ > + if (per_prio) > + atomic_inc(&per_prio->stats.completed); > + } > } The warnings in dd_exit_sched() will be triggered if dd_finish_request() is ever called with rq->q->elevator == NULL. If this can happen, it should be fixed in the block layer core instead of in the mq-deadline scheduler. Thanks, Bart.
I see. would it be possible to detach the elevator from the queue in elevator_exit instead? On 6/17/2025 3:25 PM, Bart Van Assche wrote: > On 6/17/25 1:56 PM, Elijah Wright wrote: >> in dd_finish_request(), per_prio points to a rq->elv.priv[0], which >> could be >> free memory if an in-flight requests completes after its associated >> scheduler >> has been freed >> >> Signed-off-by: Elijah Wright <git@elijahs.space> >> --- >> block/mq-deadline.c | 16 +++++++++------- >> 1 file changed, 9 insertions(+), 7 deletions(-) >> >> diff --git a/block/mq-deadline.c b/block/mq-deadline.c >> index 2edf1cac06d5..4d7b21b144d3 100644 >> --- a/block/mq-deadline.c >> +++ b/block/mq-deadline.c >> @@ -751,13 +751,15 @@ static void dd_finish_request(struct request *rq) >> { >> struct dd_per_prio *per_prio = rq->elv.priv[0]; >> - /* >> - * The block layer core may call dd_finish_request() without having >> - * called dd_insert_requests(). Skip requests that bypassed I/O >> - * scheduling. See also blk_mq_request_bypass_insert(). >> - */ >> - if (per_prio) >> - atomic_inc(&per_prio->stats.completed); >> + if (rq->q->elevator) { >> + /* >> + * The block layer core may call dd_finish_request() without >> having >> + * called dd_insert_requests(). Skip requests that bypassed I/O >> + * scheduling. See also blk_mq_request_bypass_insert(). >> + */ >> + if (per_prio) >> + atomic_inc(&per_prio->stats.completed); >> + } >> } > > The warnings in dd_exit_sched() will be triggered if dd_finish_request() > is ever called with rq->q->elevator == NULL. > > If this can happen, it should be fixed in the block layer core instead > of in the mq-deadline scheduler. > > Thanks, > > Bart.
On 6/17/25 3:52 PM, Elijah Wright wrote: > I see. would it be possible to detach the elevator from the queue in > elevator_exit instead? elevator_switch() is called with the request queue frozen. q_usage_counter is dropped after the blk_mq_finish_request() call returned. So what you described in your patch description can't happen. Bart.
© 2016 - 2025 Red Hat, Inc.