Skip to content

Commit 894cafc

Browse files
vladimirolteandavem330
authored andcommitted
net: dsa: sja1105: fix -ENOSPC when replacing the same tc-cbs too many times
After running command [2] too many times in a row: [1] $ tc qdisc add dev sw2p0 root handle 1: mqprio num_tc 8 \ map 0 1 2 3 4 5 6 7 queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 hw 0 [2] $ tc qdisc replace dev sw2p0 parent 1:1 cbs offload 1 \ idleslope 120000 sendslope -880000 locredit -1320 hicredit 180 (aka more than priv->info->num_cbs_shapers times) we start seeing the following error message: Error: Specified device failed to setup cbs hardware offload. This comes from the fact that ndo_setup_tc(TC_SETUP_QDISC_CBS) presents the same API for the qdisc create and replace cases, and the sja1105 driver fails to distinguish between the 2. Thus, it always thinks that it must allocate the same shaper for a {port, queue} pair, when it may instead have to replace an existing one. Fixes: 4d75250 ("net: dsa: sja1105: offload the Credit-Based Shaper qdisc") Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 954ad9b commit 894cafc

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

drivers/net/dsa/sja1105/sja1105_main.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2116,6 +2116,18 @@ static void sja1105_bridge_leave(struct dsa_switch *ds, int port,
21162116

21172117
#define BYTES_PER_KBIT (1000LL / 8)
21182118

2119+
static int sja1105_find_cbs_shaper(struct sja1105_private *priv,
2120+
int port, int prio)
2121+
{
2122+
int i;
2123+
2124+
for (i = 0; i < priv->info->num_cbs_shapers; i++)
2125+
if (priv->cbs[i].port == port && priv->cbs[i].prio == prio)
2126+
return i;
2127+
2128+
return -1;
2129+
}
2130+
21192131
static int sja1105_find_unused_cbs_shaper(struct sja1105_private *priv)
21202132
{
21212133
int i;
@@ -2156,9 +2168,14 @@ static int sja1105_setup_tc_cbs(struct dsa_switch *ds, int port,
21562168
if (!offload->enable)
21572169
return sja1105_delete_cbs_shaper(priv, port, offload->queue);
21582170

2159-
index = sja1105_find_unused_cbs_shaper(priv);
2160-
if (index < 0)
2161-
return -ENOSPC;
2171+
/* The user may be replacing an existing shaper */
2172+
index = sja1105_find_cbs_shaper(priv, port, offload->queue);
2173+
if (index < 0) {
2174+
/* That isn't the case - see if we can allocate a new one */
2175+
index = sja1105_find_unused_cbs_shaper(priv);
2176+
if (index < 0)
2177+
return -ENOSPC;
2178+
}
21622179

21632180
cbs = &priv->cbs[index];
21642181
cbs->port = port;

0 commit comments

Comments
 (0)