aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2018-11-07 16:34:05 -0500
committerJens Axboe <axboe@kernel.dk>2018-11-07 16:34:05 -0500
commit6961cd4d0fde97f1cdb798ba21cf124ecfa0bf95 (patch)
tree4c7e07de3f4fc24b0e494e457232a996afb68435 /arch/um/drivers
parentdf376b2ed51a2777c3398e038992f62523c0f932 (diff)
ubd: fix missing lock around request issue
We need to hold the device lock (and disable interrupts) while writing new commands, or we could be interrupted while that is happening and read invalid requests in the completion path. Fixes: 4e6da0fe8058 ("um: Convert ubd driver to blk-mq") Tested-by: Richard Weinberger <richard@nod.at> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'arch/um/drivers')
-rw-r--r--arch/um/drivers/ubd_kern.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 74c002ddc0ce..08831f5d83db 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1341,11 +1341,14 @@ static int ubd_queue_one_vec(struct blk_mq_hw_ctx *hctx, struct request *req,
1341static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx, 1341static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx,
1342 const struct blk_mq_queue_data *bd) 1342 const struct blk_mq_queue_data *bd)
1343{ 1343{
1344 struct ubd *ubd_dev = hctx->queue->queuedata;
1344 struct request *req = bd->rq; 1345 struct request *req = bd->rq;
1345 int ret = 0; 1346 int ret = 0;
1346 1347
1347 blk_mq_start_request(req); 1348 blk_mq_start_request(req);
1348 1349
1350 spin_lock_irq(&ubd_dev->lock);
1351
1349 if (req_op(req) == REQ_OP_FLUSH) { 1352 if (req_op(req) == REQ_OP_FLUSH) {
1350 ret = ubd_queue_one_vec(hctx, req, 0, NULL); 1353 ret = ubd_queue_one_vec(hctx, req, 0, NULL);
1351 } else { 1354 } else {
@@ -1361,9 +1364,11 @@ static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx,
1361 } 1364 }
1362 } 1365 }
1363out: 1366out:
1364 if (ret < 0) { 1367 spin_unlock_irq(&ubd_dev->lock);
1368
1369 if (ret < 0)
1365 blk_mq_requeue_request(req, true); 1370 blk_mq_requeue_request(req, true);
1366 } 1371
1367 return BLK_STS_OK; 1372 return BLK_STS_OK;
1368} 1373}
1369 1374