* [PATCH v5 1/3] blkcg: Introduce blkg_root_lookup()
[not found] <20180809145338.6160-1-bart.vanassche@wdc.com>
@ 2018-08-09 14:53 ` Bart Van Assche
2018-08-09 19:56 ` Tejun Heo
2018-08-09 14:53 ` [PATCH v5 2/3] block: Introduce blk_exit_queue() Bart Van Assche
2018-08-09 14:53 ` [PATCH v5 3/3] block: Ensure that a request queue is dissociated from the cgroup controller Bart Van Assche
2 siblings, 1 reply; 6+ messages in thread
From: Bart Van Assche @ 2018-08-09 14:53 UTC (permalink / raw)
To: Jens Axboe
Cc: linux-block, Christoph Hellwig, Bart Van Assche, Tejun Heo,
Ming Lei, Omar Sandoval, Johannes Thumshirn, Alexandru Moise,
Joseph Qi, stable
This new function will be used in a later patch to verify whether a
queue has been dissociated from the cgroup controller before being
released.
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Johannes Thumshirn <jthumshirn@suse.de>
Cc: Alexandru Moise <00moses.alexander00@gmail.com>
Cc: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: <stable@vger.kernel.org>
---
include/linux/blk-cgroup.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index f7b910768306..1361cfc9b878 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -341,6 +341,23 @@ static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg,
return __blkg_lookup(blkcg, q, false);
}
+/**
+ * blkg_lookup - look up blkg for the specified request queue
+ * @q: request_queue of interest
+ *
+ * Lookup blkg for @q at the root level. See also blkg_lookup().
+ */
+static inline struct blkcg_gq *blkg_root_lookup(struct request_queue *q)
+{
+ struct blkcg_gq *blkg;
+
+ rcu_read_lock();
+ blkg = blkg_lookup(&blkcg_root, q);
+ rcu_read_unlock();
+
+ return blkg;
+}
+
/**
* blkg_to_pdata - get policy private data
* @blkg: blkg of interest
@@ -864,6 +881,7 @@ static inline bool blk_cgroup_congested(void) { return false; }
static inline void blkcg_schedule_throttle(struct request_queue *q, bool use_memdelay) { }
static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { return NULL; }
+static inline struct blkcg_gq *blkg_root_lookup(struct request_queue *q) { return NULL; }
static inline int blkcg_init_queue(struct request_queue *q) { return 0; }
static inline void blkcg_drain_queue(struct request_queue *q) { }
static inline void blkcg_exit_queue(struct request_queue *q) { }
--
2.18.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v5 2/3] block: Introduce blk_exit_queue()
[not found] <20180809145338.6160-1-bart.vanassche@wdc.com>
2018-08-09 14:53 ` [PATCH v5 1/3] blkcg: Introduce blkg_root_lookup() Bart Van Assche
@ 2018-08-09 14:53 ` Bart Van Assche
2018-08-09 14:53 ` [PATCH v5 3/3] block: Ensure that a request queue is dissociated from the cgroup controller Bart Van Assche
2 siblings, 0 replies; 6+ messages in thread
From: Bart Van Assche @ 2018-08-09 14:53 UTC (permalink / raw)
To: Jens Axboe
Cc: linux-block, Christoph Hellwig, Bart Van Assche, Ming Lei,
Omar Sandoval, Alexandru Moise, Joseph Qi, stable
This patch does not change any functionality.
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Alexandru Moise <00moses.alexander00@gmail.com>
Cc: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: <stable@vger.kernel.org>
---
block/blk-core.c | 54 +++++++++++++++++++++++++++---------------------
block/blk.h | 1 +
2 files changed, 31 insertions(+), 24 deletions(-)
diff --git a/block/blk-core.c b/block/blk-core.c
index 2e054b65de42..55bc22ef2934 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -719,6 +719,35 @@ void blk_set_queue_dying(struct request_queue *q)
}
EXPORT_SYMBOL_GPL(blk_set_queue_dying);
+/* Unconfigure the I/O scheduler and dissociate from the cgroup controller. */
+void blk_exit_queue(struct request_queue *q)
+{
+ /*
+ * Since the I/O scheduler exit code may access cgroup information,
+ * perform I/O scheduler exit before disassociating from the block
+ * cgroup controller.
+ */
+ if (q->elevator) {
+ ioc_clear_queue(q);
+ elevator_exit(q, q->elevator);
+ q->elevator = NULL;
+ }
+
+ /*
+ * Remove all references to @q from the block cgroup controller before
+ * restoring @q->queue_lock to avoid that restoring this pointer causes
+ * e.g. blkcg_print_blkgs() to crash.
+ */
+ blkcg_exit_queue(q);
+
+ /*
+ * Since the cgroup code may dereference the @q->backing_dev_info
+ * pointer, only decrease its reference count after having removed the
+ * association with the block cgroup controller.
+ */
+ bdi_put(q->backing_dev_info);
+}
+
/**
* blk_cleanup_queue - shutdown a request queue
* @q: request queue to shutdown
@@ -788,30 +817,7 @@ void blk_cleanup_queue(struct request_queue *q)
*/
WARN_ON_ONCE(q->kobj.state_in_sysfs);
- /*
- * Since the I/O scheduler exit code may access cgroup information,
- * perform I/O scheduler exit before disassociating from the block
- * cgroup controller.
- */
- if (q->elevator) {
- ioc_clear_queue(q);
- elevator_exit(q, q->elevator);
- q->elevator = NULL;
- }
-
- /*
- * Remove all references to @q from the block cgroup controller before
- * restoring @q->queue_lock to avoid that restoring this pointer causes
- * e.g. blkcg_print_blkgs() to crash.
- */
- blkcg_exit_queue(q);
-
- /*
- * Since the cgroup code may dereference the @q->backing_dev_info
- * pointer, only decrease its reference count after having removed the
- * association with the block cgroup controller.
- */
- bdi_put(q->backing_dev_info);
+ blk_exit_queue(q);
if (q->mq_ops)
blk_mq_free_queue(q);
diff --git a/block/blk.h b/block/blk.h
index 6adae8f94279..aeb8026f4d7b 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -130,6 +130,7 @@ void blk_free_flush_queue(struct blk_flush_queue *q);
int blk_init_rl(struct request_list *rl, struct request_queue *q,
gfp_t gfp_mask);
void blk_exit_rl(struct request_queue *q, struct request_list *rl);
+void blk_exit_queue(struct request_queue *q);
void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
struct bio *bio);
void blk_queue_bypass_start(struct request_queue *q);
--
2.18.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v5 3/3] block: Ensure that a request queue is dissociated from the cgroup controller
[not found] <20180809145338.6160-1-bart.vanassche@wdc.com>
2018-08-09 14:53 ` [PATCH v5 1/3] blkcg: Introduce blkg_root_lookup() Bart Van Assche
2018-08-09 14:53 ` [PATCH v5 2/3] block: Introduce blk_exit_queue() Bart Van Assche
@ 2018-08-09 14:53 ` Bart Van Assche
2 siblings, 0 replies; 6+ messages in thread
From: Bart Van Assche @ 2018-08-09 14:53 UTC (permalink / raw)
To: Jens Axboe
Cc: linux-block, Christoph Hellwig, Bart Van Assche, Tejun Heo,
Ming Lei, Alexandru Moise, Joseph Qi, stable
Several block drivers call alloc_disk() followed by put_disk() if
something fails before device_add_disk() is called without calling
blk_cleanup_queue(). Make sure that also for this scenario a request
queue is dissociated from the cgroup controller. This patch avoids
that loading the parport_pc, paride and pf drivers triggers the
following kernel crash:
BUG: KASAN: null-ptr-deref in pi_init+0x42e/0x580 [paride]
Read of size 4 at addr 0000000000000008 by task modprobe/744
Call Trace:
dump_stack+0x9a/0xeb
kasan_report+0x139/0x350
pi_init+0x42e/0x580 [paride]
pf_init+0x2bb/0x1000 [pf]
do_one_initcall+0x8e/0x405
do_init_module+0xd9/0x2f2
load_module+0x3ab4/0x4700
SYSC_finit_module+0x176/0x1a0
do_syscall_64+0xee/0x2b0
entry_SYSCALL_64_after_hwframe+0x42/0xb7
Reported-by: Alexandru Moise <00moses.alexander00@gmail.com>
Fixes: a063057d7c73 ("block: Fix a race between request queue removal and the block cgroup controller") # v4.17
Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
Tested-by: Alexandru Moise <00moses.alexander00@gmail.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Cc: Tejun Heo <tj@kernel.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: Alexandru Moise <00moses.alexander00@gmail.com>
Cc: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: <stable@vger.kernel.org>
---
block/blk-sysfs.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index ca1984ecbdeb..fcadea471779 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -802,6 +802,21 @@ static void __blk_release_queue(struct work_struct *work)
blk_stat_remove_callback(q, q->poll_cb);
blk_stat_free_callback(q->poll_cb);
+ if (!blk_queue_dead(q)) {
+ /*
+ * Last reference was dropped without having called
+ * blk_cleanup_queue().
+ */
+ WARN_ONCE(blk_queue_init_done(q),
+ "request queue %p has been registered but blk_cleanup_queue() has not been called for that queue\n",
+ q);
+ blk_exit_queue(q);
+ }
+
+ WARN(blkg_root_lookup(q),
+ "request queue %p is being released but it has not yet been removed from the blkcg controller\n",
+ q);
+
blk_free_queue_stats(q->stats);
blk_exit_rl(q, &q->root_rl);
--
2.18.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v5 1/3] blkcg: Introduce blkg_root_lookup()
2018-08-09 14:53 ` [PATCH v5 1/3] blkcg: Introduce blkg_root_lookup() Bart Van Assche
@ 2018-08-09 19:56 ` Tejun Heo
2018-08-09 20:17 ` Bart Van Assche
0 siblings, 1 reply; 6+ messages in thread
From: Tejun Heo @ 2018-08-09 19:56 UTC (permalink / raw)
To: Bart Van Assche
Cc: Jens Axboe, linux-block, Christoph Hellwig, Ming Lei,
Omar Sandoval, Johannes Thumshirn, Alexandru Moise, Joseph Qi,
stable
Hello,
On Thu, Aug 09, 2018 at 07:53:36AM -0700, Bart Van Assche wrote:
> +/**
> + * blkg_lookup - look up blkg for the specified request queue
> + * @q: request_queue of interest
> + *
> + * Lookup blkg for @q at the root level. See also blkg_lookup().
> + */
> +static inline struct blkcg_gq *blkg_root_lookup(struct request_queue *q)
> +{
> + struct blkcg_gq *blkg;
> +
> + rcu_read_lock();
> + blkg = blkg_lookup(&blkcg_root, q);
> + rcu_read_unlock();
> +
> + return blkg;
> +}
So, root blkg is always available as long as the request_queue is
alive. Sth like the following would be simpler?
static inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q)
{
return q->root_blkg;
}
--
tejun
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v5 1/3] blkcg: Introduce blkg_root_lookup()
2018-08-09 19:56 ` Tejun Heo
@ 2018-08-09 20:17 ` Bart Van Assche
2018-08-09 20:23 ` Jens Axboe
0 siblings, 1 reply; 6+ messages in thread
From: Bart Van Assche @ 2018-08-09 20:17 UTC (permalink / raw)
To: tj@kernel.org
Cc: jthumshirn@suse.de, linux-block@vger.kernel.org, hch@lst.de,
stable@vger.kernel.org, axboe@kernel.dk, ming.lei@redhat.com,
osandov@fb.com, 00moses.alexander00@gmail.com,
joseph.qi@linux.alibaba.com
On Thu, 2018-08-09 at 12:56 -0700, Tejun Heo wrote:
> Hello,
>
> On Thu, Aug 09, 2018 at 07:53:36AM -0700, Bart Van Assche wrote:
> > +/**
> > + * blkg_lookup - look up blkg for the specified request queue
> > + * @q: request_queue of interest
> > + *
> > + * Lookup blkg for @q at the root level. See also blkg_lookup().
> > + */
> > +static inline struct blkcg_gq *blkg_root_lookup(struct request_queue *q)
> > +{
> > + struct blkcg_gq *blkg;
> > +
> > + rcu_read_lock();
> > + blkg = blkg_lookup(&blkcg_root, q);
> > + rcu_read_unlock();
> > +
> > + return blkg;
> > +}
>
> So, root blkg is always available as long as the request_queue is
> alive. Sth like the following would be simpler?
>
> static inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q)
> {
> return q->root_blkg;
> }
That would not only be simpler, it would also avoid that blk_queue_root_blkg()
returns NULL if bypass mode is enabled and the request queue is still associated
with the block cgroup controller. How do you want to proceed with this change?
Bart.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v5 1/3] blkcg: Introduce blkg_root_lookup()
2018-08-09 20:17 ` Bart Van Assche
@ 2018-08-09 20:23 ` Jens Axboe
0 siblings, 0 replies; 6+ messages in thread
From: Jens Axboe @ 2018-08-09 20:23 UTC (permalink / raw)
To: Bart Van Assche, tj@kernel.org
Cc: jthumshirn@suse.de, linux-block@vger.kernel.org, hch@lst.de,
stable@vger.kernel.org, ming.lei@redhat.com, osandov@fb.com,
00moses.alexander00@gmail.com, joseph.qi@linux.alibaba.com
On 8/9/18 2:17 PM, Bart Van Assche wrote:
> On Thu, 2018-08-09 at 12:56 -0700, Tejun Heo wrote:
>> Hello,
>>
>> On Thu, Aug 09, 2018 at 07:53:36AM -0700, Bart Van Assche wrote:
>>> +/**
>>> + * blkg_lookup - look up blkg for the specified request queue
>>> + * @q: request_queue of interest
>>> + *
>>> + * Lookup blkg for @q at the root level. See also blkg_lookup().
>>> + */
>>> +static inline struct blkcg_gq *blkg_root_lookup(struct request_queue *q)
>>> +{
>>> + struct blkcg_gq *blkg;
>>> +
>>> + rcu_read_lock();
>>> + blkg = blkg_lookup(&blkcg_root, q);
>>> + rcu_read_unlock();
>>> +
>>> + return blkg;
>>> +}
>>
>> So, root blkg is always available as long as the request_queue is
>> alive. Sth like the following would be simpler?
>>
>> static inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q)
>> {
>> return q->root_blkg;
>> }
>
> That would not only be simpler, it would also avoid that blk_queue_root_blkg()
> returns NULL if bypass mode is enabled and the request queue is still associated
> with the block cgroup controller. How do you want to proceed with this change?
Do a followup patch?
--
Jens Axboe
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-08-09 22:50 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20180809145338.6160-1-bart.vanassche@wdc.com>
2018-08-09 14:53 ` [PATCH v5 1/3] blkcg: Introduce blkg_root_lookup() Bart Van Assche
2018-08-09 19:56 ` Tejun Heo
2018-08-09 20:17 ` Bart Van Assche
2018-08-09 20:23 ` Jens Axboe
2018-08-09 14:53 ` [PATCH v5 2/3] block: Introduce blk_exit_queue() Bart Van Assche
2018-08-09 14:53 ` [PATCH v5 3/3] block: Ensure that a request queue is dissociated from the cgroup controller Bart Van Assche
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox