From cf7ecd23830bf8fb2763f03f2dbfccf2b469c8cd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 7 Jun 2014 19:49:12 -0700 Subject: [PATCH] 3.14-stable patches added patches: virtio_blk-fix-race-between-start-and-stop-queue.patch --- queue-3.14/series | 1 + ...ix-race-between-start-and-stop-queue.patch | 59 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 queue-3.14/virtio_blk-fix-race-between-start-and-stop-queue.patch diff --git a/queue-3.14/series b/queue-3.14/series index e1b652bea8c..6fd10e9e29b 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -28,3 +28,4 @@ mips-fix-typo-when-reporting-cache-and-ftlb-errors-for-imgtec-cores.patch dm-thin-add-no_space_timeout-dm-thin-pool-module-param.patch dm-cache-always-split-discards-on-cache-block-boundaries.patch revert-revert-mm-vmscan-do-not-swap-anon-pages-just.patch +virtio_blk-fix-race-between-start-and-stop-queue.patch diff --git a/queue-3.14/virtio_blk-fix-race-between-start-and-stop-queue.patch b/queue-3.14/virtio_blk-fix-race-between-start-and-stop-queue.patch new file mode 100644 index 00000000000..38150031c45 --- /dev/null +++ b/queue-3.14/virtio_blk-fix-race-between-start-and-stop-queue.patch @@ -0,0 +1,59 @@ +From aa0818c6ee8d8e4772725a43550823347bc1ad30 Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Fri, 16 May 2014 23:31:21 +0800 +Subject: virtio_blk: fix race between start and stop queue + +From: Ming Lei + +commit aa0818c6ee8d8e4772725a43550823347bc1ad30 upstream. + +When there isn't enough vring descriptor for adding to vq, +blk-mq will be put as stopped state until some of pending +descriptors are completed & freed. + +Unfortunately, the vq's interrupt may come just before +blk-mq's BLK_MQ_S_STOPPED flag is set, so the blk-mq will +still be kept as stopped even though lots of descriptors +are completed and freed in the interrupt handler. The worst +case is that all pending descriptors are freed in the +interrupt handler, and the queue is kept as stopped forever. + +This patch fixes the problem by starting/stopping blk-mq +with holding vq_lock. + +Cc: Jens Axboe +Cc: Rusty Russell +Signed-off-by: Ming Lei +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/block/virtio_blk.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/block/virtio_blk.c ++++ b/drivers/block/virtio_blk.c +@@ -144,11 +144,11 @@ static void virtblk_done(struct virtqueu + if (unlikely(virtqueue_is_broken(vq))) + break; + } while (!virtqueue_enable_cb(vq)); +- spin_unlock_irqrestore(&vblk->vq_lock, flags); + + /* In case queue is stopped waiting for more buffers. */ + if (req_done) + blk_mq_start_stopped_hw_queues(vblk->disk->queue); ++ spin_unlock_irqrestore(&vblk->vq_lock, flags); + } + + static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req) +@@ -200,8 +200,8 @@ static int virtio_queue_rq(struct blk_mq + spin_lock_irqsave(&vblk->vq_lock, flags); + if (__virtblk_add_req(vblk->vq, vbr, vbr->sg, num) < 0) { + virtqueue_kick(vblk->vq); +- spin_unlock_irqrestore(&vblk->vq_lock, flags); + blk_mq_stop_hw_queue(hctx); ++ spin_unlock_irqrestore(&vblk->vq_lock, flags); + return BLK_MQ_RQ_QUEUE_BUSY; + } + -- 2.47.3