#include <linux/virtio_net.h>
#include <stdbool.h>
+#include <rte_eal_paging.h>
#include <rte_malloc.h>
#include <rte_memory.h>
#include <rte_bus_pci.h>
#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_pci_device *pdev;
struct ifcvf_hw hw;
+ int configured;
int vfio_container_fd;
int vfio_group_fd;
int vfio_dev_fd;
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;
}
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);
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);
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;
}
DRV_LOG(NOTICE, "vDPA (%s): software relay is used.",
vdev->device->name);
+ internal->configured = 1;
return 0;
}
update_datapath(internal);
}
+ internal->configured = 0;
return 0;
}
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(struct rte_vdpa_device *vdev, uint64_t *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,
goto error;
}
+ internal->configured = 0;
internal->max_queues = IFCVF_MAX_QUEUES;
features = ifcvf_get_features(&internal->hw);
internal->features = (features &
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);
-}