lib/vhost_blk: split up vhost_blk task

struct spdk_vhost_blk_task shall contain only fields
that are relevant to the generic virtio blk layer.
Moved to vhost_internal.h header to allow for broader
use.

In contrast to spdk_vhost_user_blk_task that is
specific to vhost_user transport.

Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: I8438d3e6dbca816855f55ee998a632f50acde045
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12282
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Tomasz Zawadzki 2022-04-12 09:26:56 +02:00
parent 57e6a387c2
commit 8c609f29bc
2 changed files with 81 additions and 60 deletions

View File

@ -62,33 +62,18 @@
#define SPDK_VHOST_BLK_PROTOCOL_FEATURES ((1ULL << VHOST_USER_PROTOCOL_F_CONFIG) | \ #define SPDK_VHOST_BLK_PROTOCOL_FEATURES ((1ULL << VHOST_USER_PROTOCOL_F_CONFIG) | \
(1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD)) (1ULL << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD))
struct spdk_vhost_blk_task { struct spdk_vhost_user_blk_task {
struct spdk_bdev_io *bdev_io; struct spdk_vhost_blk_task blk_task;
struct spdk_vhost_blk_session *bvsession; struct spdk_vhost_blk_session *bvsession;
struct spdk_vhost_virtqueue *vq; struct spdk_vhost_virtqueue *vq;
volatile uint8_t *status;
uint16_t req_idx; uint16_t req_idx;
uint16_t num_descs; uint16_t num_descs;
uint16_t buffer_id; uint16_t buffer_id;
uint16_t inflight_head; uint16_t inflight_head;
/* for io wait */
struct spdk_bdev_io_wait_entry bdev_io_wait;
struct spdk_io_channel *bdev_io_wait_ch;
struct spdk_vhost_dev *bdev_io_wait_vdev;
/* If set, the task is currently used for I/O processing. */ /* If set, the task is currently used for I/O processing. */
bool used; bool used;
/** Number of bytes that were written. */
uint32_t used_len;
uint16_t iovcnt;
struct iovec iovs[SPDK_VHOST_IOVS_MAX];
/** Size of whole payload in bytes */
uint32_t payload_size;
}; };
struct spdk_vhost_blk_dev { struct spdk_vhost_blk_dev {
@ -129,12 +114,12 @@ process_blk_request(struct spdk_vhost_dev *vdev, struct spdk_io_channel *ch,
struct spdk_vhost_blk_task *task); struct spdk_vhost_blk_task *task);
static int static int
vhost_user_process_blk_request(struct spdk_vhost_blk_task *task) vhost_user_process_blk_request(struct spdk_vhost_user_blk_task *user_task)
{ {
struct spdk_vhost_blk_session *bvsession = task->bvsession; struct spdk_vhost_blk_session *bvsession = user_task->bvsession;
struct spdk_vhost_dev *vdev = &bvsession->bvdev->vdev; struct spdk_vhost_dev *vdev = &bvsession->bvdev->vdev;
return process_blk_request(vdev, bvsession->io_channel, task); return process_blk_request(vdev, bvsession->io_channel, &user_task->blk_task);
} }
static struct spdk_vhost_blk_dev * static struct spdk_vhost_blk_dev *
@ -160,7 +145,7 @@ to_blk_session(struct spdk_vhost_session *vsession)
} }
static void static void
blk_task_finish(struct spdk_vhost_blk_task *task) blk_task_finish(struct spdk_vhost_user_blk_task *task)
{ {
assert(task->bvsession->vsession.task_cnt > 0); assert(task->bvsession->vsession.task_cnt > 0);
task->bvsession->vsession.task_cnt--; task->bvsession->vsession.task_cnt--;
@ -168,41 +153,47 @@ blk_task_finish(struct spdk_vhost_blk_task *task)
} }
static void static void
blk_task_init(struct spdk_vhost_blk_task *task) blk_task_init(struct spdk_vhost_user_blk_task *task)
{ {
struct spdk_vhost_blk_task *blk_task = &task->blk_task;
task->used = true; task->used = true;
task->iovcnt = SPDK_COUNTOF(task->iovs); blk_task->iovcnt = SPDK_COUNTOF(blk_task->iovs);
task->status = NULL; blk_task->status = NULL;
task->used_len = 0; blk_task->used_len = 0;
task->payload_size = 0; blk_task->payload_size = 0;
} }
static void static void
blk_task_enqueue(struct spdk_vhost_blk_task *task) blk_task_enqueue(struct spdk_vhost_user_blk_task *task)
{ {
if (task->vq->packed.packed_ring) { if (task->vq->packed.packed_ring) {
vhost_vq_packed_ring_enqueue(&task->bvsession->vsession, task->vq, vhost_vq_packed_ring_enqueue(&task->bvsession->vsession, task->vq,
task->num_descs, task->num_descs,
task->buffer_id, task->used_len, task->buffer_id, task->blk_task.used_len,
task->inflight_head); task->inflight_head);
} else { } else {
vhost_vq_used_ring_enqueue(&task->bvsession->vsession, task->vq, vhost_vq_used_ring_enqueue(&task->bvsession->vsession, task->vq,
task->req_idx, task->used_len); task->req_idx, task->blk_task.used_len);
} }
} }
static void static void
blk_request_finish(uint8_t status, struct spdk_vhost_blk_task *task) blk_request_finish(uint8_t status, struct spdk_vhost_blk_task *task)
{ {
struct spdk_vhost_user_blk_task *user_task;
if (task->status) { if (task->status) {
*task->status = status; *task->status = status;
} }
blk_task_enqueue(task); user_task = SPDK_CONTAINEROF(task, struct spdk_vhost_user_blk_task, blk_task);
blk_task_enqueue(user_task);
SPDK_DEBUGLOG(vhost_blk, "Finished task (%p) req_idx=%d\n status: %" PRIu8"\n", SPDK_DEBUGLOG(vhost_blk, "Finished task (%p) req_idx=%d\n status: %" PRIu8"\n",
task, task->req_idx, status); user_task, user_task->req_idx, status);
blk_task_finish(task); blk_task_finish(user_task);
} }
/* /*
@ -446,7 +437,7 @@ blk_request_complete_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg
static void static void
blk_request_resubmit(void *arg) blk_request_resubmit(void *arg)
{ {
struct spdk_vhost_blk_task *task = (struct spdk_vhost_blk_task *)arg; struct spdk_vhost_blk_task *task = arg;
int rc = 0; int rc = 0;
rc = process_blk_request(task->bdev_io_wait_vdev, task->bdev_io_wait_ch, task); rc = process_blk_request(task->bdev_io_wait_vdev, task->bdev_io_wait_ch, task);
@ -659,16 +650,18 @@ process_blk_request(struct spdk_vhost_dev *vdev, struct spdk_io_channel *ch,
static void static void
process_blk_task(struct spdk_vhost_virtqueue *vq, uint16_t req_idx) process_blk_task(struct spdk_vhost_virtqueue *vq, uint16_t req_idx)
{ {
struct spdk_vhost_blk_task *task; struct spdk_vhost_user_blk_task *task;
struct spdk_vhost_blk_task *blk_task;
int rc; int rc;
assert(vq->packed.packed_ring == false); assert(vq->packed.packed_ring == false);
task = &((struct spdk_vhost_blk_task *)vq->tasks)[req_idx]; task = &((struct spdk_vhost_user_blk_task *)vq->tasks)[req_idx];
blk_task = &task->blk_task;
if (spdk_unlikely(task->used)) { if (spdk_unlikely(task->used)) {
SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n", SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n",
task->bvsession->vsession.name, req_idx); task->bvsession->vsession.name, req_idx);
task->used_len = 0; blk_task->used_len = 0;
blk_task_enqueue(task); blk_task_enqueue(task);
return; return;
} }
@ -677,13 +670,13 @@ process_blk_task(struct spdk_vhost_virtqueue *vq, uint16_t req_idx)
blk_task_init(task); blk_task_init(task);
rc = blk_iovs_split_queue_setup(task->bvsession, vq, task->req_idx, task->iovs, &task->iovcnt, rc = blk_iovs_split_queue_setup(task->bvsession, vq, task->req_idx,
&task->payload_size); blk_task->iovs, &blk_task->iovcnt, &blk_task->payload_size);
if (rc) { if (rc) {
SPDK_DEBUGLOG(vhost_blk, "Invalid request (req_idx = %"PRIu16").\n", task->req_idx); SPDK_DEBUGLOG(vhost_blk, "Invalid request (req_idx = %"PRIu16").\n", task->req_idx);
/* Only READ and WRITE are supported for now. */ /* Only READ and WRITE are supported for now. */
blk_request_finish(VIRTIO_BLK_S_UNSUPP, task); blk_request_finish(VIRTIO_BLK_S_UNSUPP, blk_task);
return; return;
} }
@ -698,7 +691,8 @@ process_blk_task(struct spdk_vhost_virtqueue *vq, uint16_t req_idx)
static void static void
process_packed_blk_task(struct spdk_vhost_virtqueue *vq, uint16_t req_idx) process_packed_blk_task(struct spdk_vhost_virtqueue *vq, uint16_t req_idx)
{ {
struct spdk_vhost_blk_task *task; struct spdk_vhost_user_blk_task *task;
struct spdk_vhost_blk_task *blk_task;
uint16_t task_idx = req_idx, num_descs; uint16_t task_idx = req_idx, num_descs;
int rc; int rc;
@ -719,11 +713,12 @@ process_packed_blk_task(struct spdk_vhost_virtqueue *vq, uint16_t req_idx)
*/ */
task_idx = vhost_vring_packed_desc_get_buffer_id(vq, req_idx, &num_descs); task_idx = vhost_vring_packed_desc_get_buffer_id(vq, req_idx, &num_descs);
task = &((struct spdk_vhost_blk_task *)vq->tasks)[task_idx]; task = &((struct spdk_vhost_user_blk_task *)vq->tasks)[task_idx];
blk_task = &task->blk_task;
if (spdk_unlikely(task->used)) { if (spdk_unlikely(task->used)) {
SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n", SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n",
task->bvsession->vsession.name, task_idx); task->bvsession->vsession.name, task_idx);
task->used_len = 0; blk_task->used_len = 0;
blk_task_enqueue(task); blk_task_enqueue(task);
return; return;
} }
@ -740,12 +735,13 @@ process_packed_blk_task(struct spdk_vhost_virtqueue *vq, uint16_t req_idx)
blk_task_init(task); blk_task_init(task);
rc = blk_iovs_packed_queue_setup(task->bvsession, vq, task->req_idx, task->iovs, &task->iovcnt, rc = blk_iovs_packed_queue_setup(task->bvsession, vq, task->req_idx, blk_task->iovs,
&task->payload_size); &blk_task->iovcnt,
&blk_task->payload_size);
if (rc) { if (rc) {
SPDK_DEBUGLOG(vhost_blk, "Invalid request (req_idx = %"PRIu16").\n", task->req_idx); SPDK_DEBUGLOG(vhost_blk, "Invalid request (req_idx = %"PRIu16").\n", task->req_idx);
/* Only READ and WRITE are supported for now. */ /* Only READ and WRITE are supported for now. */
blk_request_finish(VIRTIO_BLK_S_UNSUPP, task); blk_request_finish(VIRTIO_BLK_S_UNSUPP, blk_task);
return; return;
} }
@ -763,7 +759,8 @@ process_packed_inflight_blk_task(struct spdk_vhost_virtqueue *vq,
{ {
spdk_vhost_inflight_desc *desc_array = vq->vring_inflight.inflight_packed->desc; spdk_vhost_inflight_desc *desc_array = vq->vring_inflight.inflight_packed->desc;
spdk_vhost_inflight_desc *desc = &desc_array[req_idx]; spdk_vhost_inflight_desc *desc = &desc_array[req_idx];
struct spdk_vhost_blk_task *task; struct spdk_vhost_user_blk_task *task;
struct spdk_vhost_blk_task *blk_task;
uint16_t task_idx, num_descs; uint16_t task_idx, num_descs;
int rc; int rc;
@ -779,11 +776,12 @@ process_packed_inflight_blk_task(struct spdk_vhost_virtqueue *vq,
vq->packed.avail_phase = !vq->packed.avail_phase; vq->packed.avail_phase = !vq->packed.avail_phase;
} }
task = &((struct spdk_vhost_blk_task *)vq->tasks)[task_idx]; task = &((struct spdk_vhost_user_blk_task *)vq->tasks)[task_idx];
blk_task = &task->blk_task;
if (spdk_unlikely(task->used)) { if (spdk_unlikely(task->used)) {
SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n", SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n",
task->bvsession->vsession.name, task_idx); task->bvsession->vsession.name, task_idx);
task->used_len = 0; blk_task->used_len = 0;
blk_task_enqueue(task); blk_task_enqueue(task);
return; return;
} }
@ -798,12 +796,13 @@ process_packed_inflight_blk_task(struct spdk_vhost_virtqueue *vq,
blk_task_init(task); blk_task_init(task);
rc = blk_iovs_inflight_queue_setup(task->bvsession, vq, task->req_idx, task->iovs, &task->iovcnt, rc = blk_iovs_inflight_queue_setup(task->bvsession, vq, task->req_idx, blk_task->iovs,
&task->payload_size); &blk_task->iovcnt,
&blk_task->payload_size);
if (rc) { if (rc) {
SPDK_DEBUGLOG(vhost_blk, "Invalid request (req_idx = %"PRIu16").\n", task->req_idx); SPDK_DEBUGLOG(vhost_blk, "Invalid request (req_idx = %"PRIu16").\n", task->req_idx);
/* Only READ and WRITE are supported for now. */ /* Only READ and WRITE are supported for now. */
blk_request_finish(VIRTIO_BLK_S_UNSUPP, task); blk_request_finish(VIRTIO_BLK_S_UNSUPP, blk_task);
return; return;
} }
@ -969,7 +968,8 @@ static void
no_bdev_process_packed_vq(struct spdk_vhost_blk_session *bvsession, struct spdk_vhost_virtqueue *vq) no_bdev_process_packed_vq(struct spdk_vhost_blk_session *bvsession, struct spdk_vhost_virtqueue *vq)
{ {
struct spdk_vhost_session *vsession = &bvsession->vsession; struct spdk_vhost_session *vsession = &bvsession->vsession;
struct spdk_vhost_blk_task *task; struct spdk_vhost_user_blk_task *task;
struct spdk_vhost_blk_task *blk_task;
uint32_t length; uint32_t length;
uint16_t req_idx = vq->last_avail_idx; uint16_t req_idx = vq->last_avail_idx;
uint16_t task_idx, num_descs; uint16_t task_idx, num_descs;
@ -979,12 +979,13 @@ no_bdev_process_packed_vq(struct spdk_vhost_blk_session *bvsession, struct spdk_
} }
task_idx = vhost_vring_packed_desc_get_buffer_id(vq, req_idx, &num_descs); task_idx = vhost_vring_packed_desc_get_buffer_id(vq, req_idx, &num_descs);
task = &((struct spdk_vhost_blk_task *)vq->tasks)[task_idx]; task = &((struct spdk_vhost_user_blk_task *)vq->tasks)[task_idx];
blk_task = &task->blk_task;
if (spdk_unlikely(task->used)) { if (spdk_unlikely(task->used)) {
SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n", SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n",
vsession->name, req_idx); vsession->name, req_idx);
vhost_vq_packed_ring_enqueue(vsession, vq, num_descs, vhost_vq_packed_ring_enqueue(vsession, vq, num_descs,
task->buffer_id, task->used_len, task->buffer_id, blk_task->used_len,
task->inflight_head); task->inflight_head);
return; return;
} }
@ -994,15 +995,15 @@ no_bdev_process_packed_vq(struct spdk_vhost_blk_session *bvsession, struct spdk_
task->buffer_id = task_idx; task->buffer_id = task_idx;
blk_task_init(task); blk_task_init(task);
if (blk_iovs_packed_queue_setup(bvsession, vq, task->req_idx, task->iovs, &task->iovcnt, if (blk_iovs_packed_queue_setup(bvsession, vq, task->req_idx, blk_task->iovs, &blk_task->iovcnt,
&length)) { &length)) {
*(volatile uint8_t *)(task->iovs[task->iovcnt - 1].iov_base) = VIRTIO_BLK_S_IOERR; *(volatile uint8_t *)(blk_task->iovs[blk_task->iovcnt - 1].iov_base) = VIRTIO_BLK_S_IOERR;
SPDK_DEBUGLOG(vhost_blk_data, "Aborting request %" PRIu16"\n", req_idx); SPDK_DEBUGLOG(vhost_blk_data, "Aborting request %" PRIu16"\n", req_idx);
} }
task->used = false; task->used = false;
vhost_vq_packed_ring_enqueue(vsession, vq, num_descs, vhost_vq_packed_ring_enqueue(vsession, vq, num_descs,
task->buffer_id, task->used_len, task->buffer_id, blk_task->used_len,
task->inflight_head); task->inflight_head);
} }
@ -1238,7 +1239,7 @@ alloc_task_pool(struct spdk_vhost_blk_session *bvsession)
{ {
struct spdk_vhost_session *vsession = &bvsession->vsession; struct spdk_vhost_session *vsession = &bvsession->vsession;
struct spdk_vhost_virtqueue *vq; struct spdk_vhost_virtqueue *vq;
struct spdk_vhost_blk_task *task; struct spdk_vhost_user_blk_task *task;
uint32_t task_cnt; uint32_t task_cnt;
uint16_t i; uint16_t i;
uint32_t j; uint32_t j;
@ -1257,7 +1258,7 @@ alloc_task_pool(struct spdk_vhost_blk_session *bvsession)
free_task_pool(bvsession); free_task_pool(bvsession);
return -1; return -1;
} }
vq->tasks = spdk_zmalloc(sizeof(struct spdk_vhost_blk_task) * task_cnt, vq->tasks = spdk_zmalloc(sizeof(struct spdk_vhost_user_blk_task) * task_cnt,
SPDK_CACHE_LINE_SIZE, NULL, SPDK_CACHE_LINE_SIZE, NULL,
SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA); SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
if (vq->tasks == NULL) { if (vq->tasks == NULL) {
@ -1268,7 +1269,7 @@ alloc_task_pool(struct spdk_vhost_blk_session *bvsession)
} }
for (j = 0; j < task_cnt; j++) { for (j = 0; j < task_cnt; j++) {
task = &((struct spdk_vhost_blk_task *)vq->tasks)[j]; task = &((struct spdk_vhost_user_blk_task *)vq->tasks)[j];
task->bvsession = bvsession; task->bvsession = bvsession;
task->req_idx = j; task->req_idx = j;
task->vq = vq; task->vq = vq;

View File

@ -40,6 +40,7 @@
#include <rte_vhost.h> #include <rte_vhost.h>
#include "spdk_internal/vhost_user.h" #include "spdk_internal/vhost_user.h"
#include "spdk/bdev.h"
#include "spdk/log.h" #include "spdk/log.h"
#include "spdk/util.h" #include "spdk/util.h"
#include "spdk/rpc.h" #include "spdk/rpc.h"
@ -526,4 +527,23 @@ int vhost_user_init(void);
typedef void (*vhost_fini_cb)(void *ctx); typedef void (*vhost_fini_cb)(void *ctx);
void vhost_user_fini(vhost_fini_cb vhost_cb); void vhost_user_fini(vhost_fini_cb vhost_cb);
struct spdk_vhost_blk_task {
struct spdk_bdev_io *bdev_io;
volatile uint8_t *status;
/* for io wait */
struct spdk_bdev_io_wait_entry bdev_io_wait;
struct spdk_io_channel *bdev_io_wait_ch;
struct spdk_vhost_dev *bdev_io_wait_vdev;
/** Number of bytes that were written. */
uint32_t used_len;
uint16_t iovcnt;
struct iovec iovs[SPDK_VHOST_IOVS_MAX];
/** Size of whole payload in bytes */
uint32_t payload_size;
};
#endif /* SPDK_VHOST_INTERNAL_H */ #endif /* SPDK_VHOST_INTERNAL_H */