[v3,03/10] vdpa/sfc: add support to get device and protocol features
Checks
Commit Message
From: Vijay Kumar Srivastava <vsrivast@xilinx.com>
Implement vDPA ops get_feature and get_protocol_features.
This patch retrieves device supported features and enables
protocol features.
Signed-off-by: Vijay Kumar Srivastava <vsrivast@xilinx.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
doc/guides/vdpadevs/features/sfc.ini | 10 ++++
drivers/common/sfc_efx/efsys.h | 2 +-
drivers/common/sfc_efx/version.map | 10 ++++
drivers/vdpa/sfc/sfc_vdpa.c | 20 ++++++++
drivers/vdpa/sfc/sfc_vdpa.h | 2 +
drivers/vdpa/sfc/sfc_vdpa_hw.c | 13 ++++++
drivers/vdpa/sfc/sfc_vdpa_ops.c | 91 ++++++++++++++++++++++++++++++++----
drivers/vdpa/sfc/sfc_vdpa_ops.h | 3 ++
8 files changed, 142 insertions(+), 9 deletions(-)
Comments
> -----Original Message-----
> From: Vijay Srivastava <vijay.srivastava@xilinx.com>
> Sent: Friday, October 29, 2021 10:47 PM
> To: dev@dpdk.org
> Cc: maxime.coquelin@redhat.com; Xia, Chenbo <chenbo.xia@intel.com>;
> andrew.rybchenko@oktetlabs.ru; Vijay Kumar Srivastava <vsrivast@xilinx.com>
> Subject: [PATCH v3 03/10] vdpa/sfc: add support to get device and protocol
> features
>
> From: Vijay Kumar Srivastava <vsrivast@xilinx.com>
>
> Implement vDPA ops get_feature and get_protocol_features.
> This patch retrieves device supported features and enables
> protocol features.
>
> Signed-off-by: Vijay Kumar Srivastava <vsrivast@xilinx.com>
> Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
> doc/guides/vdpadevs/features/sfc.ini | 10 ++++
> drivers/common/sfc_efx/efsys.h | 2 +-
> drivers/common/sfc_efx/version.map | 10 ++++
> drivers/vdpa/sfc/sfc_vdpa.c | 20 ++++++++
> drivers/vdpa/sfc/sfc_vdpa.h | 2 +
> drivers/vdpa/sfc/sfc_vdpa_hw.c | 13 ++++++
> drivers/vdpa/sfc/sfc_vdpa_ops.c | 91 ++++++++++++++++++++++++++++++++---
> -
> drivers/vdpa/sfc/sfc_vdpa_ops.h | 3 ++
> 8 files changed, 142 insertions(+), 9 deletions(-)
>
> diff --git a/doc/guides/vdpadevs/features/sfc.ini
> b/doc/guides/vdpadevs/features/sfc.ini
> index 71b6158..700d061 100644
> --- a/doc/guides/vdpadevs/features/sfc.ini
> +++ b/doc/guides/vdpadevs/features/sfc.ini
> @@ -4,6 +4,16 @@
> ; Refer to default.ini for the full list of available driver features.
> ;
> [Features]
> +csum = Y
> +guest csum = Y
> +host tso4 = Y
> +host tso6 = Y
> +version 1 = Y
> +mrg rxbuf = Y
> +any layout = Y
> +in_order = Y
> +proto host notifier = Y
> +IOMMU platform = Y
> Linux = Y
> x86-64 = Y
> Usage doc = Y
> diff --git a/drivers/common/sfc_efx/efsys.h b/drivers/common/sfc_efx/efsys.h
> index d133d61..37ec6b9 100644
> --- a/drivers/common/sfc_efx/efsys.h
> +++ b/drivers/common/sfc_efx/efsys.h
> @@ -187,7 +187,7 @@
>
> #define EFSYS_OPT_MAE 1
>
> -#define EFSYS_OPT_VIRTIO 0
> +#define EFSYS_OPT_VIRTIO 1
>
> /* ID */
>
> diff --git a/drivers/common/sfc_efx/version.map
> b/drivers/common/sfc_efx/version.map
> index 642a62e..ec86220 100644
> --- a/drivers/common/sfc_efx/version.map
> +++ b/drivers/common/sfc_efx/version.map
> @@ -247,6 +247,16 @@ INTERNAL {
> efx_txq_nbufs;
> efx_txq_size;
>
> + efx_virtio_fini;
> + efx_virtio_get_doorbell_offset;
> + efx_virtio_get_features;
> + efx_virtio_init;
> + efx_virtio_qcreate;
> + efx_virtio_qdestroy;
> + efx_virtio_qstart;
> + efx_virtio_qstop;
> + efx_virtio_verify_features;
> +
> sfc_efx_dev_class_get;
> sfc_efx_family;
>
> diff --git a/drivers/vdpa/sfc/sfc_vdpa.c b/drivers/vdpa/sfc/sfc_vdpa.c
> index b7eca56..ccbd243 100644
> --- a/drivers/vdpa/sfc/sfc_vdpa.c
> +++ b/drivers/vdpa/sfc/sfc_vdpa.c
> @@ -43,6 +43,26 @@ struct sfc_vdpa_adapter *
> return found ? sva : NULL;
> }
>
> +struct sfc_vdpa_ops_data *
> +sfc_vdpa_get_data_by_dev(struct rte_vdpa_device *vdpa_dev)
> +{
> + bool found = false;
> + struct sfc_vdpa_adapter *sva;
> +
> + pthread_mutex_lock(&sfc_vdpa_adapter_list_lock);
> +
> + TAILQ_FOREACH(sva, &sfc_vdpa_adapter_list, next) {
> + if (vdpa_dev == sva->ops_data->vdpa_dev) {
> + found = true;
> + break;
> + }
> + }
> +
> + pthread_mutex_unlock(&sfc_vdpa_adapter_list_lock);
> +
> + return found ? sva->ops_data : NULL;
> +}
> +
> static int
> sfc_vdpa_vfio_setup(struct sfc_vdpa_adapter *sva)
> {
> diff --git a/drivers/vdpa/sfc/sfc_vdpa.h b/drivers/vdpa/sfc/sfc_vdpa.h
> index 046f25d..c10c3d3 100644
> --- a/drivers/vdpa/sfc/sfc_vdpa.h
> +++ b/drivers/vdpa/sfc/sfc_vdpa.h
> @@ -60,6 +60,8 @@ struct sfc_vdpa_adapter {
>
> struct sfc_vdpa_adapter *
> sfc_vdpa_get_adapter_by_dev(struct rte_pci_device *pdev);
> +struct sfc_vdpa_ops_data *
> +sfc_vdpa_get_data_by_dev(struct rte_vdpa_device *vdpa_dev);
>
> int
> sfc_vdpa_hw_init(struct sfc_vdpa_adapter *sva);
> diff --git a/drivers/vdpa/sfc/sfc_vdpa_hw.c b/drivers/vdpa/sfc/sfc_vdpa_hw.c
> index 7c256ff..7a67bd8 100644
> --- a/drivers/vdpa/sfc/sfc_vdpa_hw.c
> +++ b/drivers/vdpa/sfc/sfc_vdpa_hw.c
> @@ -278,10 +278,20 @@
> if (rc != 0)
> goto fail_estimate_rsrc_limits;
>
> + sfc_vdpa_log_init(sva, "init virtio");
> + rc = efx_virtio_init(enp);
> + if (rc != 0) {
> + sfc_vdpa_err(sva, "virtio init failed: %s", rte_strerror(rc));
> + goto fail_virtio_init;
> + }
> +
> sfc_vdpa_log_init(sva, "done");
>
> return 0;
>
> +fail_virtio_init:
> + efx_nic_fini(enp);
> +
> fail_estimate_rsrc_limits:
> fail_nic_reset:
> efx_nic_unprobe(enp);
> @@ -310,6 +320,9 @@
>
> sfc_vdpa_log_init(sva, "entry");
>
> + sfc_vdpa_log_init(sva, "virtio fini");
> + efx_virtio_fini(enp);
> +
> sfc_vdpa_log_init(sva, "unprobe nic");
> efx_nic_unprobe(enp);
>
> diff --git a/drivers/vdpa/sfc/sfc_vdpa_ops.c b/drivers/vdpa/sfc/sfc_vdpa_ops.c
> index 71696be..5750944 100644
> --- a/drivers/vdpa/sfc/sfc_vdpa_ops.c
> +++ b/drivers/vdpa/sfc/sfc_vdpa_ops.c
> @@ -3,17 +3,31 @@
> * Copyright(c) 2020-2021 Xilinx, Inc.
> */
>
> +#include <rte_errno.h>
> #include <rte_malloc.h>
> #include <rte_vdpa.h>
> #include <rte_vdpa_dev.h>
> #include <rte_vhost.h>
>
> +#include "efx.h"
> #include "sfc_vdpa_ops.h"
> #include "sfc_vdpa.h"
>
> -/* Dummy functions for mandatory vDPA ops to pass vDPA device registration.
> - * In subsequent patches these ops would be implemented.
> +/* These protocol features are needed to enable notifier ctrl */
> +#define SFC_VDPA_PROTOCOL_FEATURES \
> + ((1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK) | \
> + (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))
> +
> +/*
> + * Set of features which are enabled by default.
> + * Protocol feature bit is needed to enable notification notifier ctrl.
> */
> +#define SFC_VDPA_DEFAULT_FEATURES \
> + (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)
> +
> static int
> sfc_vdpa_get_queue_num(struct rte_vdpa_device *vdpa_dev, uint32_t *queue_num)
> {
> @@ -24,22 +38,67 @@
> }
>
> static int
> +sfc_vdpa_get_device_features(struct sfc_vdpa_ops_data *ops_data)
> +{
> + int rc;
> + uint64_t dev_features;
> + efx_nic_t *nic;
> +
> + nic = sfc_vdpa_adapter_by_dev_handle(ops_data->dev_handle)->nic;
> +
> + rc = efx_virtio_get_features(nic, EFX_VIRTIO_DEVICE_TYPE_NET,
> + &dev_features);
> + if (rc != 0) {
> + sfc_vdpa_err(ops_data->dev_handle,
> + "could not read device feature: %s",
> + rte_strerror(rc));
> + return rc;
> + }
> +
> + ops_data->dev_features = dev_features;
> +
> + sfc_vdpa_info(ops_data->dev_handle,
> + "device supported virtio features : 0x%" PRIx64,
> + ops_data->dev_features);
> +
> + return 0;
> +}
> +
> +static int
> sfc_vdpa_get_features(struct rte_vdpa_device *vdpa_dev, uint64_t *features)
> {
> - RTE_SET_USED(vdpa_dev);
> - RTE_SET_USED(features);
> + struct sfc_vdpa_ops_data *ops_data;
>
> - return -1;
> + ops_data = sfc_vdpa_get_data_by_dev(vdpa_dev);
> + if (ops_data == NULL)
> + return -1;
> +
> + *features = ops_data->drv_features;
> +
> + sfc_vdpa_info(ops_data->dev_handle,
> + "vDPA ops get_feature :: features : 0x%" PRIx64,
> + *features);
> +
> + return 0;
> }
>
> static int
> sfc_vdpa_get_protocol_features(struct rte_vdpa_device *vdpa_dev,
> uint64_t *features)
> {
> - RTE_SET_USED(vdpa_dev);
> - RTE_SET_USED(features);
> + struct sfc_vdpa_ops_data *ops_data;
>
> - return -1;
> + ops_data = sfc_vdpa_get_data_by_dev(vdpa_dev);
> + if (ops_data == NULL)
> + return -1;
> +
> + *features = SFC_VDPA_PROTOCOL_FEATURES;
> +
> + sfc_vdpa_info(ops_data->dev_handle,
> + "vDPA ops get_protocol_feature :: features : 0x%" PRIx64,
> + *features);
> +
> + return 0;
> }
>
> static int
> @@ -91,6 +150,7 @@ struct sfc_vdpa_ops_data *
> {
> struct sfc_vdpa_ops_data *ops_data;
> struct rte_pci_device *pci_dev;
> + int rc;
>
> /* Create vDPA ops context */
> ops_data = rte_zmalloc("vdpa", sizeof(struct sfc_vdpa_ops_data), 0);
> @@ -111,10 +171,25 @@ struct sfc_vdpa_ops_data *
> goto fail_register_device;
> }
>
> + /* Read supported device features */
> + sfc_vdpa_log_init(dev_handle, "get device feature");
> + rc = sfc_vdpa_get_device_features(ops_data);
> + if (rc != 0)
> + goto fail_get_dev_feature;
> +
> + /* Driver features are superset of device supported feature
> + * and any additional features supported by the driver.
> + */
> + ops_data->drv_features =
> + ops_data->dev_features | SFC_VDPA_DEFAULT_FEATURES;
> +
> ops_data->state = SFC_VDPA_STATE_INITIALIZED;
>
> return ops_data;
>
> +fail_get_dev_feature:
> + rte_vdpa_unregister_device(ops_data->vdpa_dev);
> +
> fail_register_device:
> rte_free(ops_data);
> return NULL;
> diff --git a/drivers/vdpa/sfc/sfc_vdpa_ops.h b/drivers/vdpa/sfc/sfc_vdpa_ops.h
> index 817b302..21cbb73 100644
> --- a/drivers/vdpa/sfc/sfc_vdpa_ops.h
> +++ b/drivers/vdpa/sfc/sfc_vdpa_ops.h
> @@ -26,6 +26,9 @@ struct sfc_vdpa_ops_data {
> struct rte_vdpa_device *vdpa_dev;
> enum sfc_vdpa_context vdpa_context;
> enum sfc_vdpa_state state;
> +
> + uint64_t dev_features;
> + uint64_t drv_features;
> };
>
> struct sfc_vdpa_ops_data *
> --
> 1.8.3.1
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
@@ -4,6 +4,16 @@
; Refer to default.ini for the full list of available driver features.
;
[Features]
+csum = Y
+guest csum = Y
+host tso4 = Y
+host tso6 = Y
+version 1 = Y
+mrg rxbuf = Y
+any layout = Y
+in_order = Y
+proto host notifier = Y
+IOMMU platform = Y
Linux = Y
x86-64 = Y
Usage doc = Y
@@ -187,7 +187,7 @@
#define EFSYS_OPT_MAE 1
-#define EFSYS_OPT_VIRTIO 0
+#define EFSYS_OPT_VIRTIO 1
/* ID */
@@ -247,6 +247,16 @@ INTERNAL {
efx_txq_nbufs;
efx_txq_size;
+ efx_virtio_fini;
+ efx_virtio_get_doorbell_offset;
+ efx_virtio_get_features;
+ efx_virtio_init;
+ efx_virtio_qcreate;
+ efx_virtio_qdestroy;
+ efx_virtio_qstart;
+ efx_virtio_qstop;
+ efx_virtio_verify_features;
+
sfc_efx_dev_class_get;
sfc_efx_family;
@@ -43,6 +43,26 @@ struct sfc_vdpa_adapter *
return found ? sva : NULL;
}
+struct sfc_vdpa_ops_data *
+sfc_vdpa_get_data_by_dev(struct rte_vdpa_device *vdpa_dev)
+{
+ bool found = false;
+ struct sfc_vdpa_adapter *sva;
+
+ pthread_mutex_lock(&sfc_vdpa_adapter_list_lock);
+
+ TAILQ_FOREACH(sva, &sfc_vdpa_adapter_list, next) {
+ if (vdpa_dev == sva->ops_data->vdpa_dev) {
+ found = true;
+ break;
+ }
+ }
+
+ pthread_mutex_unlock(&sfc_vdpa_adapter_list_lock);
+
+ return found ? sva->ops_data : NULL;
+}
+
static int
sfc_vdpa_vfio_setup(struct sfc_vdpa_adapter *sva)
{
@@ -60,6 +60,8 @@ struct sfc_vdpa_adapter {
struct sfc_vdpa_adapter *
sfc_vdpa_get_adapter_by_dev(struct rte_pci_device *pdev);
+struct sfc_vdpa_ops_data *
+sfc_vdpa_get_data_by_dev(struct rte_vdpa_device *vdpa_dev);
int
sfc_vdpa_hw_init(struct sfc_vdpa_adapter *sva);
@@ -278,10 +278,20 @@
if (rc != 0)
goto fail_estimate_rsrc_limits;
+ sfc_vdpa_log_init(sva, "init virtio");
+ rc = efx_virtio_init(enp);
+ if (rc != 0) {
+ sfc_vdpa_err(sva, "virtio init failed: %s", rte_strerror(rc));
+ goto fail_virtio_init;
+ }
+
sfc_vdpa_log_init(sva, "done");
return 0;
+fail_virtio_init:
+ efx_nic_fini(enp);
+
fail_estimate_rsrc_limits:
fail_nic_reset:
efx_nic_unprobe(enp);
@@ -310,6 +320,9 @@
sfc_vdpa_log_init(sva, "entry");
+ sfc_vdpa_log_init(sva, "virtio fini");
+ efx_virtio_fini(enp);
+
sfc_vdpa_log_init(sva, "unprobe nic");
efx_nic_unprobe(enp);
@@ -3,17 +3,31 @@
* Copyright(c) 2020-2021 Xilinx, Inc.
*/
+#include <rte_errno.h>
#include <rte_malloc.h>
#include <rte_vdpa.h>
#include <rte_vdpa_dev.h>
#include <rte_vhost.h>
+#include "efx.h"
#include "sfc_vdpa_ops.h"
#include "sfc_vdpa.h"
-/* Dummy functions for mandatory vDPA ops to pass vDPA device registration.
- * In subsequent patches these ops would be implemented.
+/* These protocol features are needed to enable notifier ctrl */
+#define SFC_VDPA_PROTOCOL_FEATURES \
+ ((1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK) | \
+ (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))
+
+/*
+ * Set of features which are enabled by default.
+ * Protocol feature bit is needed to enable notification notifier ctrl.
*/
+#define SFC_VDPA_DEFAULT_FEATURES \
+ (1ULL << VHOST_USER_F_PROTOCOL_FEATURES)
+
static int
sfc_vdpa_get_queue_num(struct rte_vdpa_device *vdpa_dev, uint32_t *queue_num)
{
@@ -24,22 +38,67 @@
}
static int
+sfc_vdpa_get_device_features(struct sfc_vdpa_ops_data *ops_data)
+{
+ int rc;
+ uint64_t dev_features;
+ efx_nic_t *nic;
+
+ nic = sfc_vdpa_adapter_by_dev_handle(ops_data->dev_handle)->nic;
+
+ rc = efx_virtio_get_features(nic, EFX_VIRTIO_DEVICE_TYPE_NET,
+ &dev_features);
+ if (rc != 0) {
+ sfc_vdpa_err(ops_data->dev_handle,
+ "could not read device feature: %s",
+ rte_strerror(rc));
+ return rc;
+ }
+
+ ops_data->dev_features = dev_features;
+
+ sfc_vdpa_info(ops_data->dev_handle,
+ "device supported virtio features : 0x%" PRIx64,
+ ops_data->dev_features);
+
+ return 0;
+}
+
+static int
sfc_vdpa_get_features(struct rte_vdpa_device *vdpa_dev, uint64_t *features)
{
- RTE_SET_USED(vdpa_dev);
- RTE_SET_USED(features);
+ struct sfc_vdpa_ops_data *ops_data;
- return -1;
+ ops_data = sfc_vdpa_get_data_by_dev(vdpa_dev);
+ if (ops_data == NULL)
+ return -1;
+
+ *features = ops_data->drv_features;
+
+ sfc_vdpa_info(ops_data->dev_handle,
+ "vDPA ops get_feature :: features : 0x%" PRIx64,
+ *features);
+
+ return 0;
}
static int
sfc_vdpa_get_protocol_features(struct rte_vdpa_device *vdpa_dev,
uint64_t *features)
{
- RTE_SET_USED(vdpa_dev);
- RTE_SET_USED(features);
+ struct sfc_vdpa_ops_data *ops_data;
- return -1;
+ ops_data = sfc_vdpa_get_data_by_dev(vdpa_dev);
+ if (ops_data == NULL)
+ return -1;
+
+ *features = SFC_VDPA_PROTOCOL_FEATURES;
+
+ sfc_vdpa_info(ops_data->dev_handle,
+ "vDPA ops get_protocol_feature :: features : 0x%" PRIx64,
+ *features);
+
+ return 0;
}
static int
@@ -91,6 +150,7 @@ struct sfc_vdpa_ops_data *
{
struct sfc_vdpa_ops_data *ops_data;
struct rte_pci_device *pci_dev;
+ int rc;
/* Create vDPA ops context */
ops_data = rte_zmalloc("vdpa", sizeof(struct sfc_vdpa_ops_data), 0);
@@ -111,10 +171,25 @@ struct sfc_vdpa_ops_data *
goto fail_register_device;
}
+ /* Read supported device features */
+ sfc_vdpa_log_init(dev_handle, "get device feature");
+ rc = sfc_vdpa_get_device_features(ops_data);
+ if (rc != 0)
+ goto fail_get_dev_feature;
+
+ /* Driver features are superset of device supported feature
+ * and any additional features supported by the driver.
+ */
+ ops_data->drv_features =
+ ops_data->dev_features | SFC_VDPA_DEFAULT_FEATURES;
+
ops_data->state = SFC_VDPA_STATE_INITIALIZED;
return ops_data;
+fail_get_dev_feature:
+ rte_vdpa_unregister_device(ops_data->vdpa_dev);
+
fail_register_device:
rte_free(ops_data);
return NULL;
@@ -26,6 +26,9 @@ struct sfc_vdpa_ops_data {
struct rte_vdpa_device *vdpa_dev;
enum sfc_vdpa_context vdpa_context;
enum sfc_vdpa_state state;
+
+ uint64_t dev_features;
+ uint64_t drv_features;
};
struct sfc_vdpa_ops_data *