Skip to content

Commit 278e7d0

Browse files
jacob-kellerJeff Kirsher
authored andcommitted
i40e: store MAC/VLAN filters in a hash with the MAC Address as key
Replace the mac_filter_list with a static size hash table of 8bits. The primary advantage of this is a decrease in latency of operations related to searching for specific MAC filters, including .set_rx_mode. Using a linked list resulted in several locations which were O(n^2). Using a hash table should give us latency growth closer to O(n*log(n)). Change-ID: I5330bd04053b880e670210933e35830b95948ebb Signed-off-by: Jacob Keller <[email protected]> Tested-by: Andrew Bowers <[email protected]>
1 parent 290d255 commit 278e7d0

File tree

5 files changed

+161
-107
lines changed

5 files changed

+161
-107
lines changed

drivers/net/ethernet/intel/i40e/i40e.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <linux/iommu.h>
4040
#include <linux/slab.h>
4141
#include <linux/list.h>
42+
#include <linux/hashtable.h>
4243
#include <linux/string.h>
4344
#include <linux/in.h>
4445
#include <linux/ip.h>
@@ -445,6 +446,20 @@ struct i40e_pf {
445446
u16 phy_led_val;
446447
};
447448

449+
/**
450+
* i40e_mac_to_hkey - Convert a 6-byte MAC Address to a u64 hash key
451+
* @macaddr: the MAC Address as the base key
452+
*
453+
* Simply copies the address and returns it as a u64 for hashing
454+
**/
455+
static inline u64 i40e_addr_to_hkey(const u8 *macaddr)
456+
{
457+
u64 key = 0;
458+
459+
ether_addr_copy((u8 *)&key, macaddr);
460+
return key;
461+
}
462+
448463
enum i40e_filter_state {
449464
I40E_FILTER_INVALID = 0, /* Invalid state */
450465
I40E_FILTER_NEW, /* New, not sent to FW yet */
@@ -454,7 +469,7 @@ enum i40e_filter_state {
454469
/* There is no 'removed' state; the filter struct is freed */
455470
};
456471
struct i40e_mac_filter {
457-
struct list_head list;
472+
struct hlist_node hlist;
458473
u8 macaddr[ETH_ALEN];
459474
#define I40E_VLAN_ANY -1
460475
s16 vlan;
@@ -498,9 +513,10 @@ struct i40e_vsi {
498513
#define I40E_VSI_FLAG_VEB_OWNER BIT(1)
499514
unsigned long flags;
500515

501-
/* Per VSI lock to protect elements/list (MAC filter) */
502-
spinlock_t mac_filter_list_lock;
503-
struct list_head mac_filter_list;
516+
/* Per VSI lock to protect elements/hash (MAC filter) */
517+
spinlock_t mac_filter_hash_lock;
518+
/* Fixed size hash table with 2^8 buckets for MAC filters */
519+
DECLARE_HASHTABLE(mac_filter_hash, 8);
504520

505521
/* VSI stats */
506522
struct rtnl_link_stats64 net_stats;

drivers/net/ethernet/intel/i40e/i40e_debugfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
134134
struct rtnl_link_stats64 *nstat;
135135
struct i40e_mac_filter *f;
136136
struct i40e_vsi *vsi;
137-
int i;
137+
int i, bkt;
138138

139139
vsi = i40e_dbg_find_vsi(pf, seid);
140140
if (!vsi) {
@@ -166,7 +166,7 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
166166
pf->hw.mac.addr,
167167
pf->hw.mac.san_addr,
168168
pf->hw.mac.port_addr);
169-
list_for_each_entry(f, &vsi->mac_filter_list, list) {
169+
hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
170170
dev_info(&pf->pdev->dev,
171171
" mac_filter_hash: %pM vid=%d, state %s\n",
172172
f->macaddr, f->vlan,

drivers/net/ethernet/intel/i40e/i40e_fcoe.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,12 +1522,12 @@ void i40e_fcoe_config_netdev(struct net_device *netdev, struct i40e_vsi *vsi)
15221522
* same PCI function.
15231523
*/
15241524
netdev->dev_port = 1;
1525-
spin_lock_bh(&vsi->mac_filter_list_lock);
1525+
spin_lock_bh(&vsi->mac_filter_hash_lock);
15261526
i40e_add_filter(vsi, hw->mac.san_addr, 0);
15271527
i40e_add_filter(vsi, (u8[6]) FC_FCOE_FLOGI_MAC, 0);
15281528
i40e_add_filter(vsi, FIP_ALL_FCOE_MACS, 0);
15291529
i40e_add_filter(vsi, FIP_ALL_ENODE_MACS, 0);
1530-
spin_unlock_bh(&vsi->mac_filter_list_lock);
1530+
spin_unlock_bh(&vsi->mac_filter_hash_lock);
15311531

15321532
/* use san mac */
15331533
ether_addr_copy(netdev->dev_addr, hw->mac.san_addr);

0 commit comments

Comments
 (0)