vhost: spdk live recovery from crash or killing
This patch is for the vhost-blk live recovery feature which can make spdk recover from crash or killing. The relate rte_xx functions are in the the shared memory protocol patches which have been merged in DPDK 19.11. Change-Id: Ia0ac99f8ba0bd66dc9f525f2c72bd1de141ec596 Signed-off-by: Li Lin <lilin24@baidu.com> Signed-off-by: Ni Xun <nixun@baidu.com> Signed-off-by: Zhang Yu <zhangyu31@baidu.com> Signed-off-by: Jin Yu <jin.yu@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/471235 Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
f29d20a21e
commit
b8d72590b3
@ -414,6 +414,7 @@ vhost_vq_used_ring_enqueue(struct spdk_vhost_session *vsession,
|
||||
struct rte_vhost_vring *vring = &virtqueue->vring;
|
||||
struct vring_used *used = vring->used;
|
||||
uint16_t last_idx = virtqueue->last_used_idx & (vring->size - 1);
|
||||
uint16_t vq_idx = virtqueue->vring_idx;
|
||||
|
||||
SPDK_DEBUGLOG(SPDK_LOG_VHOST_RING,
|
||||
"Queue %td - USED RING: last_idx=%"PRIu16" req id=%"PRIu16" len=%"PRIu32"\n",
|
||||
@ -428,10 +429,14 @@ vhost_vq_used_ring_enqueue(struct spdk_vhost_session *vsession,
|
||||
/* Ensure the used ring is updated before we log it or increment used->idx. */
|
||||
spdk_smp_wmb();
|
||||
|
||||
rte_vhost_set_last_inflight_io_split(vsession->vid, vq_idx, id);
|
||||
|
||||
vhost_log_used_vring_elem(vsession, virtqueue, last_idx);
|
||||
* (volatile uint16_t *) &used->idx = virtqueue->last_used_idx;
|
||||
vhost_log_used_vring_idx(vsession, virtqueue);
|
||||
|
||||
rte_vhost_clr_inflight_desc_split(vsession->vid, vq_idx, virtqueue->last_used_idx, id);
|
||||
|
||||
virtqueue->used_req_cnt++;
|
||||
}
|
||||
|
||||
@ -1060,6 +1065,7 @@ vhost_start_device_cb(int vid)
|
||||
continue;
|
||||
}
|
||||
q->vring_idx = i;
|
||||
rte_vhost_get_vhost_ring_inflight(vid, i, &q->vring_inflight);
|
||||
|
||||
if (q->vring.desc == NULL || q->vring.size == 0) {
|
||||
continue;
|
||||
|
@ -59,7 +59,8 @@
|
||||
(1ULL << VIRTIO_BLK_F_BARRIER) | (1ULL << VIRTIO_BLK_F_SCSI))
|
||||
|
||||
/* Vhost-blk support protocol features */
|
||||
#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))
|
||||
|
||||
struct spdk_vhost_blk_task {
|
||||
struct spdk_bdev_io *bdev_io;
|
||||
@ -432,6 +433,64 @@ process_blk_request(struct spdk_vhost_blk_task *task,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
submit_inflight_desc(struct spdk_vhost_blk_session *bvsession,
|
||||
struct spdk_vhost_virtqueue *vq)
|
||||
{
|
||||
struct spdk_vhost_blk_dev *bvdev = bvsession->bvdev;
|
||||
struct spdk_vhost_blk_task *task;
|
||||
struct spdk_vhost_session *vsession = &bvsession->vsession;
|
||||
spdk_vhost_resubmit_info *resubmit = vq->vring_inflight.resubmit_inflight;
|
||||
spdk_vhost_resubmit_desc *resubmit_list;
|
||||
int rc;
|
||||
uint16_t req_idx;
|
||||
|
||||
if (spdk_likely(resubmit == NULL || resubmit->resubmit_list == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
resubmit_list = resubmit->resubmit_list;
|
||||
while (resubmit->resubmit_num-- > 0) {
|
||||
req_idx = resubmit_list[resubmit->resubmit_num].index;
|
||||
SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "====== Start processing request idx %"PRIu16"======\n",
|
||||
req_idx);
|
||||
|
||||
if (spdk_unlikely(req_idx >= vq->vring.size)) {
|
||||
SPDK_ERRLOG("%s: request idx '%"PRIu16"' exceeds virtqueue size (%"PRIu16").\n",
|
||||
bvdev->vdev.name, req_idx, vq->vring.size);
|
||||
vhost_vq_used_ring_enqueue(vsession, vq, req_idx, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
task = &((struct spdk_vhost_blk_task *)vq->tasks)[req_idx];
|
||||
if (spdk_unlikely(task->used)) {
|
||||
SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n",
|
||||
bvdev->vdev.name, req_idx);
|
||||
vhost_vq_used_ring_enqueue(vsession, vq, req_idx, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
vsession->task_cnt++;
|
||||
|
||||
task->used = true;
|
||||
task->iovcnt = SPDK_COUNTOF(task->iovs);
|
||||
task->status = NULL;
|
||||
task->used_len = 0;
|
||||
|
||||
rc = process_blk_request(task, bvsession, vq);
|
||||
if (rc == 0) {
|
||||
SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "====== Task %p req_idx %d submitted ======\n", task,
|
||||
req_idx);
|
||||
} else {
|
||||
SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "====== Task %p req_idx %d failed ======\n", task,
|
||||
req_idx);
|
||||
}
|
||||
}
|
||||
|
||||
free(resubmit_list);
|
||||
resubmit->resubmit_list = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
process_vq(struct spdk_vhost_blk_session *bvsession, struct spdk_vhost_virtqueue *vq)
|
||||
{
|
||||
@ -440,6 +499,9 @@ process_vq(struct spdk_vhost_blk_session *bvsession, struct spdk_vhost_virtqueue
|
||||
int rc;
|
||||
uint16_t reqs[32];
|
||||
uint16_t reqs_cnt, i;
|
||||
uint16_t vq_idx = vq->vring_idx;
|
||||
|
||||
submit_inflight_desc(bvsession, vq);
|
||||
|
||||
reqs_cnt = vhost_vq_avail_ring_get(vq, reqs, SPDK_COUNTOF(reqs));
|
||||
if (!reqs_cnt) {
|
||||
@ -457,6 +519,7 @@ process_vq(struct spdk_vhost_blk_session *bvsession, struct spdk_vhost_virtqueue
|
||||
continue;
|
||||
}
|
||||
|
||||
rte_vhost_set_inflight_desc_split(vsession->vid, vq_idx, reqs[i]);
|
||||
task = &((struct spdk_vhost_blk_task *)vq->tasks)[reqs[i]];
|
||||
if (spdk_unlikely(task->used)) {
|
||||
SPDK_ERRLOG("%s: request with idx '%"PRIu16"' is already pending.\n",
|
||||
|
@ -85,8 +85,12 @@ struct vhost_poll_group {
|
||||
TAILQ_ENTRY(vhost_poll_group) tailq;
|
||||
};
|
||||
|
||||
typedef struct rte_vhost_resubmit_desc spdk_vhost_resubmit_desc;
|
||||
typedef struct rte_vhost_resubmit_info spdk_vhost_resubmit_info;
|
||||
|
||||
struct spdk_vhost_virtqueue {
|
||||
struct rte_vhost_vring vring;
|
||||
struct rte_vhost_ring_inflight vring_inflight;
|
||||
uint16_t last_avail_idx;
|
||||
uint16_t last_used_idx;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user