Skip to content

Commit 7aa0dc7

Browse files
idoschPaolo Abeni
authored andcommitted
vxlan: Use linked list to traverse FDB entries
In preparation for removing the fixed size hash table, convert FDB entry traversal to use the newly added FDB linked list. No functional changes intended. Reviewed-by: Petr Machata <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Link: https://patch.msgid.link/[email protected] Reviewed-by: Nikolay Aleksandrov <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 8d45673 commit 7aa0dc7

File tree

1 file changed

+75
-97
lines changed

1 file changed

+75
-97
lines changed

drivers/net/vxlan/vxlan_core.c

Lines changed: 75 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -517,24 +517,20 @@ int vxlan_fdb_replay(const struct net_device *dev, __be32 vni,
517517
struct vxlan_dev *vxlan;
518518
struct vxlan_rdst *rdst;
519519
struct vxlan_fdb *f;
520-
unsigned int h;
521520
int rc = 0;
522521

523522
if (!netif_is_vxlan(dev))
524523
return -EINVAL;
525524
vxlan = netdev_priv(dev);
526525

527526
spin_lock_bh(&vxlan->hash_lock);
528-
for (h = 0; h < FDB_HASH_SIZE; ++h) {
529-
hlist_for_each_entry(f, &vxlan->fdb_head[h], hlist) {
530-
if (f->vni == vni) {
531-
list_for_each_entry(rdst, &f->remotes, list) {
532-
rc = vxlan_fdb_notify_one(nb, vxlan,
533-
f, rdst,
534-
extack);
535-
if (rc)
536-
goto unlock;
537-
}
527+
hlist_for_each_entry(f, &vxlan->fdb_list, fdb_node) {
528+
if (f->vni == vni) {
529+
list_for_each_entry(rdst, &f->remotes, list) {
530+
rc = vxlan_fdb_notify_one(nb, vxlan, f, rdst,
531+
extack);
532+
if (rc)
533+
goto unlock;
538534
}
539535
}
540536
}
@@ -552,18 +548,17 @@ void vxlan_fdb_clear_offload(const struct net_device *dev, __be32 vni)
552548
struct vxlan_dev *vxlan;
553549
struct vxlan_rdst *rdst;
554550
struct vxlan_fdb *f;
555-
unsigned int h;
556551

557552
if (!netif_is_vxlan(dev))
558553
return;
559554
vxlan = netdev_priv(dev);
560555

561556
spin_lock_bh(&vxlan->hash_lock);
562-
for (h = 0; h < FDB_HASH_SIZE; ++h) {
563-
hlist_for_each_entry(f, &vxlan->fdb_head[h], hlist)
564-
if (f->vni == vni)
565-
list_for_each_entry(rdst, &f->remotes, list)
566-
rdst->offloaded = false;
557+
hlist_for_each_entry(f, &vxlan->fdb_list, fdb_node) {
558+
if (f->vni == vni) {
559+
list_for_each_entry(rdst, &f->remotes, list)
560+
rdst->offloaded = false;
561+
}
567562
}
568563
spin_unlock_bh(&vxlan->hash_lock);
569564

@@ -1351,52 +1346,46 @@ static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
13511346
{
13521347
struct ndo_fdb_dump_context *ctx = (void *)cb->ctx;
13531348
struct vxlan_dev *vxlan = netdev_priv(dev);
1354-
unsigned int h;
1349+
struct vxlan_fdb *f;
13551350
int err = 0;
13561351

1357-
for (h = 0; h < FDB_HASH_SIZE; ++h) {
1358-
struct vxlan_fdb *f;
1359-
1360-
rcu_read_lock();
1361-
hlist_for_each_entry_rcu(f, &vxlan->fdb_head[h], hlist) {
1362-
struct vxlan_rdst *rd;
1363-
1364-
if (rcu_access_pointer(f->nh)) {
1365-
if (*idx < ctx->fdb_idx)
1366-
goto skip_nh;
1367-
err = vxlan_fdb_info(skb, vxlan, f,
1368-
NETLINK_CB(cb->skb).portid,
1369-
cb->nlh->nlmsg_seq,
1370-
RTM_NEWNEIGH,
1371-
NLM_F_MULTI, NULL);
1372-
if (err < 0) {
1373-
rcu_read_unlock();
1374-
goto out;
1375-
}
1376-
skip_nh:
1377-
*idx += 1;
1378-
continue;
1352+
rcu_read_lock();
1353+
hlist_for_each_entry_rcu(f, &vxlan->fdb_list, fdb_node) {
1354+
struct vxlan_rdst *rd;
1355+
1356+
if (rcu_access_pointer(f->nh)) {
1357+
if (*idx < ctx->fdb_idx)
1358+
goto skip_nh;
1359+
err = vxlan_fdb_info(skb, vxlan, f,
1360+
NETLINK_CB(cb->skb).portid,
1361+
cb->nlh->nlmsg_seq,
1362+
RTM_NEWNEIGH, NLM_F_MULTI, NULL);
1363+
if (err < 0) {
1364+
rcu_read_unlock();
1365+
goto out;
13791366
}
1367+
skip_nh:
1368+
*idx += 1;
1369+
continue;
1370+
}
13801371

1381-
list_for_each_entry_rcu(rd, &f->remotes, list) {
1382-
if (*idx < ctx->fdb_idx)
1383-
goto skip;
1384-
1385-
err = vxlan_fdb_info(skb, vxlan, f,
1386-
NETLINK_CB(cb->skb).portid,
1387-
cb->nlh->nlmsg_seq,
1388-
RTM_NEWNEIGH,
1389-
NLM_F_MULTI, rd);
1390-
if (err < 0) {
1391-
rcu_read_unlock();
1392-
goto out;
1393-
}
1394-
skip:
1395-
*idx += 1;
1372+
list_for_each_entry_rcu(rd, &f->remotes, list) {
1373+
if (*idx < ctx->fdb_idx)
1374+
goto skip;
1375+
1376+
err = vxlan_fdb_info(skb, vxlan, f,
1377+
NETLINK_CB(cb->skb).portid,
1378+
cb->nlh->nlmsg_seq,
1379+
RTM_NEWNEIGH, NLM_F_MULTI, rd);
1380+
if (err < 0) {
1381+
rcu_read_unlock();
1382+
goto out;
13961383
}
1384+
skip:
1385+
*idx += 1;
13971386
}
1398-
rcu_read_unlock();
13991387
}
1388+
rcu_read_unlock();
14001389
out:
14011390
return err;
14021391
}
@@ -2830,35 +2819,30 @@ static void vxlan_cleanup(struct timer_list *t)
28302819
{
28312820
struct vxlan_dev *vxlan = from_timer(vxlan, t, age_timer);
28322821
unsigned long next_timer = jiffies + FDB_AGE_INTERVAL;
2833-
unsigned int h;
2822+
struct hlist_node *n;
2823+
struct vxlan_fdb *f;
28342824

28352825
if (!netif_running(vxlan->dev))
28362826
return;
28372827

28382828
spin_lock(&vxlan->hash_lock);
2839-
for (h = 0; h < FDB_HASH_SIZE; ++h) {
2840-
struct hlist_node *p, *n;
2841-
2842-
hlist_for_each_safe(p, n, &vxlan->fdb_head[h]) {
2843-
struct vxlan_fdb *f
2844-
= container_of(p, struct vxlan_fdb, hlist);
2845-
unsigned long timeout;
2829+
hlist_for_each_entry_safe(f, n, &vxlan->fdb_list, fdb_node) {
2830+
unsigned long timeout;
28462831

2847-
if (f->state & (NUD_PERMANENT | NUD_NOARP))
2848-
continue;
2832+
if (f->state & (NUD_PERMANENT | NUD_NOARP))
2833+
continue;
28492834

2850-
if (f->flags & NTF_EXT_LEARNED)
2851-
continue;
2835+
if (f->flags & NTF_EXT_LEARNED)
2836+
continue;
28522837

2853-
timeout = READ_ONCE(f->updated) + vxlan->cfg.age_interval * HZ;
2854-
if (time_before_eq(timeout, jiffies)) {
2855-
netdev_dbg(vxlan->dev,
2856-
"garbage collect %pM\n",
2857-
f->eth_addr);
2858-
f->state = NUD_STALE;
2859-
vxlan_fdb_destroy(vxlan, f, true, true);
2860-
} else if (time_before(timeout, next_timer))
2861-
next_timer = timeout;
2838+
timeout = READ_ONCE(f->updated) + vxlan->cfg.age_interval * HZ;
2839+
if (time_before_eq(timeout, jiffies)) {
2840+
netdev_dbg(vxlan->dev, "garbage collect %pM\n",
2841+
f->eth_addr);
2842+
f->state = NUD_STALE;
2843+
vxlan_fdb_destroy(vxlan, f, true, true);
2844+
} else if (time_before(timeout, next_timer)) {
2845+
next_timer = timeout;
28622846
}
28632847
}
28642848
spin_unlock(&vxlan->hash_lock);
@@ -3050,31 +3034,25 @@ static void vxlan_flush(struct vxlan_dev *vxlan,
30503034
const struct vxlan_fdb_flush_desc *desc)
30513035
{
30523036
bool match_remotes = vxlan_fdb_flush_should_match_remotes(desc);
3053-
unsigned int h;
3037+
struct hlist_node *n;
3038+
struct vxlan_fdb *f;
30543039

30553040
spin_lock_bh(&vxlan->hash_lock);
3056-
for (h = 0; h < FDB_HASH_SIZE; ++h) {
3057-
struct hlist_node *p, *n;
3058-
3059-
hlist_for_each_safe(p, n, &vxlan->fdb_head[h]) {
3060-
struct vxlan_fdb *f
3061-
= container_of(p, struct vxlan_fdb, hlist);
3062-
3063-
if (!vxlan_fdb_flush_matches(f, vxlan, desc))
3064-
continue;
3065-
3066-
if (match_remotes) {
3067-
bool destroy_fdb = false;
3041+
hlist_for_each_entry_safe(f, n, &vxlan->fdb_list, fdb_node) {
3042+
if (!vxlan_fdb_flush_matches(f, vxlan, desc))
3043+
continue;
30683044

3069-
vxlan_fdb_flush_match_remotes(f, vxlan, desc,
3070-
&destroy_fdb);
3045+
if (match_remotes) {
3046+
bool destroy_fdb = false;
30713047

3072-
if (!destroy_fdb)
3073-
continue;
3074-
}
3048+
vxlan_fdb_flush_match_remotes(f, vxlan, desc,
3049+
&destroy_fdb);
30753050

3076-
vxlan_fdb_destroy(vxlan, f, true, true);
3051+
if (!destroy_fdb)
3052+
continue;
30773053
}
3054+
3055+
vxlan_fdb_destroy(vxlan, f, true, true);
30783056
}
30793057
spin_unlock_bh(&vxlan->hash_lock);
30803058
}
@@ -4860,7 +4838,7 @@ static void vxlan_fdb_nh_flush(struct nexthop *nh)
48604838
vxlan = rcu_dereference(fdb->vdev);
48614839
WARN_ON(!vxlan);
48624840
spin_lock_bh(&vxlan->hash_lock);
4863-
if (!hlist_unhashed(&fdb->hlist))
4841+
if (!hlist_unhashed(&fdb->fdb_node))
48644842
vxlan_fdb_destroy(vxlan, fdb, false, false);
48654843
spin_unlock_bh(&vxlan->hash_lock);
48664844
}

0 commit comments

Comments
 (0)