aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2015-10-27 19:06:55 -0400
committerMike Snitzer <snitzer@redhat.com>2015-10-29 22:09:40 -0400
commitad5f498f610fa3fd8bd265139098bc1405cd2783 (patch)
tree9e3fa163b68180e4d0ddc3466d04c91d4e7e3a5f
parenta6dd1020d8ac55782f3e04856644cf68765f8c1b (diff)
dm: initialize non-blk-mq queue data before queue is used
Commit bfebd1cdb497a57757c83f5fbf1a29931591e2a4 ("dm: add full blk-mq support to request-based DM") moves the initialization of the fields backing_dev_info.congested_fn, backing_dev_info.congested_data and queuedata from the function dm_init_md_queue (that is called when the device is created) to dm_init_old_md_queue (that is called after the device type is determined). There is no locking when accessing these variables, thus it is possible for other parts of the kernel to briefly see this data in a transient state (e.g. queue->backing_dev_info.congested_fn initialized and md->queue->backing_dev_info.congested_data uninitialized, resulting in passing an incorrect parameter to the function dm_any_congested). This queue data is left initialized for blk-mq devices even though they that don't use it. Fixes: bfebd1cdb497 ("dm: add full blk-mq support to request-based DM") Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Cc: stable@vger.kernel.org # v4.1+
-rw-r--r--drivers/md/dm.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 6264781dc69a..77ebb985154c 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -2197,6 +2197,13 @@ static void dm_init_md_queue(struct mapped_device *md)
2197 * This queue is new, so no concurrency on the queue_flags. 2197 * This queue is new, so no concurrency on the queue_flags.
2198 */ 2198 */
2199 queue_flag_clear_unlocked(QUEUE_FLAG_STACKABLE, md->queue); 2199 queue_flag_clear_unlocked(QUEUE_FLAG_STACKABLE, md->queue);
2200
2201 /*
2202 * Initialize data that will only be used by a non-blk-mq DM queue
2203 * - must do so here (in alloc_dev callchain) before queue is used
2204 */
2205 md->queue->queuedata = md;
2206 md->queue->backing_dev_info.congested_data = md;
2200} 2207}
2201 2208
2202static void dm_init_old_md_queue(struct mapped_device *md) 2209static void dm_init_old_md_queue(struct mapped_device *md)
@@ -2207,10 +2214,7 @@ static void dm_init_old_md_queue(struct mapped_device *md)
2207 /* 2214 /*
2208 * Initialize aspects of queue that aren't relevant for blk-mq 2215 * Initialize aspects of queue that aren't relevant for blk-mq
2209 */ 2216 */
2210 md->queue->queuedata = md;
2211 md->queue->backing_dev_info.congested_fn = dm_any_congested; 2217 md->queue->backing_dev_info.congested_fn = dm_any_congested;
2212 md->queue->backing_dev_info.congested_data = md;
2213
2214 blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY); 2218 blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
2215} 2219}
2216 2220