X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fvdpa%2Fifc%2Fifcvf_vdpa.c;h=1dc813d0a3570bed9bfc568680fd69328e3c8e95;hb=ba57777d7d25f8fa1f1c951ec56e01b7f1207d9b;hp=ec97178dcb18fe53f6ce9eba158bd9ef2fa96961;hpb=0265a1980f7b2752b0cba9c476eb6c670b8ad778;p=dpdk.git diff --git a/drivers/vdpa/ifc/ifcvf_vdpa.c b/drivers/vdpa/ifc/ifcvf_vdpa.c index ec97178dcb..1dc813d0a3 100644 --- a/drivers/vdpa/ifc/ifcvf_vdpa.c +++ b/drivers/vdpa/ifc/ifcvf_vdpa.c @@ -11,11 +11,13 @@ #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -24,39 +26,36 @@ #include "base/ifcvf.h" +RTE_LOG_REGISTER(ifcvf_vdpa_logtype, pmd.vdpa.ifcvf, NOTICE); #define DRV_LOG(level, fmt, args...) \ rte_log(RTE_LOG_ ## level, ifcvf_vdpa_logtype, \ "IFCVF %s(): " fmt "\n", __func__, ##args) -#ifndef PAGE_SIZE -#define PAGE_SIZE 4096 -#endif - #define IFCVF_USED_RING_LEN(size) \ ((size) * sizeof(struct vring_used_elem) + sizeof(uint16_t) * 3) #define IFCVF_VDPA_MODE "vdpa" #define IFCVF_SW_FALLBACK_LM "sw-live-migration" +#define THREAD_NAME_LEN 16 + static const char * const ifcvf_valid_arguments[] = { IFCVF_VDPA_MODE, IFCVF_SW_FALLBACK_LM, NULL }; -static int ifcvf_vdpa_logtype; - struct ifcvf_internal { - struct rte_vdpa_dev_addr dev_addr; struct rte_pci_device *pdev; struct ifcvf_hw hw; + int configured; int vfio_container_fd; int vfio_group_fd; int vfio_dev_fd; pthread_t tid; /* thread for notify relay */ int epfd; int vid; - int did; + struct rte_vdpa_device *vdev; uint16_t max_queues; uint64_t features; rte_atomic32_t started; @@ -85,7 +84,7 @@ static pthread_mutex_t internal_list_lock = PTHREAD_MUTEX_INITIALIZER; static void update_used_ring(struct ifcvf_internal *internal, uint16_t qid); static struct internal_list * -find_internal_resource_by_did(int did) +find_internal_resource_by_vdev(struct rte_vdpa_device *vdev) { int found = 0; struct internal_list *list; @@ -93,7 +92,7 @@ find_internal_resource_by_did(int did) pthread_mutex_lock(&internal_list_lock); TAILQ_FOREACH(list, &internal_list, next) { - if (did == list->internal->did) { + if (vdev == list->internal->vdev) { found = 1; break; } @@ -116,7 +115,8 @@ find_internal_resource_by_dev(struct rte_pci_device *pdev) pthread_mutex_lock(&internal_list_lock); TAILQ_FOREACH(list, &internal_list, next) { - if (pdev == list->internal->pdev) { + if (!rte_pci_addr_cmp(&pdev->addr, + &list->internal->pdev->addr)) { found = 1; break; } @@ -496,14 +496,17 @@ notify_relay(void *arg) static int setup_notify_relay(struct ifcvf_internal *internal) { + char name[THREAD_NAME_LEN]; int ret; - ret = pthread_create(&internal->tid, NULL, notify_relay, - (void *)internal); - if (ret) { + snprintf(name, sizeof(name), "ifc-notify-%d", internal->vid); + ret = rte_ctrl_thread_create(&internal->tid, name, NULL, notify_relay, + (void *)internal); + if (ret != 0) { DRV_LOG(ERR, "failed to create notify relay pthread."); return -1; } + return 0; } @@ -599,11 +602,11 @@ m_ifcvf_start(struct ifcvf_internal *internal) for (i = 0; i < nr_vring; i++) { rte_vhost_get_vhost_vring(vid, i, &vq); - size = RTE_ALIGN_CEIL(vring_size(vq.size, PAGE_SIZE), - PAGE_SIZE); - vring_buf = rte_zmalloc("ifcvf", size, PAGE_SIZE); + size = RTE_ALIGN_CEIL(vring_size(vq.size, rte_mem_page_size()), + rte_mem_page_size()); + vring_buf = rte_zmalloc("ifcvf", size, rte_mem_page_size()); vring_init(&internal->m_vring[i], vq.size, vring_buf, - PAGE_SIZE); + rte_mem_page_size()); ret = rte_vfio_container_dma_map(internal->vfio_container_fd, (uint64_t)(uintptr_t)vring_buf, m_vring_iova, size); @@ -685,8 +688,8 @@ m_ifcvf_stop(struct ifcvf_internal *internal) len = IFCVF_USED_RING_LEN(vq.size); rte_vhost_log_used_vring(vid, i, 0, len); - size = RTE_ALIGN_CEIL(vring_size(vq.size, PAGE_SIZE), - PAGE_SIZE); + size = RTE_ALIGN_CEIL(vring_size(vq.size, rte_mem_page_size()), + rte_mem_page_size()); rte_vfio_container_dma_unmap(internal->vfio_container_fd, (uint64_t)(uintptr_t)internal->m_vring[i].desc, m_vring_iova, size); @@ -799,14 +802,17 @@ vring_relay(void *arg) static int setup_vring_relay(struct ifcvf_internal *internal) { + char name[THREAD_NAME_LEN]; int ret; - ret = pthread_create(&internal->tid, NULL, vring_relay, - (void *)internal); - if (ret) { + snprintf(name, sizeof(name), "ifc-vring-%d", internal->vid); + ret = rte_ctrl_thread_create(&internal->tid, name, NULL, vring_relay, + (void *)internal); + if (ret != 0) { DRV_LOG(ERR, "failed to create ring relay pthread."); return -1; } + return 0; } @@ -839,7 +845,7 @@ ifcvf_sw_fallback_switchover(struct ifcvf_internal *internal) vdpa_ifcvf_stop(internal); vdpa_disable_vfio_intr(internal); - ret = rte_vhost_host_notifier_ctrl(vid, false); + ret = rte_vhost_host_notifier_ctrl(vid, RTE_VHOST_QUEUE_ALL, false); if (ret && ret != -ENOTSUP) goto error; @@ -858,7 +864,7 @@ ifcvf_sw_fallback_switchover(struct ifcvf_internal *internal) if (ret) goto stop_vf; - rte_vhost_host_notifier_ctrl(vid, true); + rte_vhost_host_notifier_ctrl(vid, RTE_VHOST_QUEUE_ALL, true); internal->sw_fallback_running = true; @@ -877,14 +883,14 @@ error: static int ifcvf_dev_config(int vid) { - int did; + struct rte_vdpa_device *vdev; struct internal_list *list; struct ifcvf_internal *internal; - did = rte_vhost_get_vdpa_device_id(vid); - list = find_internal_resource_by_did(did); + vdev = rte_vhost_get_vdpa_device(vid); + list = find_internal_resource_by_vdev(vdev); if (list == NULL) { - DRV_LOG(ERR, "Invalid device id: %d", did); + DRV_LOG(ERR, "Invalid vDPA device: %p", vdev); return -1; } @@ -893,23 +899,25 @@ ifcvf_dev_config(int vid) rte_atomic32_set(&internal->dev_attached, 1); update_datapath(internal); - if (rte_vhost_host_notifier_ctrl(vid, true) != 0) - DRV_LOG(NOTICE, "vDPA (%d): software relay is used.", did); + if (rte_vhost_host_notifier_ctrl(vid, RTE_VHOST_QUEUE_ALL, true) != 0) + DRV_LOG(NOTICE, "vDPA (%s): software relay is used.", + vdev->device->name); + internal->configured = 1; return 0; } static int ifcvf_dev_close(int vid) { - int did; + struct rte_vdpa_device *vdev; struct internal_list *list; struct ifcvf_internal *internal; - did = rte_vhost_get_vdpa_device_id(vid); - list = find_internal_resource_by_did(did); + vdev = rte_vhost_get_vdpa_device(vid); + list = find_internal_resource_by_vdev(vdev); if (list == NULL) { - DRV_LOG(ERR, "Invalid device id: %d", did); + DRV_LOG(ERR, "Invalid vDPA device: %p", vdev); return -1; } @@ -934,6 +942,7 @@ ifcvf_dev_close(int vid) update_datapath(internal); } + internal->configured = 0; return 0; } @@ -941,15 +950,15 @@ static int ifcvf_set_features(int vid) { uint64_t features = 0; - int did; + struct rte_vdpa_device *vdev; struct internal_list *list; struct ifcvf_internal *internal; uint64_t log_base = 0, log_size = 0; - did = rte_vhost_get_vdpa_device_id(vid); - list = find_internal_resource_by_did(did); + vdev = rte_vhost_get_vdpa_device(vid); + list = find_internal_resource_by_vdev(vdev); if (list == NULL) { - DRV_LOG(ERR, "Invalid device id: %d", did); + DRV_LOG(ERR, "Invalid vDPA device: %p", vdev); return -1; } @@ -974,13 +983,13 @@ ifcvf_set_features(int vid) static int ifcvf_get_vfio_group_fd(int vid) { - int did; + struct rte_vdpa_device *vdev; struct internal_list *list; - did = rte_vhost_get_vdpa_device_id(vid); - list = find_internal_resource_by_did(did); + vdev = rte_vhost_get_vdpa_device(vid); + list = find_internal_resource_by_vdev(vdev); if (list == NULL) { - DRV_LOG(ERR, "Invalid device id: %d", did); + DRV_LOG(ERR, "Invalid vDPA device: %p", vdev); return -1; } @@ -990,13 +999,13 @@ ifcvf_get_vfio_group_fd(int vid) static int ifcvf_get_vfio_device_fd(int vid) { - int did; + struct rte_vdpa_device *vdev; struct internal_list *list; - did = rte_vhost_get_vdpa_device_id(vid); - list = find_internal_resource_by_did(did); + vdev = rte_vhost_get_vdpa_device(vid); + list = find_internal_resource_by_vdev(vdev); if (list == NULL) { - DRV_LOG(ERR, "Invalid device id: %d", did); + DRV_LOG(ERR, "Invalid vDPA device: %p", vdev); return -1; } @@ -1006,16 +1015,16 @@ ifcvf_get_vfio_device_fd(int vid) static int ifcvf_get_notify_area(int vid, int qid, uint64_t *offset, uint64_t *size) { - int did; + struct rte_vdpa_device *vdev; struct internal_list *list; struct ifcvf_internal *internal; struct vfio_region_info reg = { .argsz = sizeof(reg) }; int ret; - did = rte_vhost_get_vdpa_device_id(vid); - list = find_internal_resource_by_did(did); + vdev = rte_vhost_get_vdpa_device(vid); + list = find_internal_resource_by_vdev(vdev); if (list == NULL) { - DRV_LOG(ERR, "Invalid device id: %d", did); + DRV_LOG(ERR, "Invalid vDPA device: %p", vdev); return -1; } @@ -1036,13 +1045,13 @@ ifcvf_get_notify_area(int vid, int qid, uint64_t *offset, uint64_t *size) } static int -ifcvf_get_queue_num(int did, uint32_t *queue_num) +ifcvf_get_queue_num(struct rte_vdpa_device *vdev, uint32_t *queue_num) { struct internal_list *list; - list = find_internal_resource_by_did(did); + list = find_internal_resource_by_vdev(vdev); if (list == NULL) { - DRV_LOG(ERR, "Invalid device id: %d", did); + DRV_LOG(ERR, "Invalid vDPA device: %p", vdev); return -1; } @@ -1052,13 +1061,13 @@ ifcvf_get_queue_num(int did, uint32_t *queue_num) } static int -ifcvf_get_vdpa_features(int did, uint64_t *features) +ifcvf_get_vdpa_features(struct rte_vdpa_device *vdev, uint64_t *features) { struct internal_list *list; - list = find_internal_resource_by_did(did); + list = find_internal_resource_by_vdev(vdev); if (list == NULL) { - DRV_LOG(ERR, "Invalid device id: %d", did); + DRV_LOG(ERR, "Invalid vDPA device: %p", vdev); return -1; } @@ -1072,21 +1081,72 @@ ifcvf_get_vdpa_features(int did, uint64_t *features) 1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ | \ 1ULL << VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD | \ 1ULL << VHOST_USER_PROTOCOL_F_HOST_NOTIFIER | \ - 1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD) + 1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD | \ + 1ULL << VHOST_USER_PROTOCOL_F_STATUS) static int -ifcvf_get_protocol_features(int did __rte_unused, uint64_t *features) +ifcvf_get_protocol_features(struct rte_vdpa_device *vdev, uint64_t *features) { + RTE_SET_USED(vdev); + *features = VDPA_SUPPORTED_PROTOCOL_FEATURES; return 0; } +static int +ifcvf_set_vring_state(int vid, int vring, int state) +{ + struct rte_vdpa_device *vdev; + struct internal_list *list; + struct ifcvf_internal *internal; + struct ifcvf_hw *hw; + struct ifcvf_pci_common_cfg *cfg; + int ret = 0; + + vdev = rte_vhost_get_vdpa_device(vid); + list = find_internal_resource_by_vdev(vdev); + if (list == NULL) { + DRV_LOG(ERR, "Invalid vDPA device: %p", vdev); + return -1; + } + + internal = list->internal; + if (vring < 0 || vring >= internal->max_queues * 2) { + DRV_LOG(ERR, "Vring index %d not correct", vring); + return -1; + } + + hw = &internal->hw; + if (!internal->configured) + goto exit; + + cfg = hw->common_cfg; + IFCVF_WRITE_REG16(vring, &cfg->queue_select); + IFCVF_WRITE_REG16(!!state, &cfg->queue_enable); + + if (!state && hw->vring[vring].enable) { + ret = vdpa_disable_vfio_intr(internal); + if (ret) + return ret; + } + + if (state && !hw->vring[vring].enable) { + ret = vdpa_enable_vfio_intr(internal, 0); + if (ret) + return ret; + } + +exit: + hw->vring[vring].enable = !!state; + return 0; +} + static struct rte_vdpa_dev_ops ifcvf_ops = { .get_queue_num = ifcvf_get_queue_num, .get_features = ifcvf_get_vdpa_features, .get_protocol_features = ifcvf_get_protocol_features, .dev_conf = ifcvf_dev_config, .dev_close = ifcvf_dev_close, - .set_vring_state = NULL, + .set_vring_state = ifcvf_set_vring_state, .set_features = ifcvf_set_features, .migration_done = NULL, .get_vfio_group_fd = ifcvf_get_vfio_group_fd, @@ -1166,6 +1226,7 @@ ifcvf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, goto error; } + internal->configured = 0; internal->max_queues = IFCVF_MAX_QUEUES; features = ifcvf_get_features(&internal->hw); internal->features = (features & @@ -1176,8 +1237,6 @@ ifcvf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, (1ULL << VHOST_USER_F_PROTOCOL_FEATURES) | (1ULL << VHOST_F_LOG_ALL); - internal->dev_addr.pci_addr = pci_dev->addr; - internal->dev_addr.type = VDPA_ADDR_PCI; list->internal = internal; if (rte_kvargs_count(kvlist, IFCVF_SW_FALLBACK_LM)) { @@ -1188,9 +1247,8 @@ ifcvf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, } internal->sw_lm = sw_fallback_lm; - internal->did = rte_vdpa_register_device(&internal->dev_addr, - &ifcvf_ops); - if (internal->did < 0) { + internal->vdev = rte_vdpa_register_device(&pci_dev->device, &ifcvf_ops); + if (internal->vdev == NULL) { DRV_LOG(ERR, "failed to register device %s", pci_dev->name); goto error; } @@ -1233,7 +1291,7 @@ ifcvf_pci_remove(struct rte_pci_device *pci_dev) rte_pci_unmap_device(internal->pdev); rte_vfio_container_destroy(internal->vfio_container_fd); - rte_vdpa_unregister_device(internal->did); + rte_vdpa_unregister_device(internal->vdev); pthread_mutex_lock(&internal_list_lock); TAILQ_REMOVE(&internal_list, list, next); @@ -1271,10 +1329,3 @@ static struct rte_pci_driver rte_ifcvf_vdpa = { RTE_PMD_REGISTER_PCI(net_ifcvf, rte_ifcvf_vdpa); RTE_PMD_REGISTER_PCI_TABLE(net_ifcvf, pci_id_ifcvf_map); RTE_PMD_REGISTER_KMOD_DEP(net_ifcvf, "* vfio-pci"); - -RTE_INIT(ifcvf_vdpa_init_log) -{ - ifcvf_vdpa_logtype = rte_log_register("pmd.net.ifcvf_vdpa"); - if (ifcvf_vdpa_logtype >= 0) - rte_log_set_level(ifcvf_vdpa_logtype, RTE_LOG_NOTICE); -}