aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShaohua Li <shli@fusionio.com>2013-11-19 20:57:24 -0500
committerJens Axboe <axboe@kernel.dk>2013-11-19 21:00:45 -0500
commitf02b9ac35a47dff745c7637fbc095f01cc03646e (patch)
tree3615c099998adb4d8b65681acb16d9b060b1ee89
parent94eddfbeaafa3e8040a2c47d370dea0e58e76941 (diff)
virtio-blk: virtqueue_kick() must be ordered with other virtqueue operations
It isn't safe to call it without holding the vblk->vq_lock. Reported-by: Dave Chinner <david@fromorbit.com> Signed-off-by: Shaohua Li <shli@fusionio.com> Fixed another condition of virtqueue_kick() not holding the lock. Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--drivers/block/virtio_blk.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 588479d58f52..6a680d4de7f1 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -199,15 +199,16 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req)
199 199
200 spin_lock_irqsave(&vblk->vq_lock, flags); 200 spin_lock_irqsave(&vblk->vq_lock, flags);
201 if (__virtblk_add_req(vblk->vq, vbr, vbr->sg, num) < 0) { 201 if (__virtblk_add_req(vblk->vq, vbr, vbr->sg, num) < 0) {
202 virtqueue_kick(vblk->vq);
202 spin_unlock_irqrestore(&vblk->vq_lock, flags); 203 spin_unlock_irqrestore(&vblk->vq_lock, flags);
203 blk_mq_stop_hw_queue(hctx); 204 blk_mq_stop_hw_queue(hctx);
204 virtqueue_kick(vblk->vq);
205 return BLK_MQ_RQ_QUEUE_BUSY; 205 return BLK_MQ_RQ_QUEUE_BUSY;
206 } 206 }
207 spin_unlock_irqrestore(&vblk->vq_lock, flags);
208 207
209 if (last) 208 if (last)
210 virtqueue_kick(vblk->vq); 209 virtqueue_kick(vblk->vq);
210
211 spin_unlock_irqrestore(&vblk->vq_lock, flags);
211 return BLK_MQ_RQ_QUEUE_OK; 212 return BLK_MQ_RQ_QUEUE_OK;
212} 213}
213 214