mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-04 17:57:54 -04:00
Merge branch 'vxlan-convert-fdb-table-to-rhashtable'
Ido Schimmel says: ==================== vxlan: Convert FDB table to rhashtable The VXLAN driver currently stores FDB entries in a hash table with a fixed number of buckets (256), resulting in reduced performance as the number of entries grows. This patchset solves the issue by converting the driver to use rhashtable which maintains a more or less constant performance regardless of the number of entries. Measured transmitted packets per second using a single pktgen thread with varying number of entries when the transmitted packet always hits the default entry (worst case): Number of entries | Improvement ------------------|------------ 1k | +1.12% 4k | +9.22% 16k | +55% 64k | +585% 256k | +2460% The first patches are preparations for the conversion in the last patch. Specifically, the series is structured as follows: Patch #1 adds RCU read-side critical sections in the Tx path when accessing FDB entries. Targeting at net-next as I am not aware of any issues due to this omission despite the code being structured that way for a long time. Without it, traces will be generated when converting FDB lookup to rhashtable_lookup(). Patch #2-#5 simplify the creation of the default FDB entry (all-zeroes). Current code assumes that insertion into the hash table cannot fail, which will no longer be true with rhashtable. Patches #6-#10 add FDB entries to a linked list for entry traversal instead of traversing over them using the fixed size hash table which is removed in the last patch. Patches #11-#12 add wrappers for FDB lookup that make it clear when each should be used along with lockdep annotations. Needed as a preparation for rhashtable_lookup() that must be called from an RCU read-side critical section. Patch #13 treats dst cache initialization errors as non-fatal. See more info in the commit message. The current code happens to work because insertion into the fixed size hash table is slow enough for the per-CPU allocator to be able to create new chunks of per-CPU memory. Patch #14 adds an FDB key structure that includes the MAC address and source VNI. To be used as rhashtable key. Patch #15 does the conversion to rhashtable. ==================== Link: https://patch.msgid.link/20250415121143.345227-1-idosch@nvidia.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -24,18 +24,23 @@ struct vxlan_net {
|
||||
struct notifier_block nexthop_notifier_block;
|
||||
};
|
||||
|
||||
struct vxlan_fdb_key {
|
||||
u8 eth_addr[ETH_ALEN];
|
||||
__be32 vni;
|
||||
};
|
||||
|
||||
/* Forwarding table entry */
|
||||
struct vxlan_fdb {
|
||||
struct hlist_node hlist; /* linked list of entries */
|
||||
struct rhash_head rhnode;
|
||||
struct rcu_head rcu;
|
||||
unsigned long updated; /* jiffies */
|
||||
unsigned long used;
|
||||
struct list_head remotes;
|
||||
u8 eth_addr[ETH_ALEN];
|
||||
struct vxlan_fdb_key key;
|
||||
u16 state; /* see ndm_state */
|
||||
__be32 vni;
|
||||
u16 flags; /* see ndm_flags and below */
|
||||
struct list_head nh_list;
|
||||
struct hlist_node fdb_node;
|
||||
struct nexthop __rcu *nh;
|
||||
struct vxlan_dev __rcu *vdev;
|
||||
};
|
||||
|
||||
@@ -482,11 +482,9 @@ static int vxlan_update_default_fdb_entry(struct vxlan_dev *vxlan, __be32 vni,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct vxlan_rdst *dst = &vxlan->default_dst;
|
||||
u32 hash_index;
|
||||
int err = 0;
|
||||
|
||||
hash_index = fdb_head_index(vxlan, all_zeros_mac, vni);
|
||||
spin_lock_bh(&vxlan->hash_lock[hash_index]);
|
||||
spin_lock_bh(&vxlan->hash_lock);
|
||||
if (remote_ip && !vxlan_addr_any(remote_ip)) {
|
||||
err = vxlan_fdb_update(vxlan, all_zeros_mac,
|
||||
remote_ip,
|
||||
@@ -498,7 +496,7 @@ static int vxlan_update_default_fdb_entry(struct vxlan_dev *vxlan, __be32 vni,
|
||||
dst->remote_ifindex,
|
||||
NTF_SELF, 0, true, extack);
|
||||
if (err) {
|
||||
spin_unlock_bh(&vxlan->hash_lock[hash_index]);
|
||||
spin_unlock_bh(&vxlan->hash_lock);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@@ -511,7 +509,7 @@ static int vxlan_update_default_fdb_entry(struct vxlan_dev *vxlan, __be32 vni,
|
||||
dst->remote_ifindex,
|
||||
true);
|
||||
}
|
||||
spin_unlock_bh(&vxlan->hash_lock[hash_index]);
|
||||
spin_unlock_bh(&vxlan->hash_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ struct vxlan_dev {
|
||||
struct vxlan_rdst default_dst; /* default destination */
|
||||
|
||||
struct timer_list age_timer;
|
||||
spinlock_t hash_lock[FDB_HASH_SIZE];
|
||||
spinlock_t hash_lock;
|
||||
unsigned int addrcnt;
|
||||
struct gro_cells gro_cells;
|
||||
|
||||
@@ -304,9 +304,10 @@ struct vxlan_dev {
|
||||
|
||||
struct vxlan_vni_group __rcu *vnigrp;
|
||||
|
||||
struct hlist_head fdb_head[FDB_HASH_SIZE];
|
||||
struct rhashtable fdb_hash_tbl;
|
||||
|
||||
struct rhashtable mdb_tbl;
|
||||
struct hlist_head fdb_list;
|
||||
struct hlist_head mdb_list;
|
||||
unsigned int mdb_seq;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user