From: Andrew Rybchenko <arybchenko@solarflare.com>
To: <dev@dpdk.org>
Cc: Ivan Malov <ivan.malov@oktetlabs.ru>, <stable@dpdk.org>
Subject: [dpdk-dev] [PATCH] net/sfc: set multicast address list in started state only
Date: Thu, 2 Mar 2017 14:40:48 +0000 [thread overview]
Message-ID: <1488465648-27351-1-git-send-email-arybchenko@solarflare.com> (raw)
From: Ivan Malov <ivan.malov@oktetlabs.ru>
According to 'libefx' API requirements, one is allowed to
apply multicast address list to the port in started state
only, otherwise the new array should be copied to a local
storage in order to be applied during the next port start
Fixes: 0fa0070e4391 ("net/sfc: support multicast addresses list controls")
Coverity issue: 141296
Fixes: e9ddf37a507d ("net/sfc: fix setting empty multicast list")
Cc: stable@dpdk.org
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
---
drivers/net/sfc/sfc.h | 4 ++++
drivers/net/sfc/sfc_ethdev.c | 35 ++++++++++++++++-------------------
drivers/net/sfc/sfc_port.c | 19 +++++++++++++++++++
3 files changed, 39 insertions(+), 19 deletions(-)
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 8c6c02f..d1fc84b 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -150,6 +150,10 @@ struct sfc_port {
boolean_t promisc;
boolean_t allmulti;
+ unsigned int max_mcast_addrs;
+ unsigned int nb_mcast_addrs;
+ uint8_t *mcast_addrs;
+
rte_spinlock_t mac_stats_lock;
uint64_t *mac_stats_buf;
efsys_mem_t mac_stats_dma_mem;
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 71587fb..5ff1cc1 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -805,36 +805,33 @@ sfc_set_mc_addr_list(struct rte_eth_dev *dev, struct ether_addr *mc_addr_set,
uint32_t nb_mc_addr)
{
struct sfc_adapter *sa = dev->data->dev_private;
- uint8_t *mc_addrs_p = NULL;
+ struct sfc_port *port = &sa->port;
+ uint8_t *mc_addrs = port->mcast_addrs;
int rc;
unsigned int i;
- if (nb_mc_addr > EFX_MAC_MULTICAST_LIST_MAX) {
+ if (mc_addrs == NULL)
+ return -ENOBUFS;
+
+ if (nb_mc_addr > port->max_mcast_addrs) {
sfc_err(sa, "too many multicast addresses: %u > %u",
- nb_mc_addr, EFX_MAC_MULTICAST_LIST_MAX);
+ nb_mc_addr, port->max_mcast_addrs);
return -EINVAL;
}
- if (nb_mc_addr != 0) {
- uint8_t *mc_addrs;
-
- mc_addrs_p = rte_calloc("mc-addrs", nb_mc_addr,
- EFX_MAC_ADDR_LEN, 0);
- if (mc_addrs_p == NULL)
- return -ENOMEM;
-
- mc_addrs = mc_addrs_p;
- for (i = 0; i < nb_mc_addr; ++i) {
- (void)rte_memcpy(mc_addrs, mc_addr_set[i].addr_bytes,
- EFX_MAC_ADDR_LEN);
- mc_addrs += EFX_MAC_ADDR_LEN;
- }
+ for (i = 0; i < nb_mc_addr; ++i) {
+ (void)rte_memcpy(mc_addrs, mc_addr_set[i].addr_bytes,
+ EFX_MAC_ADDR_LEN);
+ mc_addrs += EFX_MAC_ADDR_LEN;
}
- rc = efx_mac_multicast_list_set(sa->nic, mc_addrs_p, nb_mc_addr);
+ port->nb_mcast_addrs = nb_mc_addr;
- rte_free(mc_addrs_p);
+ if (sa->state != SFC_ADAPTER_STARTED)
+ return 0;
+ rc = efx_mac_multicast_list_set(sa->nic, port->mcast_addrs,
+ port->nb_mcast_addrs);
if (rc != 0)
sfc_err(sa, "cannot set multicast address list (rc = %u)", rc);
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index 5998a99..507df01 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -140,6 +140,12 @@ sfc_port_start(struct sfc_adapter *sa)
if (rc != 0)
goto fail_mac_filter_set;
+ sfc_log_init(sa, "set multicast address list");
+ rc = efx_mac_multicast_list_set(sa->nic, port->mcast_addrs,
+ port->nb_mcast_addrs);
+ if (rc != 0)
+ goto fail_mcast_address_list_set;
+
efx_mac_stats_get_mask(sa->nic, port->mac_stats_mask,
sizeof(port->mac_stats_mask));
@@ -174,6 +180,7 @@ sfc_port_start(struct sfc_adapter *sa)
0, B_FALSE);
fail_mac_stats_periodic:
+fail_mcast_address_list_set:
fail_mac_filter_set:
fail_mac_addr_set:
fail_mac_pdu_set:
@@ -223,6 +230,17 @@ sfc_port_init(struct sfc_adapter *sa)
else
port->pdu = EFX_MAC_PDU(dev_data->mtu);
+ port->max_mcast_addrs = EFX_MAC_MULTICAST_LIST_MAX;
+ port->nb_mcast_addrs = 0;
+ port->mcast_addrs = rte_calloc_socket("mcast_addr_list_buf",
+ port->max_mcast_addrs,
+ EFX_MAC_ADDR_LEN, 0,
+ sa->socket_id);
+ if (port->mcast_addrs == NULL) {
+ rc = ENOMEM;
+ goto fail_mcast_addr_list_buf_alloc;
+ }
+
rte_spinlock_init(&port->mac_stats_lock);
rc = ENOMEM;
@@ -243,6 +261,7 @@ sfc_port_init(struct sfc_adapter *sa)
fail_mac_stats_dma_alloc:
rte_free(port->mac_stats_buf);
fail_mac_stats_buf_alloc:
+fail_mcast_addr_list_buf_alloc:
sfc_log_init(sa, "failed %d", rc);
return rc;
}
--
2.9.3
next reply other threads:[~2017-03-02 14:40 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-02 14:40 Andrew Rybchenko [this message]
2017-03-09 15:52 ` [dpdk-dev] [dpdk-stable] " Ferruh Yigit
2017-03-09 16:21 ` [dpdk-dev] [PATCH v2] " Andrew Rybchenko
2017-03-14 15:18 ` Ferruh Yigit
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=1488465648-27351-1-git-send-email-arybchenko@solarflare.com \
--to=arybchenko@solarflare.com \
--cc=dev@dpdk.org \
--cc=ivan.malov@oktetlabs.ru \
--cc=stable@dpdk.org \
/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).