diff --git a/lib/vhost/vhost_blk.c b/lib/vhost/vhost_blk.c index e64b3f0c2..47914307e 100644 --- a/lib/vhost/vhost_blk.c +++ b/lib/vhost/vhost_blk.c @@ -53,6 +53,9 @@ struct spdk_vhost_blk_task { uint16_t req_idx; + /* for io wait */ + struct spdk_bdev_io_wait_entry bdev_io_wait; + /* If set, the task is currently used for I/O processing. */ bool used; @@ -74,6 +77,10 @@ struct spdk_vhost_blk_dev { /* forward declaration */ static const struct spdk_vhost_dev_backend vhost_blk_device_backend; +static int +process_blk_request(struct spdk_vhost_blk_task *task, struct spdk_vhost_blk_dev *bvdev, + struct spdk_vhost_virtqueue *vq); + static void blk_task_finish(struct spdk_vhost_blk_task *task) { @@ -182,6 +189,38 @@ blk_request_complete_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg blk_request_finish(success, task); } +static void +blk_request_resubmit(void *arg) +{ + struct spdk_vhost_blk_task *task = (struct spdk_vhost_blk_task *)arg; + int rc = 0; + + rc = process_blk_request(task, task->bvdev, task->vq); + if (rc == 0) { + SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "====== Task %p resubmitted ======\n", task); + } else { + SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "====== Task %p failed ======\n", task); + } +} + +static inline void +blk_request_queue_io(struct spdk_vhost_blk_task *task) +{ + int rc; + struct spdk_vhost_blk_dev *bvdev = task->bvdev; + struct spdk_bdev *bdev = bvdev->bdev; + + task->bdev_io_wait.bdev = bdev; + task->bdev_io_wait.cb_fn = blk_request_resubmit; + task->bdev_io_wait.cb_arg = task; + + rc = spdk_bdev_queue_io_wait(bdev, bvdev->bdev_io_channel, &task->bdev_io_wait); + if (rc != 0) { + SPDK_ERRLOG("Queue io failed in vhost_blk, rc=%d\n", rc); + invalid_blk_request(task, VIRTIO_BLK_S_IOERR); + } +} + static int process_blk_request(struct spdk_vhost_blk_task *task, struct spdk_vhost_blk_dev *bvdev, struct spdk_vhost_virtqueue *vq) @@ -255,8 +294,13 @@ process_blk_request(struct spdk_vhost_blk_task *task, struct spdk_vhost_blk_dev } if (rc) { - invalid_blk_request(task, VIRTIO_BLK_S_IOERR); - return -1; + if (rc == -ENOMEM) { + SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "No memory, start to queue io.\n"); + blk_request_queue_io(task); + } else { + invalid_blk_request(task, VIRTIO_BLK_S_IOERR); + return -1; + } } break; case VIRTIO_BLK_T_GET_ID: