From 5922b6931739d54006e237b25ce7cb7f79f77ce5 Mon Sep 17 00:00:00 2001 From: Chenbo Xia Date: Mon, 24 Jun 2024 06:56:40 +0000 Subject: [PATCH] vdpa/virtio: fix container recovery During recovery, devices could be removed. So we need to make sure container will not be destroyed when there are VFs that are to be recovered belonging to the same container. Signed-off-by: Chenbo Xia --- app/vfe-vdpa/vdpa_ha.c | 18 +++++++++++------- drivers/common/virtio_ha/virtio_ha.c | 8 ++++---- drivers/common/virtio_ha/virtio_ha.h | 14 ++++++++++---- drivers/common/virtio_mi/lm.c | 2 +- drivers/vdpa/virtio/virtio_vdpa.c | 15 +++++++++------ drivers/vdpa/virtio/virtio_vdpa.h | 1 + 6 files changed, 36 insertions(+), 22 deletions(-) diff --git a/app/vfe-vdpa/vdpa_ha.c b/app/vfe-vdpa/vdpa_ha.c index e92e9d87116..bc58e7d6c93 100644 --- a/app/vfe-vdpa/vdpa_ha.c +++ b/app/vfe-vdpa/vdpa_ha.c @@ -130,7 +130,7 @@ virtio_ha_client_dev_restore_pf(int *total_vf) goto err; } - ret = virtio_ha_pf_ctx_set(pf_list + i, &pf_ctx, 0); + ret = virtio_ha_pf_ctx_set(pf_list + i, &pf_ctx, NULL); if (ret < 0) { RTE_LOG(ERR, HA, "Failed to set pf ctx in pf driver\n"); ret = -1; @@ -178,7 +178,8 @@ virtio_ha_client_dev_restore_pf(int *total_vf) memset(vf_dev, 0, sizeof(struct virtio_ha_vf_to_restore)); memcpy(&vf_dev->vf_devargs, vf_list + j, sizeof(struct vdpa_vf_with_devargs)); memcpy(&vf_dev->pf_name, pf_list + i, sizeof(struct virtio_dev_name)); - vf_dev->vf_cnt_vm = 1; + vf_dev->vm_ctx.vm_vf = 1; + vf_dev->vm_ctx.vm_tbl_vf = 1; TAILQ_INSERT_TAIL(&rq.non_prio_q, vf_dev, next); } @@ -192,10 +193,13 @@ virtio_ha_client_dev_restore_pf(int *total_vf) v2 = tmp; if (strncmp(v1->vf_devargs.vm_uuid, NULL_UUID, RTE_UUID_STRLEN) != 0 && strncmp(v2->vf_devargs.vm_uuid, NULL_UUID, RTE_UUID_STRLEN) != 0 && - strncmp(v1->vf_devargs.vm_uuid, v2->vf_devargs.vm_uuid, RTE_UUID_STRLEN) == 0 && - v1->vf_devargs.mem_tbl_set && v2->vf_devargs.mem_tbl_set) { - v1->vf_cnt_vm++; - v2->vf_cnt_vm++; + strncmp(v1->vf_devargs.vm_uuid, v2->vf_devargs.vm_uuid, RTE_UUID_STRLEN) == 0) { + v1->vm_ctx.vm_vf++; + v2->vm_ctx.vm_vf++; + if (v1->vf_devargs.mem_tbl_set && v2->vf_devargs.mem_tbl_set) { + v1->vm_ctx.vm_tbl_vf++; + v2->vm_ctx.vm_tbl_vf++; + } } tmp = TAILQ_NEXT(tmp, next); } @@ -248,7 +252,7 @@ virtio_ha_client_dev_restore_vf(int total_vf) goto err; } - ret = virtio_ha_vf_ctx_set(&vf_dev->vf_devargs.vf_name, vf_ctx, vf_dev->vf_cnt_vm); + ret = virtio_ha_vf_ctx_set(&vf_dev->vf_devargs.vf_name, vf_ctx, &vf_dev->vm_ctx); if (ret < 0) { RTE_LOG(ERR, HA, "Failed to set vf ctx in vf driver\n"); pthread_mutex_unlock(&vf_restore_lock); diff --git a/drivers/common/virtio_ha/virtio_ha.c b/drivers/common/virtio_ha/virtio_ha.c index 5d4db7b3274..d62aecd0207 100644 --- a/drivers/common/virtio_ha/virtio_ha.c +++ b/drivers/common/virtio_ha/virtio_ha.c @@ -919,12 +919,12 @@ virtio_ha_vf_ctx_query(struct virtio_dev_name *vf, } int -virtio_ha_pf_ctx_set(const struct virtio_dev_name *pf, const struct virtio_pf_ctx *ctx, int num) +virtio_ha_pf_ctx_set(const struct virtio_dev_name *pf, const struct virtio_pf_ctx *ctx, struct virtio_ha_vm_dev_ctx *vm_ctx) { if (!pf_ctx_cb || !pf_ctx_cb->set) return -1; - pf_ctx_cb->set(pf, ctx, num); + pf_ctx_cb->set(pf, ctx, vm_ctx); return 0; } @@ -941,12 +941,12 @@ virtio_ha_pf_ctx_unset(const struct virtio_dev_name *pf) } int -virtio_ha_vf_ctx_set(const struct virtio_dev_name *vf, const struct vdpa_vf_ctx *ctx, int vf_cnt_vm) +virtio_ha_vf_ctx_set(const struct virtio_dev_name *vf, const struct vdpa_vf_ctx *ctx, struct virtio_ha_vm_dev_ctx *vm_ctx) { if (!vf_ctx_cb || !vf_ctx_cb->set) return -1; - vf_ctx_cb->set(vf, ctx, vf_cnt_vm); + vf_ctx_cb->set(vf, ctx, vm_ctx); return 0; } diff --git a/drivers/common/virtio_ha/virtio_ha.h b/drivers/common/virtio_ha/virtio_ha.h index b32675652fc..94f50c42a19 100644 --- a/drivers/common/virtio_ha/virtio_ha.h +++ b/drivers/common/virtio_ha/virtio_ha.h @@ -20,8 +20,9 @@ #define VIRTIO_HA_TIME_SIZE 32 struct virtio_dev_name; +struct virtio_ha_vm_dev_ctx; -typedef void (*ctx_set_cb)(const struct virtio_dev_name *dev, const void *ctx, int vf_num_vm); +typedef void (*ctx_set_cb)(const struct virtio_dev_name *dev, const void *ctx, struct virtio_ha_vm_dev_ctx *vm_ctx); typedef void (*ctx_unset_cb)(const struct virtio_dev_name *dev); typedef void (*fd_cb)(int fd, void *data); typedef void (*ver_time_set)(char *version, char *buildtime); @@ -143,6 +144,11 @@ struct virtio_ha_device_list { pthread_t prio_thread; }; +struct virtio_ha_vm_dev_ctx { + int vm_tbl_vf; /* Number of VFs belong to the same VM and use the DMA tbl */ + int vm_vf; /* Number of VFs belong to the same VM and shares the same VFIO container */ +}; + struct virtio_ha_dev_ctx_cb { ctx_set_cb set; ctx_unset_cb unset; @@ -152,7 +158,7 @@ struct virtio_ha_vf_to_restore { TAILQ_ENTRY(virtio_ha_vf_to_restore) next; struct vdpa_vf_with_devargs vf_devargs; struct virtio_dev_name pf_name; - int vf_cnt_vm; /* VF number in the same VM */ + struct virtio_ha_vm_dev_ctx vm_ctx; }; TAILQ_HEAD(virtio_ha_vf_restore_list, virtio_ha_vf_to_restore); @@ -213,13 +219,13 @@ int virtio_ha_vf_ctx_query(struct virtio_dev_name *vf, const struct virtio_dev_name *pf, struct vdpa_vf_ctx **ctx); /* App set PF context to PF driver */ -int virtio_ha_pf_ctx_set(const struct virtio_dev_name *pf, const struct virtio_pf_ctx *ctx, int num); +int virtio_ha_pf_ctx_set(const struct virtio_dev_name *pf, const struct virtio_pf_ctx *ctx, struct virtio_ha_vm_dev_ctx *vm_ctx); /* App unset PF context from PF driver */ int virtio_ha_pf_ctx_unset(const struct virtio_dev_name *pf); /* App set VF context to VF driver */ -int virtio_ha_vf_ctx_set(const struct virtio_dev_name *vf, const struct vdpa_vf_ctx *ctx, int vf_cnt_vm); +int virtio_ha_vf_ctx_set(const struct virtio_dev_name *vf, const struct vdpa_vf_ctx *ctx, struct virtio_ha_vm_dev_ctx *vm_ctx); /* App unset VF context from VF driver */ int virtio_ha_vf_ctx_unset(const struct virtio_dev_name *vf); diff --git a/drivers/common/virtio_mi/lm.c b/drivers/common/virtio_mi/lm.c index 064dae598c6..954a50e7edf 100644 --- a/drivers/common/virtio_mi/lm.c +++ b/drivers/common/virtio_mi/lm.c @@ -1216,7 +1216,7 @@ virtio_vdpa_mi_dev_remove(struct rte_pci_device *pci_dev) } static void -virtio_ha_pf_drv_ctx_set(const struct virtio_dev_name *pf, const void *ctx, __rte_unused int num) +virtio_ha_pf_drv_ctx_set(const struct virtio_dev_name *pf, const void *ctx, __rte_unused struct virtio_ha_vm_dev_ctx *vm_ctx) { const struct virtio_pf_ctx *pf_ctx = (const struct virtio_pf_ctx *)ctx; diff --git a/drivers/vdpa/virtio/virtio_vdpa.c b/drivers/vdpa/virtio/virtio_vdpa.c index 2eef5db4bbc..50b7f24d092 100644 --- a/drivers/vdpa/virtio/virtio_vdpa.c +++ b/drivers/vdpa/virtio/virtio_vdpa.c @@ -46,7 +46,7 @@ static int stage1 = 0; struct virtio_ha_vf_drv_ctx { struct virtio_dev_name vf_name; const struct vdpa_vf_ctx *ctx; - int vf_num_vm; + struct virtio_ha_vm_dev_ctx *vm_ctx; }; extern struct virtio_vdpa_device_callback virtio_vdpa_blk_callback; @@ -63,13 +63,13 @@ static pthread_mutex_t iommu_domain_locks[VIRTIO_VDPA_MAX_IOMMU_DOMAIN]; static struct virtio_ha_vf_drv_ctx cached_ctx; static void -virtio_ha_vf_drv_ctx_set(const struct virtio_dev_name *vf, const void *ctx, int vf_num_vm) +virtio_ha_vf_drv_ctx_set(const struct virtio_dev_name *vf, const void *ctx, struct virtio_ha_vm_dev_ctx *vm_ctx) { const struct vdpa_vf_ctx *vf_ctx = (const struct vdpa_vf_ctx *)ctx; memcpy(&cached_ctx.vf_name, vf, sizeof(struct virtio_dev_name)); cached_ctx.ctx = vf_ctx; - cached_ctx.vf_num_vm = vf_num_vm; + cached_ctx.vm_ctx = vm_ctx; } static void @@ -79,7 +79,7 @@ virtio_ha_vf_drv_ctx_unset(const struct virtio_dev_name *vf) return; memset(&cached_ctx.vf_name, 0, sizeof(struct virtio_dev_name)); cached_ctx.ctx = NULL; - cached_ctx.vf_num_vm = 0; + cached_ctx.vm_ctx = NULL; } static struct virtio_vdpa_priv * @@ -140,6 +140,7 @@ alloc_iommu_domain(void) iommu_domain->container_ref_cnt = 0; iommu_domain->mem_tbl_ref_cnt = 0; iommu_domain->tbl_recover_cnt = 0; + iommu_domain->cont_recover_cnt = 0; iommu_domain->vm_pid = -1; virtio_iommu_domains[i] = iommu_domain; @@ -2250,7 +2251,7 @@ virtio_vdpa_dev_do_remove(struct rte_pci_device *pci_dev, struct virtio_vdpa_pri iommu_domain = virtio_iommu_domains[priv->iommu_idx]; if (iommu_domain) { iommu_domain->container_ref_cnt--; - if (iommu_domain->container_ref_cnt == 0) { + if (iommu_domain->container_ref_cnt == 0 && iommu_domain->cont_recover_cnt == 0) { if (priv->vfio_container_fd >= 0) { rte_vfio_container_destroy(priv->vfio_container_fd); priv->vfio_container_fd = -1; @@ -2435,9 +2436,11 @@ virtio_vdpa_dev_probe(struct rte_pci_driver *pci_drv __rte_unused, iommu_domain->mem.regions[i].size = mem->regions[i].size; } iommu_domain->mem.nregions = mem->nregions; - iommu_domain->tbl_recover_cnt = cached_ctx.vf_num_vm; + iommu_domain->tbl_recover_cnt = cached_ctx.vm_ctx->vm_tbl_vf; + iommu_domain->cont_recover_cnt = cached_ctx.vm_ctx->vm_vf; iommu_domain->vm_pid = mem->vm_pid; } + iommu_domain->cont_recover_cnt--; pthread_mutex_unlock(&iommu_domain_locks[iommu_idx]); if (cached_ctx.ctx->ctt.mem.nregions != 0) priv->tbl_recovering = true; diff --git a/drivers/vdpa/virtio/virtio_vdpa.h b/drivers/vdpa/virtio/virtio_vdpa.h index b120d7f165a..1714f4a147b 100644 --- a/drivers/vdpa/virtio/virtio_vdpa.h +++ b/drivers/vdpa/virtio/virtio_vdpa.h @@ -35,6 +35,7 @@ struct virtio_vdpa_iommu_domain { int container_ref_cnt; int mem_tbl_ref_cnt; int tbl_recover_cnt; + int cont_recover_cnt; int vm_pid; };