Commit 14304e70 authored by Petr Machata's avatar Petr Machata Committed by David S. Miller

mlxsw: spectrum_router: Use the available router pointer for netevent handling

This code handles NETEVENT_DELAY_PROBE_TIME_UPDATE, which is invoked every
time the delay_probe_time changes. mlxsw router currently only maintains
one timer, so the last delay_probe_time set wins.

Currently, mlxsw uses mlxsw_sp_port_lower_dev_hold() to find a reference to
the router. This is no longer necessary. But as a side effect, this makes
sure that only updates to "interesting netdevices" (ones that have a
physical netdevice lower) are projected.

Retain that side effect by calling mlxsw_sp_port_dev_lower_find_rcu() and
punting if there is none. Then just proceed using the router pointer that's
already at hand in the helper.

Note that previously, the code took and put a reference of the netdevice.
Because the mlxsw_sp pointer is now obtained from the notifier block, the
port pointer (non-) NULL-ness is all that's relevant, and the reference
does not need to be taken anymore.
Signed-off-by: default avatarPetr Machata <petrm@nvidia.com>
Reviewed-by: default avatarAmit Cohen <amcohen@nvidia.com>
Reviewed-by: default avatarSimon Horman <simon.horman@corigine.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 48dde35e
...@@ -2766,13 +2766,22 @@ static int mlxsw_sp_router_schedule_work(struct net *net, ...@@ -2766,13 +2766,22 @@ static int mlxsw_sp_router_schedule_work(struct net *net,
return NOTIFY_DONE; return NOTIFY_DONE;
} }
static bool mlxsw_sp_dev_lower_is_port(struct net_device *dev)
{
struct mlxsw_sp_port *mlxsw_sp_port;
rcu_read_lock();
mlxsw_sp_port = mlxsw_sp_port_dev_lower_find_rcu(dev);
rcu_read_unlock();
return !!mlxsw_sp_port;
}
static int mlxsw_sp_router_netevent_event(struct notifier_block *nb, static int mlxsw_sp_router_netevent_event(struct notifier_block *nb,
unsigned long event, void *ptr) unsigned long event, void *ptr)
{ {
struct mlxsw_sp_netevent_work *net_work; struct mlxsw_sp_netevent_work *net_work;
struct mlxsw_sp_port *mlxsw_sp_port; struct mlxsw_sp_port *mlxsw_sp_port;
struct mlxsw_sp_router *router; struct mlxsw_sp_router *router;
struct mlxsw_sp *mlxsw_sp;
unsigned long interval; unsigned long interval;
struct neigh_parms *p; struct neigh_parms *p;
struct neighbour *n; struct neighbour *n;
...@@ -2791,15 +2800,11 @@ static int mlxsw_sp_router_netevent_event(struct notifier_block *nb, ...@@ -2791,15 +2800,11 @@ static int mlxsw_sp_router_netevent_event(struct notifier_block *nb,
/* We are in atomic context and can't take RTNL mutex, /* We are in atomic context and can't take RTNL mutex,
* so use RCU variant to walk the device chain. * so use RCU variant to walk the device chain.
*/ */
mlxsw_sp_port = mlxsw_sp_port_lower_dev_hold(p->dev); if (!mlxsw_sp_dev_lower_is_port(p->dev))
if (!mlxsw_sp_port)
return NOTIFY_DONE; return NOTIFY_DONE;
mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
interval = jiffies_to_msecs(NEIGH_VAR(p, DELAY_PROBE_TIME)); interval = jiffies_to_msecs(NEIGH_VAR(p, DELAY_PROBE_TIME));
mlxsw_sp->router->neighs_update.interval = interval; router->neighs_update.interval = interval;
mlxsw_sp_port_dev_put(mlxsw_sp_port);
break; break;
case NETEVENT_NEIGH_UPDATE: case NETEVENT_NEIGH_UPDATE:
n = ptr; n = ptr;
......
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