Unverified Commit a3c1378d authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!222 vdpa: add two ioctl commands to support generic vDPA

Merge Pull Request from: @Zhao_Py 
 
[Description]​
To support generic vdpa deivce, we need add the following ioctls:
  - GET_CONFIG_SIZE: the size of the virtio config space
  - GET_VQS_COUNT: the count of virtqueues that exposed

#I5WXCZ
https://lore.kernel.org/all/20220315032553.455-1-longpeng2@huawei.com/

upstream commits list here:
64b9f64f vdpa: introduce virtio pci driver
442706f9 vdpa: add get_config_size callback in vdpa_config_ops
a61280dd vdpa: support exposing the config size to userspace
fd70a406 vdpa: Extend routine to accept vdpa device name
33b34750 vdpa: Define vdpa mgmt device, ops and a netlink interface
476c135e vdpa: Add missing comment for virtqueue count
903f7bca vdpa: Enable a user to add and delete a vdpa device
b04d910a vdpa: support exposing the count of vqs to userspace
64f2087a virtio-pci: do not access iomem via struct virtio_pci_device directly
b5d58094 virtio-pci: split out modern device
117a9de2 virtio-pci-modern: factor out modern device initialization logic
32490370 virtio-pci-modern: introduce vp_modern_remove()
1a5c85f1 virtio-pci-modern: introduce helper to set config vector
e3669129 virtio-pci-modern: introduce helpers for setting and getting status
0b017708 virtio-pci-modern: introduce helpers for setting and getting features
ed2a73db virtio-pci-modern: introduce vp_modern_generation()
a6525b99 Merge tag 'mips_5.12_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
e1b0fa2e virtio-pci-modern: introduce vp_modern_queue_address()
dc2e6481 virtio-pci-modern: introduce helper to set/get queue_enable
75658afb virtio-pci-modern: introduce helper for setting/geting queue size
6e52fc44 virtio-pci-modern: introduce helper for getting queue nums
1bfd8413 virtio-pci-modern: introduce helper to get notification offset
8000a6b6 virito-pci-modern: rename map_capability() to vp_modern_map_capability()
fd502729 virtio-pci: introduce modern device module
bc0d90ee vdpa: Enable user to query vdpa device info
29b90f92 vdpa: remove unnecessary 'default n' in Kconfig entries
275900df vdpa_sim: split vdpasim_virtqueue's iov field in out_iov and in_iov
2f8f4618 vdpa_sim: add device id field in vdpasim_dev_attr
a13b5918 vdpa_sim: add work_fn in vdpasim_dev_attr
c124a95e vdpa_sim: add set_config callback in vdpasim_dev_attr
011c35ba vdpa_sim: add supported_features field in vdpasim_dev_attr
f00bdce0 vdpa: set the virtqueue num during register
db1e8bb6 vdpa: split vdpasim to core and net modules
0c853c2c vdpa: add vdpa simulator for block device
da7af696 vdpa_sim: make vdpasim->buffer size configurable
a3c06ae1 vdpa_sim_net: Add support for user supported devices
899c4d18 vdpa_sim_blk: add support for vdpa management tool
539fec78 vdpa: add driver_override support
d6d8bb92: vhost/vdpa: use get_config_size callback in vhost_vdpa_config_validate()
9e3bb9b7: virtio_pci_modern: introduce helper to map vq notify area
7dca6c0e: virtio-pci library: switch to use vp_modern_map_vq_notify()
11d8ffed: vp_vdpa: switch to use vp_modern_map_vq_notify()
9e311bca: virtio-pci library: report resource address
526cb858: vp_vdpa: report doorbell address
0686082d: vdpa: Add reset callback in vdpa_config_ops
5bbfea1e: vp_vdpa: add vq irq offloading support
530a5678: vdpa: support packed virtqueue for set/get_vq_state()
0140b3d0: virtio-pci library: introduce vp_modern_get_driver_features()
1225c216: vp_vdpa: allow set vq state to initial state after reset
0f8a0b0b: virtio_pci_modern: __force cast the notify mapping
d7bce85a: virtio_pci_modern: correct sparse tags for notify
9632e78e: vp_vdpa: Fix return value check for vdpa_alloc_device()
27d9839f: virtio: always enter drivers/virtio/
eb057b44: vdpa: fix use-after-free on vp_vdpa_remove
bb47620b: vdpa: Consider device id larger than 31
ef76eb83: vdpa/mlx5: Fix clearing of VIRTIO_NET_F_MAC feature bit
870aaff9: vdpa: clean up get_config_size ret value handling

[Testing]
kernel options:
CONFIG_VDPA=m
CONFIG_VDPA_SIM=m
CONFIG_VDPA_SIM_NET=m
CONFIG_VDPA_SIM_BLOCK=m
CONFIG_VP_VDPA=m
CONFIG_VHOST=m
CONFIG_VHOST_MENU=y
CONFIG_VHOST_NET=m
CONFIG_VHOST_VSOCK=m
CONFIG_VHOST_VDPA=m
CONFIG_RUNTIME_TESTING_MENU=y

Tested on openEuler 22.03 LTS:
```
$ modprobe vdpa
$ modprobe vdpa_sim
$ modprobe vdpa-sim-net
$ modprobe vhost-vdpa
$ vdpa dev add mgmtdev vdpasim_net name vdpa0
$ vdpa dev show
vdpa0: type network mgmtdev vdpasim_net vendor_id 0 max_vqs 2 max_vq_size 256
$ ls /dev/vhost-vdpa-*
/dev/vhost-vdpa-0
```




 
 
Link:https://gitee.com/openeuler/kernel/pulls/222

 
Reviewed-by: default avatarKevin Zhu <zhukeqian1@huawei.com>
Reviewed-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents 606f08e8 be1d2d41
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ obj-$(CONFIG_DMADEVICES) += dma/
# SOC specific infrastructure drivers.
obj-y				+= soc/

obj-$(CONFIG_VIRTIO)		+= virtio/
obj-y				+= virtio/
obj-$(CONFIG_VDPA)		+= vdpa/
obj-$(CONFIG_XEN)		+= xen/

+24 −7
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0-only
menuconfig VDPA
	tristate "vDPA drivers"
	depends on NET
	help
	  Enable this module to support vDPA device that uses a
	  datapath which complies with virtio specifications with
@@ -9,21 +10,31 @@ menuconfig VDPA
if VDPA

config VDPA_SIM
	tristate "vDPA device simulator"
	tristate "vDPA device simulator core"
	depends on RUNTIME_TESTING_MENU && HAS_DMA
	select DMA_OPS
	select VHOST_RING
	help
	  Enable this module to support vDPA device simulators. These devices
	  are used for testing, prototyping and development of vDPA.

config VDPA_SIM_NET
	tristate "vDPA simulator for networking device"
	depends on VDPA_SIM
	select GENERIC_NET_UTILS
	default n
	help
	  vDPA networking device simulator which loop TX traffic back
	  to RX. This device is used for testing, prototyping and
	  development of vDPA.
	  vDPA networking device simulator which loops TX traffic back to RX.

config VDPA_SIM_BLOCK
	tristate "vDPA simulator for block device"
	depends on VDPA_SIM
	help
	  vDPA block device simulator which terminates IO request in a
	  memory buffer.

config IFCVF
	tristate "Intel IFC VF vDPA driver"
	depends on PCI_MSI
	default n
	help
	  This kernel module can drive Intel IFC VF NIC to offload
	  virtio dataplane traffic to hardware.
@@ -42,11 +53,17 @@ config MLX5_VDPA_NET
	tristate "vDPA driver for ConnectX devices"
	select MLX5_VDPA
	depends on MLX5_CORE
	default n
	help
	  VDPA network driver for ConnectX6 and newer. Provides offloading
	  of virtio net datapath such that descriptors put on the ring will
	  be executed by the hardware. It also supports a variety of stateless
	  offloads depending on the actual device used and firmware version.

config VP_VDPA
	tristate "Virtio PCI bridge vDPA driver"
	select VIRTIO_PCI_LIB
	depends on PCI_MSI
	help
	  This kernel module bridges virtio PCI device to vDPA bus.

endif # VDPA
+1 −0
Original line number Diff line number Diff line
@@ -3,3 +3,4 @@ obj-$(CONFIG_VDPA) += vdpa.o
obj-$(CONFIG_VDPA_SIM) += vdpa_sim/
obj-$(CONFIG_IFCVF)    += ifcvf/
obj-$(CONFIG_MLX5_VDPA) += mlx5/
obj-$(CONFIG_VP_VDPA)    += virtio_pci/
+34 −16
Original line number Diff line number Diff line
@@ -207,17 +207,6 @@ static void ifcvf_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status)
	if (status_old == status)
		return;

	if ((status_old & VIRTIO_CONFIG_S_DRIVER_OK) &&
	    !(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
		ifcvf_stop_datapath(adapter);
		ifcvf_free_irq(adapter, IFCVF_MAX_QUEUE_PAIRS * 2);
	}

	if (status == 0) {
		ifcvf_reset_vring(adapter);
		return;
	}

	if ((status & VIRTIO_CONFIG_S_DRIVER_OK) &&
	    !(status_old & VIRTIO_CONFIG_S_DRIVER_OK)) {
		ret = ifcvf_request_irq(adapter);
@@ -237,6 +226,29 @@ static void ifcvf_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status)
	ifcvf_set_status(vf, status);
}

static int ifcvf_vdpa_reset(struct vdpa_device *vdpa_dev)
{
	struct ifcvf_adapter *adapter;
	struct ifcvf_hw *vf;
	u8 status_old;

	vf  = vdpa_to_vf(vdpa_dev);
	adapter = vdpa_to_adapter(vdpa_dev);
	status_old = ifcvf_get_status(vf);

	if (status_old == 0)
		return 0;

	if (status_old & VIRTIO_CONFIG_S_DRIVER_OK) {
		ifcvf_stop_datapath(adapter);
		ifcvf_free_irq(adapter, IFCVF_MAX_QUEUE_PAIRS * 2);
	}

	ifcvf_reset_vring(adapter);

	return 0;
}

static u16 ifcvf_vdpa_get_vq_num_max(struct vdpa_device *vdpa_dev)
{
	return IFCVF_QUEUE_MAX;
@@ -247,7 +259,7 @@ static int ifcvf_vdpa_get_vq_state(struct vdpa_device *vdpa_dev, u16 qid,
{
	struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev);

	state->avail_index = ifcvf_get_vq_state(vf, qid);
	state->split.avail_index = ifcvf_get_vq_state(vf, qid);
	return 0;
}

@@ -256,7 +268,7 @@ static int ifcvf_vdpa_set_vq_state(struct vdpa_device *vdpa_dev, u16 qid,
{
	struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev);

	return ifcvf_set_vq_state(vf, qid, state->avail_index);
	return ifcvf_set_vq_state(vf, qid, state->split.avail_index);
}

static void ifcvf_vdpa_set_vq_cb(struct vdpa_device *vdpa_dev, u16 qid,
@@ -332,6 +344,11 @@ static u32 ifcvf_vdpa_get_vq_align(struct vdpa_device *vdpa_dev)
	return IFCVF_QUEUE_ALIGNMENT;
}

static size_t ifcvf_vdpa_get_config_size(struct vdpa_device *vdpa_dev)
{
	return sizeof(struct virtio_net_config);
}

static void ifcvf_vdpa_get_config(struct vdpa_device *vdpa_dev,
				  unsigned int offset,
				  void *buf, unsigned int len)
@@ -378,6 +395,7 @@ static const struct vdpa_config_ops ifc_vdpa_ops = {
	.set_features	= ifcvf_vdpa_set_features,
	.get_status	= ifcvf_vdpa_get_status,
	.set_status	= ifcvf_vdpa_set_status,
	.reset		= ifcvf_vdpa_reset,
	.get_vq_num_max	= ifcvf_vdpa_get_vq_num_max,
	.get_vq_state	= ifcvf_vdpa_get_vq_state,
	.set_vq_state	= ifcvf_vdpa_set_vq_state,
@@ -392,6 +410,7 @@ static const struct vdpa_config_ops ifc_vdpa_ops = {
	.get_device_id	= ifcvf_vdpa_get_device_id,
	.get_vendor_id	= ifcvf_vdpa_get_vendor_id,
	.get_vq_align	= ifcvf_vdpa_get_vq_align,
	.get_config_size	= ifcvf_vdpa_get_config_size,
	.get_config	= ifcvf_vdpa_get_config,
	.set_config	= ifcvf_vdpa_set_config,
	.set_config_cb  = ifcvf_vdpa_set_config_cb,
@@ -438,8 +457,7 @@ static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
	}

	adapter = vdpa_alloc_device(struct ifcvf_adapter, vdpa,
				    dev, &ifc_vdpa_ops,
				    IFCVF_MAX_QUEUE_PAIRS * 2);
				    dev, &ifc_vdpa_ops, NULL);
	if (adapter == NULL) {
		IFCVF_ERR(pdev, "Failed to allocate vDPA structure");
		return -ENOMEM;
@@ -463,7 +481,7 @@ static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
	for (i = 0; i < IFCVF_MAX_QUEUE_PAIRS * 2; i++)
		vf->vring[i].irq = -EINVAL;

	ret = vdpa_register_device(&adapter->vdpa);
	ret = vdpa_register_device(&adapter->vdpa, IFCVF_MAX_QUEUE_PAIRS * 2);
	if (ret) {
		IFCVF_ERR(pdev, "Failed to register ifcvf to vdpa bus");
		goto err;
+28 −16
Original line number Diff line number Diff line
@@ -1405,8 +1405,8 @@ static int mlx5_vdpa_set_vq_state(struct vdpa_device *vdev, u16 idx,
		return -EINVAL;
	}

	mvq->used_idx = state->avail_index;
	mvq->avail_idx = state->avail_index;
	mvq->used_idx = state->split.avail_index;
	mvq->avail_idx = state->split.avail_index;
	return 0;
}

@@ -1427,7 +1427,7 @@ static int mlx5_vdpa_get_vq_state(struct vdpa_device *vdev, u16 idx, struct vdpa
		 * Since both values should be identical, we take the value of
		 * used_idx which is reported correctly.
		 */
		state->avail_index = mvq->used_idx;
		state->split.avail_index = mvq->used_idx;
		return 0;
	}

@@ -1436,7 +1436,7 @@ static int mlx5_vdpa_get_vq_state(struct vdpa_device *vdev, u16 idx, struct vdpa
		mlx5_vdpa_warn(mvdev, "failed to query virtqueue\n");
		return err;
	}
	state->avail_index = attr.used_index;
	state->split.avail_index = attr.used_index;
	return 0;
}

@@ -1778,16 +1778,6 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
	int err;

	print_status(mvdev, status, true);
	if (!status) {
		mlx5_vdpa_info(mvdev, "performing device reset\n");
		teardown_driver(ndev);
		clear_vqs_ready(ndev);
		mlx5_vdpa_destroy_mr(&ndev->mvdev);
		ndev->mvdev.status = 0;
		ndev->mvdev.mlx_features = 0;
		++mvdev->generation;
		return;
	}

	if ((status ^ ndev->mvdev.status) & VIRTIO_CONFIG_S_DRIVER_OK) {
		if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
@@ -1810,6 +1800,26 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
	ndev->mvdev.status |= VIRTIO_CONFIG_S_FAILED;
}

static int mlx5_vdpa_reset(struct vdpa_device *vdev)
{
	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);

	print_status(mvdev, 0, true);
	mlx5_vdpa_info(mvdev, "performing device reset\n");
	teardown_driver(ndev);
	clear_vqs_ready(ndev);
	mlx5_vdpa_destroy_mr(&ndev->mvdev);
	ndev->mvdev.status = 0;
	++mvdev->generation;
	return 0;
}

static size_t mlx5_vdpa_get_config_size(struct vdpa_device *vdev)
{
	return sizeof(struct virtio_net_config);
}

static void mlx5_vdpa_get_config(struct vdpa_device *vdev, unsigned int offset, void *buf,
				 unsigned int len)
{
@@ -1901,6 +1911,8 @@ static const struct vdpa_config_ops mlx5_vdpa_ops = {
	.get_vendor_id = mlx5_vdpa_get_vendor_id,
	.get_status = mlx5_vdpa_get_status,
	.set_status = mlx5_vdpa_set_status,
	.reset = mlx5_vdpa_reset,
	.get_config_size = mlx5_vdpa_get_config_size,
	.get_config = mlx5_vdpa_get_config,
	.set_config = mlx5_vdpa_set_config,
	.get_generation = mlx5_vdpa_get_generation,
@@ -1994,7 +2006,7 @@ void *mlx5_vdpa_add_dev(struct mlx5_core_dev *mdev)
	max_vqs = min_t(u32, max_vqs, MLX5_MAX_SUPPORTED_VQS);

	ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops,
				 2 * mlx5_vdpa_max_qps(max_vqs));
				 NULL);
	if (IS_ERR(ndev))
		return ndev;

@@ -2028,7 +2040,7 @@ void *mlx5_vdpa_add_dev(struct mlx5_core_dev *mdev)
	if (err)
		goto err_res;

	err = vdpa_register_device(&mvdev->vdev);
	err = vdpa_register_device(&mvdev->vdev, 2 * mlx5_vdpa_max_qps(max_vqs));
	if (err)
		goto err_reg;

Loading