aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward Cree <ecree@solarflare.com>2017-04-04 12:02:49 -0400
committerDavid S. Miller <davem@davemloft.net>2017-04-05 21:35:21 -0400
commit148cbab6cffc8247d7dfd0f2da86c2eb8c55709c (patch)
treecb38eb1a53238ee87e4cc7737433e2a16e6eb633
parenta4b7c07fdffdd0fb2706ebfa99657687f1880282 (diff)
sfc: don't insert mc_list on low-latency firmware if it's too long
If the mc_list is longer than 256 addresses, we enter mc_promisc mode. If we're in mc_promisc mode and the firmware doesn't support cascaded multicast, normally we also insert our mc_list, to prevent stealing by another VI. However, if the mc_list was too long, this isn't really helpful - the MC groups that didn't fit in the list can still get stolen, and having only some of them stealable will probably cause more confusing behaviour than having them all stealable. Since inserting 256 multicast filters takes a long time and can lead to MCDI state machine timeouts, just skip the mc_list insert in this overflow condition. Signed-off-by: Edward Cree <ecree@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/sfc/ef10.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index c60c2d4c646a..78efb2822b86 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -119,6 +119,7 @@ struct efx_ef10_filter_table {
119 bool mc_promisc; 119 bool mc_promisc;
120/* Whether in multicast promiscuous mode when last changed */ 120/* Whether in multicast promiscuous mode when last changed */
121 bool mc_promisc_last; 121 bool mc_promisc_last;
122 bool mc_overflow; /* Too many MC addrs; should always imply mc_promisc */
122 bool vlan_filter; 123 bool vlan_filter;
123 struct list_head vlan_list; 124 struct list_head vlan_list;
124}; 125};
@@ -5058,6 +5059,7 @@ static void efx_ef10_filter_mc_addr_list(struct efx_nic *efx)
5058 struct netdev_hw_addr *mc; 5059 struct netdev_hw_addr *mc;
5059 unsigned int i, addr_count; 5060 unsigned int i, addr_count;
5060 5061
5062 table->mc_overflow = false;
5061 table->mc_promisc = !!(net_dev->flags & (IFF_PROMISC | IFF_ALLMULTI)); 5063 table->mc_promisc = !!(net_dev->flags & (IFF_PROMISC | IFF_ALLMULTI));
5062 5064
5063 addr_count = netdev_mc_count(net_dev); 5065 addr_count = netdev_mc_count(net_dev);
@@ -5065,6 +5067,7 @@ static void efx_ef10_filter_mc_addr_list(struct efx_nic *efx)
5065 netdev_for_each_mc_addr(mc, net_dev) { 5067 netdev_for_each_mc_addr(mc, net_dev) {
5066 if (i >= EFX_EF10_FILTER_DEV_MC_MAX) { 5068 if (i >= EFX_EF10_FILTER_DEV_MC_MAX) {
5067 table->mc_promisc = true; 5069 table->mc_promisc = true;
5070 table->mc_overflow = true;
5068 break; 5071 break;
5069 } 5072 }
5070 ether_addr_copy(table->dev_mc_list[i].addr, mc->addr); 5073 ether_addr_copy(table->dev_mc_list[i].addr, mc->addr);
@@ -5469,12 +5472,15 @@ static void efx_ef10_filter_vlan_sync_rx_mode(struct efx_nic *efx,
5469 } 5472 }
5470 } else { 5473 } else {
5471 /* If we failed to insert promiscuous filters, don't 5474 /* If we failed to insert promiscuous filters, don't
5472 * rollback. Regardless, also insert the mc_list 5475 * rollback. Regardless, also insert the mc_list,
5476 * unless it's incomplete due to overflow
5473 */ 5477 */
5474 efx_ef10_filter_insert_def(efx, vlan, 5478 efx_ef10_filter_insert_def(efx, vlan,
5475 EFX_ENCAP_TYPE_NONE, 5479 EFX_ENCAP_TYPE_NONE,
5476 true, false); 5480 true, false);
5477 efx_ef10_filter_insert_addr_list(efx, vlan, true, false); 5481 if (!table->mc_overflow)
5482 efx_ef10_filter_insert_addr_list(efx, vlan,
5483 true, false);
5478 } 5484 }
5479 } else { 5485 } else {
5480 /* If any filters failed to insert, rollback and fall back to 5486 /* If any filters failed to insert, rollback and fall back to