net: dsa: remove the "dsa_to_port in a loop" antipattern from the core
Ever since Vivien's conversion of the ds->ports array into a dst->ports
list, and the introduction of dsa_to_port, iterations through the ports
of a switch became quadratic whenever dsa_to_port was needed.
dsa_to_port can either be called directly, or indirectly through the
dsa_is_{user,cpu,dsa,unused}_port helpers.
Use the newly introduced dsa_switch_for_each_port() iteration macro
that works with the iterator variable being a struct dsa_port *dp
directly, and not an int i. It is an expensive variable to go from i to
dp, but cheap to go from dp to i.
This macro iterates through the entire ds->dst->ports list and filters
by the ports belonging just to the switch provided as argument.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
82b318983c
commit
d0004a020b
@@ -280,23 +280,22 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static bool dsa_is_port_initialized(struct dsa_switch *ds, int p)
|
||||
static bool dsa_port_is_initialized(const struct dsa_port *dp)
|
||||
{
|
||||
const struct dsa_port *dp = dsa_to_port(ds, p);
|
||||
|
||||
return dp->type == DSA_PORT_TYPE_USER && dp->slave;
|
||||
}
|
||||
|
||||
int dsa_switch_suspend(struct dsa_switch *ds)
|
||||
{
|
||||
int i, ret = 0;
|
||||
struct dsa_port *dp;
|
||||
int ret = 0;
|
||||
|
||||
/* Suspend slave network devices */
|
||||
for (i = 0; i < ds->num_ports; i++) {
|
||||
if (!dsa_is_port_initialized(ds, i))
|
||||
dsa_switch_for_each_port(dp, ds) {
|
||||
if (!dsa_port_is_initialized(dp))
|
||||
continue;
|
||||
|
||||
ret = dsa_slave_suspend(dsa_to_port(ds, i)->slave);
|
||||
ret = dsa_slave_suspend(dp->slave);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -310,7 +309,8 @@ EXPORT_SYMBOL_GPL(dsa_switch_suspend);
|
||||
|
||||
int dsa_switch_resume(struct dsa_switch *ds)
|
||||
{
|
||||
int i, ret = 0;
|
||||
struct dsa_port *dp;
|
||||
int ret = 0;
|
||||
|
||||
if (ds->ops->resume)
|
||||
ret = ds->ops->resume(ds);
|
||||
@@ -319,11 +319,11 @@ int dsa_switch_resume(struct dsa_switch *ds)
|
||||
return ret;
|
||||
|
||||
/* Resume slave network devices */
|
||||
for (i = 0; i < ds->num_ports; i++) {
|
||||
if (!dsa_is_port_initialized(ds, i))
|
||||
dsa_switch_for_each_port(dp, ds) {
|
||||
if (!dsa_port_is_initialized(dp))
|
||||
continue;
|
||||
|
||||
ret = dsa_slave_resume(dsa_to_port(ds, i)->slave);
|
||||
ret = dsa_slave_resume(dp->slave);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user