Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Edward Cree and committed by
David S. Miller
148cbab6 a4b7c07f

+8 -2
+8 -2
drivers/net/ethernet/sfc/ef10.c
··· 119 119 bool mc_promisc; 120 120 /* Whether in multicast promiscuous mode when last changed */ 121 121 bool mc_promisc_last; 122 + bool mc_overflow; /* Too many MC addrs; should always imply mc_promisc */ 122 123 bool vlan_filter; 123 124 struct list_head vlan_list; 124 125 }; ··· 5059 5058 struct netdev_hw_addr *mc; 5060 5059 unsigned int i, addr_count; 5061 5060 5061 + table->mc_overflow = false; 5062 5062 table->mc_promisc = !!(net_dev->flags & (IFF_PROMISC | IFF_ALLMULTI)); 5063 5063 5064 5064 addr_count = netdev_mc_count(net_dev); ··· 5067 5065 netdev_for_each_mc_addr(mc, net_dev) { 5068 5066 if (i >= EFX_EF10_FILTER_DEV_MC_MAX) { 5069 5067 table->mc_promisc = true; 5068 + table->mc_overflow = true; 5070 5069 break; 5071 5070 } 5072 5071 ether_addr_copy(table->dev_mc_list[i].addr, mc->addr); ··· 5472 5469 } 5473 5470 } else { 5474 5471 /* If we failed to insert promiscuous filters, don't 5475 - * rollback. Regardless, also insert the mc_list 5472 + * rollback. Regardless, also insert the mc_list, 5473 + * unless it's incomplete due to overflow 5476 5474 */ 5477 5475 efx_ef10_filter_insert_def(efx, vlan, 5478 5476 EFX_ENCAP_TYPE_NONE, 5479 5477 true, false); 5480 - efx_ef10_filter_insert_addr_list(efx, vlan, true, false); 5478 + if (!table->mc_overflow) 5479 + efx_ef10_filter_insert_addr_list(efx, vlan, 5480 + true, false); 5481 5481 } 5482 5482 } else { 5483 5483 /* If any filters failed to insert, rollback and fall back to