netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Gautam Dawar <gdawar@amd.com>
To: Jason Wang <jasowang@redhat.com>, Gautam Dawar <gautam.dawar@amd.com>
Cc: linux-net-drivers@amd.com, netdev@vger.kernel.org,
	eperezma@redhat.com, tanuj.kamde@amd.com, Koushik.Dutta@amd.com,
	harpreet.anand@amd.com, Edward Cree <ecree.xilinx@gmail.com>,
	Martin Habets <habetsm.xilinx@gmail.com>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH net-next 07/11] sfc: implement filters for receiving traffic
Date: Thu, 5 Jan 2023 18:16:32 +0530	[thread overview]
Message-ID: <a936c0e3-8f65-af51-b0c3-a907f414e0c7@amd.com> (raw)
In-Reply-To: <CACGkMEsgJCniBiggqX4V+quhBY-Dj1Jnr7H+YD4w6gESOX1SmQ@mail.gmail.com>


On 12/14/22 12:15, Jason Wang wrote:
> Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding.
>
>
> On Wed, Dec 7, 2022 at 10:57 PM Gautam Dawar <gautam.dawar@amd.com> wrote:
>> Implement unicast, broadcast and unknown multicast
>> filters for receiving different types of traffic.
> I suggest squashing this into the patch that implements set_config().

The patch that implements set_config() also implements device level vdpa 
config operations. I think that squashing the filtering support (this 
patch) in to that patch will make it unnecessary long and combine lot of 
unrelated functionality (except the call to configure filters in 
set_config operation).

>
>> Signed-off-by: Gautam Dawar <gautam.dawar@amd.com>
>> ---
>>   drivers/net/ethernet/sfc/ef100_vdpa.c     | 159 ++++++++++++++++++++++
>>   drivers/net/ethernet/sfc/ef100_vdpa.h     |  35 +++++
>>   drivers/net/ethernet/sfc/ef100_vdpa_ops.c |  27 +++-
>>   3 files changed, 220 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/ethernet/sfc/ef100_vdpa.c b/drivers/net/ethernet/sfc/ef100_vdpa.c
>> index 41eb7aef6798..04d64bfe3c93 100644
>> --- a/drivers/net/ethernet/sfc/ef100_vdpa.c
>> +++ b/drivers/net/ethernet/sfc/ef100_vdpa.c
>> @@ -17,12 +17,168 @@
>>   #include "mcdi_filters.h"
>>   #include "mcdi_functions.h"
>>   #include "ef100_netdev.h"
>> +#include "filter.h"
>> +#include "efx.h"
>>
>> +#define EFX_INVALID_FILTER_ID -1
>> +
>> +/* vDPA queues starts from 2nd VI or qid 1 */
>> +#define EF100_VDPA_BASE_RX_QID 1
>> +
>> +static const char * const filter_names[] = { "bcast", "ucast", "mcast" };
>>   static struct virtio_device_id ef100_vdpa_id_table[] = {
>>          { .device = VIRTIO_ID_NET, .vendor = PCI_VENDOR_ID_REDHAT_QUMRANET },
>>          { 0 },
>>   };
>>
>> +static int ef100_vdpa_set_mac_filter(struct efx_nic *efx,
>> +                                    struct efx_filter_spec *spec,
>> +                                    u32 qid,
>> +                                    u8 *mac_addr)
>> +{
>> +       int rc;
>> +
>> +       efx_filter_init_rx(spec, EFX_FILTER_PRI_AUTO, 0, qid);
>> +
>> +       if (mac_addr) {
>> +               rc = efx_filter_set_eth_local(spec, EFX_FILTER_VID_UNSPEC,
>> +                                             mac_addr);
>> +               if (rc)
>> +                       pci_err(efx->pci_dev,
>> +                               "Filter set eth local failed, err: %d\n", rc);
>> +       } else {
>> +               efx_filter_set_mc_def(spec);
>> +       }
>> +
>> +       rc = efx_filter_insert_filter(efx, spec, true);
>> +       if (rc < 0)
>> +               pci_err(efx->pci_dev,
>> +                       "Filter insert failed, err: %d\n", rc);
>> +
>> +       return rc;
>> +}
>> +
>> +static int ef100_vdpa_delete_filter(struct ef100_vdpa_nic *vdpa_nic,
>> +                                   enum ef100_vdpa_mac_filter_type type)
>> +{
>> +       struct vdpa_device *vdev = &vdpa_nic->vdpa_dev;
>> +       int rc;
>> +
>> +       if (vdpa_nic->filters[type].filter_id == EFX_INVALID_FILTER_ID)
>> +               return rc;
>> +
>> +       rc = efx_filter_remove_id_safe(vdpa_nic->efx,
>> +                                      EFX_FILTER_PRI_AUTO,
>> +                                      vdpa_nic->filters[type].filter_id);
>> +       if (rc) {
>> +               dev_err(&vdev->dev, "%s filter id: %d remove failed, err: %d\n",
>> +                       filter_names[type], vdpa_nic->filters[type].filter_id,
>> +                       rc);
>> +       } else {
>> +               vdpa_nic->filters[type].filter_id = EFX_INVALID_FILTER_ID;
>> +               vdpa_nic->filter_cnt--;
>> +       }
>> +       return rc;
>> +}
>> +
>> +int ef100_vdpa_add_filter(struct ef100_vdpa_nic *vdpa_nic,
>> +                         enum ef100_vdpa_mac_filter_type type)
>> +{
>> +       struct vdpa_device *vdev = &vdpa_nic->vdpa_dev;
>> +       struct efx_nic *efx = vdpa_nic->efx;
>> +       /* Configure filter on base Rx queue only */
>> +       u32 qid = EF100_VDPA_BASE_RX_QID;
>> +       struct efx_filter_spec *spec;
>> +       u8 baddr[ETH_ALEN];
>> +       int rc;
>> +
>> +       /* remove existing filter */
>> +       rc = ef100_vdpa_delete_filter(vdpa_nic, type);
>> +       if (rc < 0) {
>> +               dev_err(&vdev->dev, "%s MAC filter deletion failed, err: %d",
>> +                       filter_names[type], rc);
>> +               return rc;
>> +       }
>> +
>> +       /* Configure MAC Filter */
>> +       spec = &vdpa_nic->filters[type].spec;
>> +       if (type == EF100_VDPA_BCAST_MAC_FILTER) {
>> +               eth_broadcast_addr(baddr);
>> +               rc = ef100_vdpa_set_mac_filter(efx, spec, qid, baddr);
>> +       } else if (type == EF100_VDPA_UNKNOWN_MCAST_MAC_FILTER) {
>> +               rc = ef100_vdpa_set_mac_filter(efx, spec, qid, NULL);
>> +       } else {
>> +               /* Ensure we have everything required to insert the filter */
>> +               if (!vdpa_nic->mac_configured ||
>> +                   !vdpa_nic->vring[0].vring_created ||
>> +                   !is_valid_ether_addr(vdpa_nic->mac_address))
>> +                       return -EINVAL;
>> +
>> +               rc = ef100_vdpa_set_mac_filter(efx, spec, qid,
>> +                                              vdpa_nic->mac_address);
>> +       }
>> +
>> +       if (rc >= 0) {
>> +               vdpa_nic->filters[type].filter_id = rc;
>> +               vdpa_nic->filter_cnt++;
> I'm not sure I get this, but the code seems doesn't allow the driver
> to set multiple uc filters, so I think filter_cnt should be always 3?
> If yes, I don't see how filter_cnt can help here.
The filter_cnt is supposed to maintain the total number of filters 
created on a vdpa device. For now, this count will always be 3 and may 
not be of much use but later it will include the count of multiple 
multicast and unicast filters.
>
>> +
>> +               return 0;
>> +       }
>> +
>> +       dev_err(&vdev->dev, "%s MAC filter insert failed, err: %d\n",
>> +               filter_names[type], rc);
>> +
>> +       if (type != EF100_VDPA_UNKNOWN_MCAST_MAC_FILTER) {
>> +               ef100_vdpa_filter_remove(vdpa_nic);
>> +               return rc;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +int ef100_vdpa_filter_remove(struct ef100_vdpa_nic *vdpa_nic)
>> +{
>> +       enum ef100_vdpa_mac_filter_type filter;
>> +       int err = 0;
>> +       int rc;
>> +
>> +       for (filter = EF100_VDPA_BCAST_MAC_FILTER;
>> +            filter <= EF100_VDPA_UNKNOWN_MCAST_MAC_FILTER; filter++) {
>> +               rc = ef100_vdpa_delete_filter(vdpa_nic, filter);
>> +               if (rc < 0)
>> +                       /* store status of last failed filter remove */
>> +                       err = rc;
>> +       }
>> +       return err;
>> +}
>> +
>> +int ef100_vdpa_filter_configure(struct ef100_vdpa_nic *vdpa_nic)
>> +{
>> +       struct vdpa_device *vdev = &vdpa_nic->vdpa_dev;
>> +       enum ef100_vdpa_mac_filter_type filter;
>> +       int rc;
>> +
>> +       /* remove existing filters, if any */
>> +       rc = ef100_vdpa_filter_remove(vdpa_nic);
>> +       if (rc < 0) {
>> +               dev_err(&vdev->dev,
>> +                       "MAC filter deletion failed, err: %d", rc);
>> +               goto fail;
>> +       }
>> +
>> +       for (filter = EF100_VDPA_BCAST_MAC_FILTER;
>> +            filter <= EF100_VDPA_UNKNOWN_MCAST_MAC_FILTER; filter++) {
>> +               if (filter == EF100_VDPA_UCAST_MAC_FILTER &&
>> +                   !vdpa_nic->mac_configured)
>> +                       continue;
>> +               rc = ef100_vdpa_add_filter(vdpa_nic, filter);
>> +               if (rc < 0)
>> +                       goto fail;
>> +       }
>> +fail:
>> +       return rc;
>> +}
>> +
>>   int ef100_vdpa_init(struct efx_probe_data *probe_data)
>>   {
>>          struct efx_nic *efx = &probe_data->efx;
>> @@ -168,6 +324,9 @@ static struct ef100_vdpa_nic *ef100_vdpa_create(struct efx_nic *efx,
>>          ether_addr_copy(vdpa_nic->mac_address, mac);
>>          vdpa_nic->mac_configured = true;
>>
>> +       for (i = 0; i < EF100_VDPA_MAC_FILTER_NTYPES; i++)
>> +               vdpa_nic->filters[i].filter_id = EFX_INVALID_FILTER_ID;
>> +
>>          for (i = 0; i < (2 * vdpa_nic->max_queue_pairs); i++)
>>                  vdpa_nic->vring[i].irq = -EINVAL;
>>
>> diff --git a/drivers/net/ethernet/sfc/ef100_vdpa.h b/drivers/net/ethernet/sfc/ef100_vdpa.h
>> index 3cc33daa0431..a33edd6dda12 100644
>> --- a/drivers/net/ethernet/sfc/ef100_vdpa.h
>> +++ b/drivers/net/ethernet/sfc/ef100_vdpa.h
>> @@ -72,6 +72,22 @@ enum ef100_vdpa_vq_type {
>>          EF100_VDPA_VQ_NTYPES
>>   };
>>
>> +/**
>> + * enum ef100_vdpa_mac_filter_type - vdpa filter types
>> + *
>> + * @EF100_VDPA_BCAST_MAC_FILTER: Broadcast MAC filter
>> + * @EF100_VDPA_UCAST_MAC_FILTER: Unicast MAC filter
>> + * @EF100_VDPA_UNKNOWN_MCAST_MAC_FILTER: Unknown multicast MAC filter to allow
>> + *     IPv6 Neighbor Solicitation Message
>> + * @EF100_VDPA_MAC_FILTER_NTYPES: Number of vDPA filter types
>> + */
>> +enum ef100_vdpa_mac_filter_type {
>> +       EF100_VDPA_BCAST_MAC_FILTER,
>> +       EF100_VDPA_UCAST_MAC_FILTER,
>> +       EF100_VDPA_UNKNOWN_MCAST_MAC_FILTER,
>> +       EF100_VDPA_MAC_FILTER_NTYPES,
>> +};
>> +
>>   /**
>>    * struct ef100_vdpa_vring_info - vDPA vring data structure
>>    *
>> @@ -109,6 +125,17 @@ struct ef100_vdpa_vring_info {
>>          struct vdpa_callback cb;
>>   };
>>
>> +/**
>> + * struct ef100_vdpa_filter - vDPA filter data structure
>> + *
>> + * @filter_id: filter id of this filter
>> + * @efx_filter_spec: hardware filter specs for this vdpa device
>> + */
>> +struct ef100_vdpa_filter {
>> +       s32 filter_id;
>> +       struct efx_filter_spec spec;
>> +};
>> +
>>   /**
>>    *  struct ef100_vdpa_nic - vDPA NIC data structure
>>    *
>> @@ -118,6 +145,7 @@ struct ef100_vdpa_vring_info {
>>    * @lock: Managing access to vdpa config operations
>>    * @pf_index: PF index of the vDPA VF
>>    * @vf_index: VF index of the vDPA VF
>> + * @filter_cnt: total number of filters created on this vdpa device
>>    * @status: device status as per VIRTIO spec
>>    * @features: negotiated feature bits
>>    * @max_queue_pairs: maximum number of queue pairs supported
>> @@ -125,6 +153,7 @@ struct ef100_vdpa_vring_info {
>>    * @vring: vring information of the vDPA device.
>>    * @mac_address: mac address of interface associated with this vdpa device
>>    * @mac_configured: true after MAC address is configured
>> + * @filters: details of all filters created on this vdpa device
>>    * @cfg_cb: callback for config change
>>    */
>>   struct ef100_vdpa_nic {
>> @@ -135,6 +164,7 @@ struct ef100_vdpa_nic {
>>          struct mutex lock;
>>          u32 pf_index;
>>          u32 vf_index;
>> +       u32 filter_cnt;
>>          u8 status;
>>          u64 features;
>>          u32 max_queue_pairs;
>> @@ -142,6 +172,7 @@ struct ef100_vdpa_nic {
>>          struct ef100_vdpa_vring_info vring[EF100_VDPA_MAX_QUEUES_PAIRS * 2];
>>          u8 *mac_address;
>>          bool mac_configured;
>> +       struct ef100_vdpa_filter filters[EF100_VDPA_MAC_FILTER_NTYPES];
>>          struct vdpa_callback cfg_cb;
>>   };
>>
>> @@ -149,6 +180,10 @@ int ef100_vdpa_init(struct efx_probe_data *probe_data);
>>   void ef100_vdpa_fini(struct efx_probe_data *probe_data);
>>   int ef100_vdpa_register_mgmtdev(struct efx_nic *efx);
>>   void ef100_vdpa_unregister_mgmtdev(struct efx_nic *efx);
>> +int ef100_vdpa_filter_configure(struct ef100_vdpa_nic *vdpa_nic);
>> +int ef100_vdpa_filter_remove(struct ef100_vdpa_nic *vdpa_nic);
>> +int ef100_vdpa_add_filter(struct ef100_vdpa_nic *vdpa_nic,
>> +                         enum ef100_vdpa_mac_filter_type type);
>>   int ef100_vdpa_irq_vectors_alloc(struct pci_dev *pci_dev, u16 nvqs);
>>   void ef100_vdpa_irq_vectors_free(void *data);
>>
>> diff --git a/drivers/net/ethernet/sfc/ef100_vdpa_ops.c b/drivers/net/ethernet/sfc/ef100_vdpa_ops.c
>> index b7efd3e0c901..132ddb4a647b 100644
>> --- a/drivers/net/ethernet/sfc/ef100_vdpa_ops.c
>> +++ b/drivers/net/ethernet/sfc/ef100_vdpa_ops.c
>> @@ -135,6 +135,15 @@ static int delete_vring(struct ef100_vdpa_nic *vdpa_nic, u16 idx)
>>          if (vdpa_nic->vring[idx].vring_ctx)
>>                  delete_vring_ctx(vdpa_nic, idx);
>>
>> +       if (idx == 0 && vdpa_nic->filter_cnt != 0) {
>> +               rc = ef100_vdpa_filter_remove(vdpa_nic);
>> +               if (rc < 0) {
>> +                       dev_err(&vdpa_nic->vdpa_dev.dev,
>> +                               "%s: vdpa remove filter failed, err:%d\n",
>> +                               __func__, rc);
>> +               }
>> +       }
>> +
>>          return rc;
>>   }
>>
>> @@ -193,8 +202,22 @@ static int create_vring(struct ef100_vdpa_nic *vdpa_nic, u16 idx)
>>                  vdpa_nic->vring[idx].doorbell_offset_valid = true;
>>          }
>>
>> +       /* Configure filters on rxq 0 */
>> +       if (idx == 0) {
> This seems tricky, can we move this to set_status() when DRIVER_OK is set?
For a virtqueue to be created, qenable must be set to 1 and status 
should be set to DRIVER_OK. The current implementation ensures both 
conditions before creating the HW queue. This will handle the situation 
where DRIVER_OK is set by a bad guest virtio-net driver but queue has 
not been enabled.
>
> Thanks
>
>
>> +               rc = ef100_vdpa_filter_configure(vdpa_nic);
>> +               if (rc < 0) {
>> +                       dev_err(&vdpa_nic->vdpa_dev.dev,
>> +                               "%s: vdpa configure filter failed, err:%d\n",
>> +                               __func__, rc);
>> +                       goto err_filter_configure;
>> +               }
>> +       }
>> +
>>          return 0;
>>
>> +err_filter_configure:
>> +       ef100_vdpa_filter_remove(vdpa_nic);
>> +       vdpa_nic->vring[idx].doorbell_offset_valid = false;
>>   err_get_doorbell_offset:
>>          efx_vdpa_vring_destroy(vdpa_nic->vring[idx].vring_ctx,
>>                                 &vring_dyn_cfg);
>> @@ -578,8 +601,10 @@ static void ef100_vdpa_set_config(struct vdpa_device *vdev, unsigned int offset,
>>          }
>>
>>          memcpy((u8 *)&vdpa_nic->net_config + offset, buf, len);
>> -       if (is_valid_ether_addr(vdpa_nic->mac_address))
>> +       if (is_valid_ether_addr(vdpa_nic->mac_address)) {
>>                  vdpa_nic->mac_configured = true;
>> +               ef100_vdpa_add_filter(vdpa_nic, EF100_VDPA_UCAST_MAC_FILTER);
>> +       }
>>   }
>>
>>   static void ef100_vdpa_free(struct vdpa_device *vdev)
>> --
>> 2.30.1
>>

  reply	other threads:[~2023-01-05 12:47 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-07 14:54 [PATCH net-next 00/11] sfc: add vDPA support for EF100 devices Gautam Dawar
2022-12-07 14:54 ` [PATCH net-next 01/11] sfc: add function personality " Gautam Dawar
2022-12-07 14:54 ` [PATCH net-next 02/11] sfc: implement MCDI interface for vDPA operations Gautam Dawar
2022-12-14  6:43   ` Jason Wang
2022-12-16 12:50     ` Gautam Dawar
2022-12-07 14:54 ` [PATCH net-next 03/11] sfc: implement init and fini functions for vDPA personality Gautam Dawar
2022-12-07 14:54 ` [PATCH net-next 04/11] sfc: implement vDPA management device operations Gautam Dawar
2022-12-07 16:31   ` kernel test robot
2022-12-14  6:43   ` Jason Wang
2022-12-15  7:07     ` Gautam Dawar
2022-12-07 14:54 ` [PATCH net-next 05/11] sfc: implement vdpa device config operations Gautam Dawar
2022-12-14  6:44   ` Jason Wang
2022-12-15  9:53     ` Gautam Dawar
2022-12-07 14:54 ` [PATCH net-next 06/11] sfc: implement vdpa vring " Gautam Dawar
2022-12-14  6:45   ` Jason Wang
2022-12-07 14:54 ` [PATCH net-next 07/11] sfc: implement filters for receiving traffic Gautam Dawar
2022-12-14  6:45   ` Jason Wang
2023-01-05 12:46     ` Gautam Dawar [this message]
2022-12-07 14:54 ` [PATCH net-next 08/11] sfc: implement device status related vdpa config operations Gautam Dawar
2022-12-14  6:45   ` Jason Wang
2023-01-09 10:21     ` Gautam Dawar
2023-01-11  6:36       ` Jason Wang
2023-01-13  4:28         ` Jason Wang
2023-01-13  6:10           ` Gautam Dawar
2023-01-13  6:20             ` Jason Wang
2023-01-13  6:33               ` Gautam Dawar
2023-01-16  2:55                 ` Jason Wang
2022-12-07 14:54 ` [PATCH net-next 09/11] sfc: implement iova rbtree to store dma mappings Gautam Dawar
2022-12-14  6:46   ` Jason Wang
2022-12-16 12:48     ` Gautam Dawar
2022-12-19  6:03       ` Jason Wang
2023-01-05 13:08         ` Gautam Dawar
2023-01-09  8:49           ` Jason Wang
2023-02-09 13:39             ` Gautam Dawar
2022-12-07 14:54 ` [PATCH net-next 10/11] sfc: implement vdpa config_ops for dma operations Gautam Dawar
2022-12-07 19:23   ` kernel test robot
2022-12-14  6:46   ` Jason Wang
2022-12-07 14:54 ` [PATCH net-next 11/11] sfc: register the vDPA device Gautam Dawar
2022-12-11 18:05 ` [PATCH net-next 00/11] sfc: add vDPA support for EF100 devices Martin Habets

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a936c0e3-8f65-af51-b0c3-a907f414e0c7@amd.com \
    --to=gdawar@amd.com \
    --cc=Koushik.Dutta@amd.com \
    --cc=davem@davemloft.net \
    --cc=ecree.xilinx@gmail.com \
    --cc=edumazet@google.com \
    --cc=eperezma@redhat.com \
    --cc=gautam.dawar@amd.com \
    --cc=habetsm.xilinx@gmail.com \
    --cc=harpreet.anand@amd.com \
    --cc=jasowang@redhat.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-net-drivers@amd.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=tanuj.kamde@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).