Skip to content

Commit

Permalink
Merge branch 'mlxsw-Reduce-dependency-between-bridge-and-router-code'
Browse files Browse the repository at this point in the history
Ido Schimmel says:

====================
mlxsw: Reduce dependency between bridge and router code

This patch set reduces the dependency between the bridge and the router
code in preparation for RTNL removal from the route insertion path in
mlxsw.

The motivation and solution are explained in detail in patch #3. The
main idea is that we need to stop special-casing the VXLAN devices with
regards to the reference counting of the FIDs. Otherwise, we can bump
into the situation described in patch #3, where the routing code calls
into the bridge code which calls back into the routing code. After
adding a mutex to protect router data structures to remove RTNL
dependency, this can result in an AA deadlock.

Patches #1 and #2 are preparations. They convert the FIDs to use
'refcount_t' for reference counting in order to catch over/under flows
and add extack to the bridge creation function.

Patches #3-#5 reduce the dependency between the bridge and the router
code. First, by having the VXLAN device take a reference on the FID in
patch #3 and then by removing unnecessary code following the change in
patch #3.

Patches #6-#10 adjust existing selftests and add new ones to exercise
the new code paths.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Feb 17, 2020
2 parents 583cb0b + 495c3da commit 790a9a7
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 132 deletions.
4 changes: 0 additions & 4 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,10 +468,6 @@ int mlxsw_sp_bridge_vxlan_join(struct mlxsw_sp *mlxsw_sp,
struct netlink_ext_ack *extack);
void mlxsw_sp_bridge_vxlan_leave(struct mlxsw_sp *mlxsw_sp,
const struct net_device *vxlan_dev);
struct mlxsw_sp_fid *mlxsw_sp_bridge_fid_get(struct mlxsw_sp *mlxsw_sp,
const struct net_device *br_dev,
u16 vid,
struct netlink_ext_ack *extack);
extern struct notifier_block mlxsw_sp_switchdev_notifier;

/* spectrum.c */
Expand Down
13 changes: 7 additions & 6 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <linux/netdevice.h>
#include <linux/rhashtable.h>
#include <linux/rtnetlink.h>
#include <linux/refcount.h>

#include "spectrum.h"
#include "reg.h"
Expand All @@ -24,7 +25,7 @@ struct mlxsw_sp_fid_core {
struct mlxsw_sp_fid {
struct list_head list;
struct mlxsw_sp_rif *rif;
unsigned int ref_count;
refcount_t ref_count;
u16 fid_index;
struct mlxsw_sp_fid_family *fid_family;
struct rhash_head ht_node;
Expand Down Expand Up @@ -149,7 +150,7 @@ struct mlxsw_sp_fid *mlxsw_sp_fid_lookup_by_index(struct mlxsw_sp *mlxsw_sp,
fid = rhashtable_lookup_fast(&mlxsw_sp->fid_core->fid_ht, &fid_index,
mlxsw_sp_fid_ht_params);
if (fid)
fid->ref_count++;
refcount_inc(&fid->ref_count);

return fid;
}
Expand Down Expand Up @@ -183,7 +184,7 @@ struct mlxsw_sp_fid *mlxsw_sp_fid_lookup_by_vni(struct mlxsw_sp *mlxsw_sp,
fid = rhashtable_lookup_fast(&mlxsw_sp->fid_core->vni_ht, &vni,
mlxsw_sp_fid_vni_ht_params);
if (fid)
fid->ref_count++;
refcount_inc(&fid->ref_count);

return fid;
}
Expand Down Expand Up @@ -1030,7 +1031,7 @@ static struct mlxsw_sp_fid *mlxsw_sp_fid_lookup(struct mlxsw_sp *mlxsw_sp,
list_for_each_entry(fid, &fid_family->fids_list, list) {
if (!fid->fid_family->ops->compare(fid, arg))
continue;
fid->ref_count++;
refcount_inc(&fid->ref_count);
return fid;
}

Expand Down Expand Up @@ -1075,7 +1076,7 @@ static struct mlxsw_sp_fid *mlxsw_sp_fid_get(struct mlxsw_sp *mlxsw_sp,
goto err_rhashtable_insert;

list_add(&fid->list, &fid_family->fids_list);
fid->ref_count++;
refcount_set(&fid->ref_count, 1);
return fid;

err_rhashtable_insert:
Expand All @@ -1093,7 +1094,7 @@ void mlxsw_sp_fid_put(struct mlxsw_sp_fid *fid)
struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
struct mlxsw_sp *mlxsw_sp = fid_family->mlxsw_sp;

if (--fid->ref_count != 0)
if (!refcount_dec_and_test(&fid->ref_count))
return;

list_del(&fid->list);
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
Original file line number Diff line number Diff line change
Expand Up @@ -7428,7 +7428,7 @@ mlxsw_sp_rif_vlan_fid_get(struct mlxsw_sp_rif *rif,
}
}

return mlxsw_sp_bridge_fid_get(rif->mlxsw_sp, br_dev, vid, extack);
return mlxsw_sp_fid_8021q_get(rif->mlxsw_sp, vid);
}

static void mlxsw_sp_rif_vlan_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
Expand Down Expand Up @@ -7519,7 +7519,7 @@ static struct mlxsw_sp_fid *
mlxsw_sp_rif_fid_fid_get(struct mlxsw_sp_rif *rif,
struct netlink_ext_ack *extack)
{
return mlxsw_sp_bridge_fid_get(rif->mlxsw_sp, rif->dev, 0, extack);
return mlxsw_sp_fid_8021d_get(rif->mlxsw_sp, rif->dev->ifindex);
}

static void mlxsw_sp_rif_fid_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
Expand Down
Loading

0 comments on commit 790a9a7

Please sign in to comment.