Commit e60234dd authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

mlxsw: spectrum_router: Use ordered workqueue for neigh updates

We currently associate each neighbour entry with a work item, so it's
not possible to have multiple events queued for the same neighbour
entry. However, this is about to be changed so that the neighbour entry
is only resolved when the work item is scheduled.

The above can result in a mismatch between the kernel's and the device's
neighbour table, unless the associated work items are processed in the
order in which they were submitted.

Do that by migrating the NEIGH_UPDATE work items to be processed in the
ordered workqueue which was recently introduced in mlxsw in commit
a3832b31 ("mlxsw: core: Create an ordered workqueue for FIB
offload").
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a0e4761d
...@@ -614,7 +614,7 @@ struct mlxsw_sp_neigh_entry { ...@@ -614,7 +614,7 @@ struct mlxsw_sp_neigh_entry {
struct mlxsw_sp_neigh_key key; struct mlxsw_sp_neigh_key key;
u16 rif; u16 rif;
bool offloaded; bool offloaded;
struct delayed_work dw; struct work_struct work;
struct mlxsw_sp_port *mlxsw_sp_port; struct mlxsw_sp_port *mlxsw_sp_port;
unsigned char ha[ETH_ALEN]; unsigned char ha[ETH_ALEN];
struct list_head nexthop_list; /* list of nexthops using struct list_head nexthop_list; /* list of nexthops using
...@@ -659,7 +659,7 @@ mlxsw_sp_neigh_entry_create(struct neighbour *n, u16 rif) ...@@ -659,7 +659,7 @@ mlxsw_sp_neigh_entry_create(struct neighbour *n, u16 rif)
return NULL; return NULL;
neigh_entry->key.n = n; neigh_entry->key.n = n;
neigh_entry->rif = rif; neigh_entry->rif = rif;
INIT_DELAYED_WORK(&neigh_entry->dw, mlxsw_sp_router_neigh_update_hw); INIT_WORK(&neigh_entry->work, mlxsw_sp_router_neigh_update_hw);
INIT_LIST_HEAD(&neigh_entry->nexthop_list); INIT_LIST_HEAD(&neigh_entry->nexthop_list);
return neigh_entry; return neigh_entry;
} }
...@@ -935,7 +935,7 @@ mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp, ...@@ -935,7 +935,7 @@ mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp,
static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work) static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work)
{ {
struct mlxsw_sp_neigh_entry *neigh_entry = struct mlxsw_sp_neigh_entry *neigh_entry =
container_of(work, struct mlxsw_sp_neigh_entry, dw.work); container_of(work, struct mlxsw_sp_neigh_entry, work);
struct neighbour *n = neigh_entry->key.n; struct neighbour *n = neigh_entry->key.n;
struct mlxsw_sp_port *mlxsw_sp_port = neigh_entry->mlxsw_sp_port; struct mlxsw_sp_port *mlxsw_sp_port = neigh_entry->mlxsw_sp_port;
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
...@@ -1052,7 +1052,7 @@ int mlxsw_sp_router_netevent_event(struct notifier_block *unused, ...@@ -1052,7 +1052,7 @@ int mlxsw_sp_router_netevent_event(struct notifier_block *unused,
* work. * work.
*/ */
neigh_clone(n); neigh_clone(n);
if (!mlxsw_core_schedule_dw(&neigh_entry->dw, 0)) { if (!mlxsw_core_schedule_work(&neigh_entry->work)) {
neigh_release(n); neigh_release(n);
mlxsw_sp_port_dev_put(mlxsw_sp_port); mlxsw_sp_port_dev_put(mlxsw_sp_port);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment