[Intel-wired-lan] [PATCH net-next v3 3/6] iavf: Add framework to enable ethtool RSS config
Jankowski, Konrad0
konrad0.jankowski at intel.com
Wed Apr 21 19:23:31 UTC 2021
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces at osuosl.org> On Behalf Of
> Haiyue Wang
> Sent: wtorek, 13 kwietnia 2021 02:49
> To: intel-wired-lan at lists.osuosl.org
> Cc: Zhang, Qi Z <qi.z.zhang at intel.com>
> Subject: [Intel-wired-lan] [PATCH net-next v3 3/6] iavf: Add framework to
> enable ethtool RSS config
>
> Add the virtchnl message interface to VF, so that VF can request RSS input
> set(s) based on PF's capability.
>
> This framework allows ethtool RSS config support on the VF driver.
>
> Signed-off-by: Haiyue Wang <haiyue.wang at intel.com>
> ---
> drivers/net/ethernet/intel/iavf/iavf.h | 10 ++
> .../net/ethernet/intel/iavf/iavf_adv_rss.h | 25 +++
> drivers/net/ethernet/intel/iavf/iavf_main.c | 27 ++++
> .../net/ethernet/intel/iavf/iavf_virtchnl.c | 152 ++++++++++++++++++
> 4 files changed, 214 insertions(+)
> create mode 100644 drivers/net/ethernet/intel/iavf/iavf_adv_rss.h
>
> diff --git a/drivers/net/ethernet/intel/iavf/iavf.h
> b/drivers/net/ethernet/intel/iavf/iavf.h
> index 09e5b9cf5719..1e996d9c1351 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf.h
> +++ b/drivers/net/ethernet/intel/iavf/iavf.h
> @@ -38,6 +38,7 @@
> #include <linux/avf/virtchnl.h>
> #include "iavf_txrx.h"
> #include "iavf_fdir.h"
> +#include "iavf_adv_rss.h"
>
> #define DEFAULT_DEBUG_LEVEL_SHIFT 3
> #define PFX "iavf: "
> @@ -304,6 +305,8 @@ struct iavf_adapter {
> #define IAVF_FLAG_AQ_DEL_CLOUD_FILTER BIT(24)
> #define IAVF_FLAG_AQ_ADD_FDIR_FILTER BIT(25)
> #define IAVF_FLAG_AQ_DEL_FDIR_FILTER BIT(26)
> +#define IAVF_FLAG_AQ_ADD_ADV_RSS_CFG BIT(27)
> +#define IAVF_FLAG_AQ_DEL_ADV_RSS_CFG BIT(28)
>
> /* OS defined structs */
> struct net_device *netdev;
> @@ -346,6 +349,8 @@ struct iavf_adapter {
> VIRTCHNL_VF_CAP_ADV_LINK_SPEED) #define
> FDIR_FLTR_SUPPORT(_a) ((_a)->vf_res->vf_cap_flags & \
> VIRTCHNL_VF_OFFLOAD_FDIR_PF)
> +#define ADV_RSS_SUPPORT(_a) ((_a)->vf_res->vf_cap_flags & \
> + VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF)
> struct virtchnl_vf_resource *vf_res; /* incl. all VSIs */
> struct virtchnl_vsi_resource *vsi_res; /* our LAN VSI */
> struct virtchnl_version_info pf_version; @@ -373,6 +378,9 @@ struct
> iavf_adapter {
> u16 fdir_active_fltr;
> struct list_head fdir_list_head;
> spinlock_t fdir_fltr_lock; /* protect the Flow Director filter list
> */
> +
> + struct list_head adv_rss_list_head;
> + spinlock_t adv_rss_lock; /* protect the RSS management list
> */
> };
>
>
> @@ -445,6 +453,8 @@ void iavf_add_cloud_filter(struct iavf_adapter
> *adapter); void iavf_del_cloud_filter(struct iavf_adapter *adapter); void
> iavf_add_fdir_filter(struct iavf_adapter *adapter); void
> iavf_del_fdir_filter(struct iavf_adapter *adapter);
> +void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter); void
> +iavf_del_adv_rss_cfg(struct iavf_adapter *adapter);
> struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter,
> const u8 *macaddr);
> #endif /* _IAVF_H_ */
> diff --git a/drivers/net/ethernet/intel/iavf/iavf_adv_rss.h
> b/drivers/net/ethernet/intel/iavf/iavf_adv_rss.h
> new file mode 100644
> index 000000000000..66262090e697
> --- /dev/null
> +++ b/drivers/net/ethernet/intel/iavf/iavf_adv_rss.h
> @@ -0,0 +1,25 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright (c) 2021, Intel Corporation. */
> +
> +#ifndef _IAVF_ADV_RSS_H_
> +#define _IAVF_ADV_RSS_H_
> +
> +struct iavf_adapter;
> +
> +/* State of advanced RSS configuration */ enum iavf_adv_rss_state_t {
> + IAVF_ADV_RSS_ADD_REQUEST, /* User requests to add RSS
> */
> + IAVF_ADV_RSS_ADD_PENDING, /* RSS pending add by the PF
> */
> + IAVF_ADV_RSS_DEL_REQUEST, /* Driver requests to delete
> RSS */
> + IAVF_ADV_RSS_DEL_PENDING, /* RSS pending delete by the
> PF */
> + IAVF_ADV_RSS_ACTIVE, /* RSS configuration is active
> */
> +};
> +
> +/* bookkeeping of advanced RSS configuration */ struct iavf_adv_rss {
> + enum iavf_adv_rss_state_t state;
> + struct list_head list;
> +
> + struct virtchnl_rss_cfg cfg_msg;
> +};
> +#endif /* _IAVF_ADV_RSS_H_ */
> diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c
> b/drivers/net/ethernet/intel/iavf/iavf_main.c
> index 357e66e866b7..1323778f461d 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf_main.c
> +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
> @@ -962,6 +962,7 @@ void iavf_down(struct iavf_adapter *adapter)
> struct iavf_cloud_filter *cf;
> struct iavf_fdir_fltr *fdir;
> struct iavf_mac_filter *f;
> + struct iavf_adv_rss *rss;
>
> if (adapter->state <= __IAVF_DOWN_PENDING)
> return;
> @@ -1004,6 +1005,12 @@ void iavf_down(struct iavf_adapter *adapter)
> }
> spin_unlock_bh(&adapter->fdir_fltr_lock);
>
> + /* remove all advance RSS configuration */
> + spin_lock_bh(&adapter->adv_rss_lock);
> + list_for_each_entry(rss, &adapter->adv_rss_list_head, list)
> + rss->state = IAVF_ADV_RSS_DEL_REQUEST;
> + spin_unlock_bh(&adapter->adv_rss_lock);
> +
> if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) &&
> adapter->state != __IAVF_RESETTING) {
> /* cancel any current operation */
> @@ -1016,6 +1023,7 @@ void iavf_down(struct iavf_adapter *adapter)
> adapter->aq_required |=
> IAVF_FLAG_AQ_DEL_VLAN_FILTER;
> adapter->aq_required |=
> IAVF_FLAG_AQ_DEL_CLOUD_FILTER;
> adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER;
> + adapter->aq_required |=
> IAVF_FLAG_AQ_DEL_ADV_RSS_CFG;
> adapter->aq_required |=
> IAVF_FLAG_AQ_DISABLE_QUEUES;
> }
>
> @@ -1646,6 +1654,14 @@ static int iavf_process_aq_command(struct
> iavf_adapter *adapter)
> iavf_del_fdir_filter(adapter);
> return IAVF_SUCCESS;
> }
> + if (adapter->aq_required & IAVF_FLAG_AQ_ADD_ADV_RSS_CFG) {
> + iavf_add_adv_rss_cfg(adapter);
> + return 0;
> + }
> + if (adapter->aq_required & IAVF_FLAG_AQ_DEL_ADV_RSS_CFG) {
> + iavf_del_adv_rss_cfg(adapter);
> + return 0;
> + }
> return -EAGAIN;
> }
>
> @@ -3776,11 +3792,13 @@ static int iavf_probe(struct pci_dev *pdev, const
> struct pci_device_id *ent)
> spin_lock_init(&adapter->mac_vlan_list_lock);
> spin_lock_init(&adapter->cloud_filter_list_lock);
> spin_lock_init(&adapter->fdir_fltr_lock);
> + spin_lock_init(&adapter->adv_rss_lock);
>
> INIT_LIST_HEAD(&adapter->mac_filter_list);
> INIT_LIST_HEAD(&adapter->vlan_filter_list);
> INIT_LIST_HEAD(&adapter->cloud_filter_list);
> INIT_LIST_HEAD(&adapter->fdir_list_head);
> + INIT_LIST_HEAD(&adapter->adv_rss_list_head);
>
> INIT_WORK(&adapter->reset_task, iavf_reset_task);
> INIT_WORK(&adapter->adminq_task, iavf_adminq_task); @@ -
> 3886,6 +3904,7 @@ static void iavf_remove(struct pci_dev *pdev)
> struct iavf_adapter *adapter = netdev_priv(netdev);
> struct iavf_fdir_fltr *fdir, *fdirtmp;
> struct iavf_vlan_filter *vlf, *vlftmp;
> + struct iavf_adv_rss *rss, *rsstmp;
> struct iavf_mac_filter *f, *ftmp;
> struct iavf_cloud_filter *cf, *cftmp;
> struct iavf_hw *hw = &adapter->hw;
> @@ -3969,6 +3988,14 @@ static void iavf_remove(struct pci_dev *pdev)
> }
> spin_unlock_bh(&adapter->fdir_fltr_lock);
>
> + spin_lock_bh(&adapter->adv_rss_lock);
> + list_for_each_entry_safe(rss, rsstmp, &adapter->adv_rss_list_head,
> + list) {
> + list_del(&rss->list);
> + kfree(rss);
> + }
> + spin_unlock_bh(&adapter->adv_rss_lock);
> +
> free_netdev(netdev);
>
> pci_disable_pcie_error_reporting(pdev);
> diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> index 9aaade0aae4c..54d2efe1732d 100644
> --- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> +++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
> @@ -142,6 +142,7 @@ int iavf_send_vf_config_msg(struct iavf_adapter
> *adapter)
> VIRTCHNL_VF_OFFLOAD_ADQ |
> VIRTCHNL_VF_OFFLOAD_USO |
> VIRTCHNL_VF_OFFLOAD_FDIR_PF |
> + VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF |
> VIRTCHNL_VF_CAP_ADV_LINK_SPEED;
>
> adapter->current_op = VIRTCHNL_OP_GET_VF_RESOURCES; @@ -
> 1294,6 +1295,102 @@ void iavf_del_fdir_filter(struct iavf_adapter *adapter)
> iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_FDIR_FILTER, (u8
> *)&f, len); }
>
> +/**
> + * iavf_add_adv_rss_cfg
> + * @adapter: the VF adapter structure
> + *
> + * Request that the PF add RSS configuration as specified
> + * by the user via ethtool.
> + **/
> +void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter) {
> + struct virtchnl_rss_cfg *rss_cfg;
> + struct iavf_adv_rss *rss;
> + bool process_rss = false;
> + int len;
> +
> + if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
> + /* bail because we already have a command pending */
> + dev_err(&adapter->pdev->dev, "Cannot add RSS
> configuration, command %d pending\n",
> + adapter->current_op);
> + return;
> + }
> +
> + len = sizeof(struct virtchnl_rss_cfg);
> + rss_cfg = kzalloc(len, GFP_KERNEL);
> + if (!rss_cfg)
> + return;
> +
> + spin_lock_bh(&adapter->adv_rss_lock);
> + list_for_each_entry(rss, &adapter->adv_rss_list_head, list) {
> + if (rss->state == IAVF_ADV_RSS_ADD_REQUEST) {
> + process_rss = true;
> + rss->state = IAVF_ADV_RSS_ADD_PENDING;
> + memcpy(rss_cfg, &rss->cfg_msg, len);
> + break;
> + }
> + }
> + spin_unlock_bh(&adapter->adv_rss_lock);
> +
> + if (process_rss) {
> + adapter->current_op = VIRTCHNL_OP_ADD_RSS_CFG;
> + iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_RSS_CFG,
> + (u8 *)rss_cfg, len);
> + } else {
> + adapter->aq_required &=
> ~IAVF_FLAG_AQ_ADD_ADV_RSS_CFG;
> + }
> +
> + kfree(rss_cfg);
> +}
> +
> +/**
> + * iavf_del_adv_rss_cfg
> + * @adapter: the VF adapter structure
> + *
> + * Request that the PF delete RSS configuration as specified
> + * by the user via ethtool.
> + **/
> +void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter) {
> + struct virtchnl_rss_cfg *rss_cfg;
> + struct iavf_adv_rss *rss;
> + bool process_rss = false;
> + int len;
> +
> + if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
> + /* bail because we already have a command pending */
> + dev_err(&adapter->pdev->dev, "Cannot remove RSS
> configuration, command %d pending\n",
> + adapter->current_op);
> + return;
> + }
> +
> + len = sizeof(struct virtchnl_rss_cfg);
> + rss_cfg = kzalloc(len, GFP_KERNEL);
> + if (!rss_cfg)
> + return;
> +
> + spin_lock_bh(&adapter->adv_rss_lock);
> + list_for_each_entry(rss, &adapter->adv_rss_list_head, list) {
> + if (rss->state == IAVF_ADV_RSS_DEL_REQUEST) {
> + process_rss = true;
> + rss->state = IAVF_ADV_RSS_DEL_PENDING;
> + memcpy(rss_cfg, &rss->cfg_msg, len);
> + break;
> + }
> + }
> + spin_unlock_bh(&adapter->adv_rss_lock);
> +
> + if (process_rss) {
> + adapter->current_op = VIRTCHNL_OP_DEL_RSS_CFG;
> + iavf_send_pf_msg(adapter, VIRTCHNL_OP_DEL_RSS_CFG,
> + (u8 *)rss_cfg, len);
> + } else {
> + adapter->aq_required &=
> ~IAVF_FLAG_AQ_DEL_ADV_RSS_CFG;
> + }
> +
> + kfree(rss_cfg);
> +}
> +
> /**
> * iavf_request_reset
> * @adapter: adapter structure
> @@ -1494,6 +1591,37 @@ void iavf_virtchnl_completion(struct iavf_adapter
> *adapter,
> spin_unlock_bh(&adapter->fdir_fltr_lock);
> }
> break;
> + case VIRTCHNL_OP_ADD_RSS_CFG: {
> + struct iavf_adv_rss *rss, *rss_tmp;
> +
> + spin_lock_bh(&adapter->adv_rss_lock);
> + list_for_each_entry_safe(rss, rss_tmp,
> + &adapter-
> >adv_rss_list_head,
> + list) {
> + if (rss->state ==
> IAVF_ADV_RSS_ADD_PENDING) {
> + list_del(&rss->list);
> + kfree(rss);
> + }
> + }
> + spin_unlock_bh(&adapter->adv_rss_lock);
> + }
> + break;
> + case VIRTCHNL_OP_DEL_RSS_CFG: {
> + struct iavf_adv_rss *rss;
> +
> + spin_lock_bh(&adapter->adv_rss_lock);
> + list_for_each_entry(rss, &adapter-
> >adv_rss_list_head,
> + list) {
> + if (rss->state ==
> IAVF_ADV_RSS_DEL_PENDING) {
> + rss->state = IAVF_ADV_RSS_ACTIVE;
> + dev_err(&adapter->pdev->dev,
> "Failed to delete RSS configuration, error %s\n",
> + iavf_stat_str(&adapter->hw,
> + v_retval));
> + }
> + }
> + spin_unlock_bh(&adapter->adv_rss_lock);
> + }
> + break;
> case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
> case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:
> dev_warn(&adapter->pdev->dev, "Changing VLAN
> Stripping is not allowed when Port VLAN is configured\n"); @@ -1683,6
> +1811,30 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
> spin_unlock_bh(&adapter->fdir_fltr_lock);
> }
> break;
> + case VIRTCHNL_OP_ADD_RSS_CFG: {
> + struct iavf_adv_rss *rss;
> +
> + spin_lock_bh(&adapter->adv_rss_lock);
> + list_for_each_entry(rss, &adapter->adv_rss_list_head, list)
> + if (rss->state == IAVF_ADV_RSS_ADD_PENDING)
> + rss->state = IAVF_ADV_RSS_ACTIVE;
> + spin_unlock_bh(&adapter->adv_rss_lock);
> + }
> + break;
> + case VIRTCHNL_OP_DEL_RSS_CFG: {
> + struct iavf_adv_rss *rss, *rss_tmp;
> +
> + spin_lock_bh(&adapter->adv_rss_lock);
> + list_for_each_entry_safe(rss, rss_tmp,
> + &adapter->adv_rss_list_head, list) {
> + if (rss->state == IAVF_ADV_RSS_DEL_PENDING) {
> + list_del(&rss->list);
> + kfree(rss);
> + }
> + }
> + spin_unlock_bh(&adapter->adv_rss_lock);
> + }
> + break;
> default:
> if (adapter->current_op && (v_opcode != adapter-
> >current_op))
> dev_warn(&adapter->pdev->dev, "Expected
> response %d from PF, received %d\n",
Tested-by: Konrad Jankowski <konrad0.jankowski at intel.com>
More information about the Intel-wired-lan
mailing list