diff options
| -rw-r--r-- | drivers/block/virtio_blk.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index b1cb3f4c4db4..a2db9ed288f2 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
| @@ -158,6 +158,7 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req) | |||
| 158 | unsigned long flags; | 158 | unsigned long flags; |
| 159 | unsigned int num; | 159 | unsigned int num; |
| 160 | const bool last = (req->cmd_flags & REQ_END) != 0; | 160 | const bool last = (req->cmd_flags & REQ_END) != 0; |
| 161 | int err; | ||
| 161 | 162 | ||
| 162 | BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems); | 163 | BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems); |
| 163 | 164 | ||
| @@ -198,11 +199,16 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx, struct request *req) | |||
| 198 | } | 199 | } |
| 199 | 200 | ||
| 200 | spin_lock_irqsave(&vblk->vq_lock, flags); | 201 | spin_lock_irqsave(&vblk->vq_lock, flags); |
| 201 | if (__virtblk_add_req(vblk->vq, vbr, vbr->sg, num) < 0) { | 202 | err = __virtblk_add_req(vblk->vq, vbr, vbr->sg, num); |
| 203 | if (err) { | ||
| 202 | virtqueue_kick(vblk->vq); | 204 | virtqueue_kick(vblk->vq); |
| 203 | spin_unlock_irqrestore(&vblk->vq_lock, flags); | 205 | spin_unlock_irqrestore(&vblk->vq_lock, flags); |
| 204 | blk_mq_stop_hw_queue(hctx); | 206 | blk_mq_stop_hw_queue(hctx); |
| 205 | return BLK_MQ_RQ_QUEUE_BUSY; | 207 | /* Out of mem doesn't actually happen, since we fall back |
| 208 | * to direct descriptors */ | ||
| 209 | if (err == -ENOMEM || err == -ENOSPC) | ||
| 210 | return BLK_MQ_RQ_QUEUE_BUSY; | ||
| 211 | return BLK_MQ_RQ_QUEUE_ERROR; | ||
| 206 | } | 212 | } |
| 207 | 213 | ||
| 208 | if (last) | 214 | if (last) |
