The guest virtio device may request MTU updating when the vhost backend device exposes a capability to support it.
Exspose the MTU feature capability. At configuration time, check the requested MTU and update it in the HW device. Signed-off-by: Matan Azrad <ma...@mellanox.com> Reviewed-by: Maxime Coquelin <maxime.coque...@redhat.com> --- doc/guides/rel_notes/release_20_08.rst | 1 + doc/guides/vdpadevs/features/mlx5.ini | 1 + drivers/vdpa/mlx5/mlx5_vdpa.c | 67 ++++++++++++++++++++++++++++++++-- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/doc/guides/rel_notes/release_20_08.rst b/doc/guides/rel_notes/release_20_08.rst index e2c93b1..cc39984 100644 --- a/doc/guides/rel_notes/release_20_08.rst +++ b/doc/guides/rel_notes/release_20_08.rst @@ -79,6 +79,7 @@ New Features Updated Mellanox mlx5 vDPA driver with new features, including: * Added support for virtio queue statistics. + * Added support for MTU update. diff --git a/doc/guides/vdpadevs/features/mlx5.ini b/doc/guides/vdpadevs/features/mlx5.ini index 788d4e0..8bb9977 100644 --- a/doc/guides/vdpadevs/features/mlx5.ini +++ b/doc/guides/vdpadevs/features/mlx5.ini @@ -10,6 +10,7 @@ host tso4 = Y host tso6 = Y version 1 = Y log all = Y +mtu = Y any layout = Y guest announce = Y mq = Y diff --git a/drivers/vdpa/mlx5/mlx5_vdpa.c b/drivers/vdpa/mlx5/mlx5_vdpa.c index 94cac66..8b0b3b8 100644 --- a/drivers/vdpa/mlx5/mlx5_vdpa.c +++ b/drivers/vdpa/mlx5/mlx5_vdpa.c @@ -2,6 +2,11 @@ * Copyright 2019 Mellanox Technologies, Ltd */ #include <unistd.h> +#include <net/if.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <netinet/in.h> #include <rte_malloc.h> #include <rte_log.h> @@ -25,14 +30,19 @@ (1ULL << VIRTIO_NET_F_MQ) | \ (1ULL << VIRTIO_NET_F_GUEST_ANNOUNCE) | \ (1ULL << VIRTIO_F_ORDER_PLATFORM) | \ - (1ULL << VHOST_F_LOG_ALL)) + (1ULL << VHOST_F_LOG_ALL) | \ + (1ULL << VIRTIO_NET_F_MTU)) #define MLX5_VDPA_PROTOCOL_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_MQ)) + (1ULL << VHOST_USER_PROTOCOL_F_MQ) | \ + (1ULL << VHOST_USER_PROTOCOL_F_NET_MTU)) + +#define MLX5_VDPA_MAX_RETRIES 20 +#define MLX5_VDPA_USEC 1000 TAILQ_HEAD(mlx5_vdpa_privs, mlx5_vdpa_priv) priv_list = TAILQ_HEAD_INITIALIZER(priv_list); @@ -223,6 +233,55 @@ } static int +mlx5_vdpa_mtu_set(struct mlx5_vdpa_priv *priv) +{ + struct ifreq request; + uint16_t vhost_mtu = 0; + uint16_t kern_mtu = 0; + int ret = rte_vhost_get_mtu(priv->vid, &vhost_mtu); + int sock; + int retries = MLX5_VDPA_MAX_RETRIES; + + if (ret) { + DRV_LOG(DEBUG, "Cannot get vhost MTU - %d.", ret); + return ret; + } + if (!vhost_mtu) { + DRV_LOG(DEBUG, "Vhost MTU is 0."); + return ret; + } + ret = mlx5_get_ifname_sysfs(priv->ctx->device->ibdev_path, + request.ifr_name); + if (ret) { + DRV_LOG(DEBUG, "Cannot get kernel IF name - %d.", ret); + return ret; + } + sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + if (sock == -1) { + DRV_LOG(DEBUG, "Cannot open IF socket."); + return sock; + } + while (retries--) { + ret = ioctl(sock, SIOCGIFMTU, &request); + if (ret == -1) + break; + kern_mtu = request.ifr_mtu; + DRV_LOG(DEBUG, "MTU: current %d requested %d.", (int)kern_mtu, + (int)vhost_mtu); + if (kern_mtu == vhost_mtu) + break; + request.ifr_mtu = vhost_mtu; + ret = ioctl(sock, SIOCSIFMTU, &request); + if (ret == -1) + break; + request.ifr_mtu = 0; + usleep(MLX5_VDPA_USEC); + } + close(sock); + return kern_mtu == vhost_mtu ? 0 : -1; +} + +static int mlx5_vdpa_dev_close(int vid) { int did = rte_vhost_get_vdpa_device_id(vid); @@ -265,6 +324,8 @@ return -1; } priv->vid = vid; + if (mlx5_vdpa_mtu_set(priv)) + DRV_LOG(WARNING, "MTU cannot be set on device %d.", did); if (mlx5_vdpa_pd_create(priv) || mlx5_vdpa_mem_register(priv) || mlx5_vdpa_direct_db_prepare(priv) || mlx5_vdpa_virtqs_prepare(priv) || mlx5_vdpa_steer_setup(priv) || @@ -513,8 +574,6 @@ return ret; } -#define MLX5_VDPA_MAX_RETRIES 20 -#define MLX5_VDPA_USEC 1000 static int mlx5_vdpa_roce_disable(struct rte_pci_addr *addr, struct ibv_device **ibv) { -- 1.8.3.1