[dpdk-dev] [PATCH 3/7] net/virtio: introduce Vhost-vDPA backend type
Maxime Coquelin
maxime.coquelin at redhat.com
Fri Sep 11 17:08:01 CEST 2020
Introduce virtio_user_backend_type function and its enum in
order to support more than two backends with vDPA backend
addition.
Backend type is determined by checking the virtio-user control
file information at runtime.
Signed-off-by: Maxime Coquelin <maxime.coquelin at redhat.com>
Signed-off-by: Adrian Moreno <amorenoz at redhat.com>
---
.../net/virtio/virtio_user/virtio_user_dev.c | 86 +++++++++++++++----
.../net/virtio/virtio_user/virtio_user_dev.h | 10 ++-
drivers/net/virtio/virtio_user_ethdev.c | 3 +-
3 files changed, 79 insertions(+), 20 deletions(-)
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 2a0c861085..93274b2a94 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -12,6 +12,8 @@
#include <sys/eventfd.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <linux/major.h>
#include <rte_string_fns.h>
#include <rte_eal_memconfig.h>
@@ -111,15 +113,55 @@ virtio_user_queue_setup(struct virtio_user_dev *dev,
return 0;
}
-int
-is_vhost_user_by_type(const char *path)
+static uint32_t
+vdpa_dynamic_major_num(void)
+{
+ FILE *fp;
+ char *line = NULL;
+ size_t size;
+ char name[11];
+ bool found = false;
+ uint32_t num;
+
+ fp = fopen("/proc/devices", "r");
+ if (fp == NULL) {
+ PMD_INIT_LOG(ERR, "Cannot open /proc/devices: %s",
+ strerror(errno));
+ return UNNAMED_MAJOR;
+ }
+
+ while (getline(&line, &size, fp) > 0) {
+ char *stripped = line + strspn(line, " ");
+ if ((sscanf(stripped, "%u %10s", &num, name) == 2) &&
+ (strncmp(name, "vhost-vdpa", 10) == 0)) {
+ found = true;
+ break;
+ }
+ }
+ fclose(fp);
+ return found ? num : UNNAMED_MAJOR;
+}
+
+enum virtio_user_backend_type
+virtio_user_backend_type(const char *path)
{
struct stat sb;
- if (stat(path, &sb) == -1)
- return 0;
+ if (stat(path, &sb) == -1) {
+ PMD_INIT_LOG(ERR, "Stat fails: %s (%s)\n", path,
+ strerror(errno));
+ return VIRTIO_USER_BACKEND_UNKNOWN;
+ }
- return S_ISSOCK(sb.st_mode);
+ if (S_ISSOCK(sb.st_mode)) {
+ return VIRTIO_USER_BACKEND_VHOST_USER;
+ } else if (S_ISCHR(sb.st_mode)) {
+ if (major(sb.st_rdev) == MISC_MAJOR)
+ return VIRTIO_USER_BACKEND_VHOST_KERNEL;
+ if (major(sb.st_rdev) == vdpa_dynamic_major_num())
+ return VIRTIO_USER_BACKEND_VHOST_VDPA;
+ }
+ return VIRTIO_USER_BACKEND_UNKNOWN;
}
int
@@ -144,7 +186,8 @@ virtio_user_start_device(struct virtio_user_dev *dev)
rte_mcfg_mem_read_lock();
pthread_mutex_lock(&dev->mutex);
- if (is_vhost_user_by_type(dev->path) && dev->vhostfd < 0)
+ if (virtio_user_backend_type(dev->path) ==
+ VIRTIO_USER_BACKEND_VHOST_USER && dev->vhostfd < 0)
goto error;
/* Step 0: tell vhost to create queues */
@@ -359,17 +402,19 @@ virtio_user_dev_setup(struct virtio_user_dev *dev)
dev->vhostfds = NULL;
dev->tapfds = NULL;
+ dev->backend_type = virtio_user_backend_type(dev->path);
+
if (dev->is_server) {
- if (access(dev->path, F_OK) == 0 &&
- !is_vhost_user_by_type(dev->path)) {
- PMD_DRV_LOG(ERR, "Server mode doesn't support vhost-kernel!");
+ if (dev->backend_type != VIRTIO_USER_BACKEND_VHOST_USER) {
+ PMD_DRV_LOG(ERR, "Server mode only supports vhost-user!");
return -1;
}
dev->ops = &virtio_ops_user;
} else {
- if (is_vhost_user_by_type(dev->path)) {
+ if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER) {
dev->ops = &virtio_ops_user;
- } else {
+ } else if (dev->backend_type ==
+ VIRTIO_USER_BACKEND_VHOST_KERNEL) {
dev->ops = &virtio_ops_kernel;
dev->vhostfds = malloc(dev->max_queue_pairs *
@@ -457,7 +502,8 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
return -1;
}
- if (!is_vhost_user_by_type(dev->path))
+ if (virtio_user_backend_type(dev->path) !=
+ VIRTIO_USER_BACKEND_VHOST_USER)
dev->unsupported_features |=
(1ULL << VHOST_USER_F_PROTOCOL_FEATURES);
@@ -505,8 +551,6 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
dev->device_features = VIRTIO_USER_SUPPORTED_FEATURES;
}
-
-
if (!mrg_rxbuf)
dev->unsupported_features |= (1ull << VIRTIO_NET_F_MRG_RXBUF);
@@ -539,7 +583,8 @@ virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
}
/* The backend will not report this feature, we add it explicitly */
- if (is_vhost_user_by_type(dev->path))
+ if (virtio_user_backend_type(dev->path) ==
+ VIRTIO_USER_BACKEND_VHOST_USER)
dev->frontend_features |= (1ull << VIRTIO_NET_F_STATUS);
/*
@@ -790,9 +835,11 @@ virtio_user_send_status_update(struct virtio_user_dev *dev, uint8_t status)
{
int ret;
uint64_t arg = status;
+ enum virtio_user_backend_type backend_type =
+ virtio_user_backend_type(dev->path);
/* Vhost-user only for now */
- if (!is_vhost_user_by_type(dev->path))
+ if (backend_type != VIRTIO_USER_BACKEND_VHOST_USER)
return 0;
if (!(dev->protocol_features & (1ULL << VHOST_USER_PROTOCOL_F_STATUS)))
@@ -813,9 +860,11 @@ virtio_user_update_status(struct virtio_user_dev *dev)
{
uint64_t ret;
int err;
+ enum virtio_user_backend_type backend_type =
+ virtio_user_backend_type(dev->path);
/* Vhost-user only for now */
- if (!is_vhost_user_by_type(dev->path))
+ if (backend_type != VIRTIO_USER_BACKEND_VHOST_USER)
return 0;
if (!(dev->protocol_features & (1UL << VHOST_USER_PROTOCOL_F_STATUS)))
@@ -828,7 +877,8 @@ virtio_user_update_status(struct virtio_user_dev *dev)
return -1;
}
if (ret > UINT8_MAX) {
- PMD_INIT_LOG(ERR, "Invalid VHOST_USER_GET_STATUS response 0x%" PRIx64 "\n", ret);
+ PMD_INIT_LOG(ERR, "Invalid VHOST_USER_GET_STATUS "
+ "response 0x%" PRIx64 "\n", ret);
return -1;
}
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.h b/drivers/net/virtio/virtio_user/virtio_user_dev.h
index 9377d5ba66..4bb7cdbd26 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.h
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.h
@@ -10,6 +10,13 @@
#include "../virtio_pci.h"
#include "../virtio_ring.h"
+enum virtio_user_backend_type {
+ VIRTIO_USER_BACKEND_UNKNOWN,
+ VIRTIO_USER_BACKEND_VHOST_USER,
+ VIRTIO_USER_BACKEND_VHOST_KERNEL,
+ VIRTIO_USER_BACKEND_VHOST_VDPA,
+};
+
struct virtio_user_queue {
uint16_t used_idx;
bool avail_wrap_counter;
@@ -17,6 +24,7 @@ struct virtio_user_queue {
};
struct virtio_user_dev {
+ enum virtio_user_backend_type backend_type;
/* for vhost_user backend */
int vhostfd;
int listenfd; /* listening fd */
@@ -60,7 +68,7 @@ struct virtio_user_dev {
bool started;
};
-int is_vhost_user_by_type(const char *path);
+enum virtio_user_backend_type virtio_user_backend_type(const char *path);
int virtio_user_start_device(struct virtio_user_dev *dev);
int virtio_user_stop_device(struct virtio_user_dev *dev);
int virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index 60d17af888..2163d0e30d 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -632,7 +632,8 @@ virtio_user_pmd_probe(struct rte_vdev_device *dev)
}
if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_INTERFACE_NAME) == 1) {
- if (is_vhost_user_by_type(path)) {
+ if (virtio_user_backend_type(path) !=
+ VIRTIO_USER_BACKEND_VHOST_KERNEL) {
PMD_INIT_LOG(ERR,
"arg %s applies only to vhost-kernel backend",
VIRTIO_USER_ARG_INTERFACE_NAME);
--
2.26.2
More information about the dev
mailing list