Skip to content

Commit 3ff468e

Browse files
vladimirolteankuba-moo
authored andcommitted
net: mscc: ocelot: remove struct ocelot_mm_state :: lock
Unfortunately, the workarounds for the hardware bugs make it pointless to keep fine-grained locking for the MAC Merge state of each port. Our vsc9959_cut_through_fwd() implementation requires ocelot->fwd_domain_lock to be held, in order to serialize with changes to the bridging domains and to port speed changes (which affect which ports can be cut-through). Simultaneously, the traffic classes which can be cut-through cannot be preemptible at the same time, and this will depend on the MAC Merge layer state (which changes from threaded interrupt context). Since vsc9959_cut_through_fwd() would have to hold the mm->lock of all ports for a correct and race-free implementation with respect to ocelot_mm_irq(), in practice it means that any time a port's mm->lock is held, it would potentially block holders of ocelot->fwd_domain_lock. In the interest of simple locking rules, make all MAC Merge layer state changes (and preemptible traffic class changes) be serialized by the ocelot->fwd_domain_lock. Signed-off-by: Vladimir Oltean <[email protected]> Reviewed-by: Simon Horman <[email protected]> Reviewed-by: Florian Fainelli <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 15f93f4 commit 3ff468e

2 files changed

Lines changed: 8 additions & 13 deletions

File tree

drivers/net/ethernet/mscc/ocelot_mm.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ static void ocelot_mm_update_port_status(struct ocelot *ocelot, int port)
5656
enum ethtool_mm_verify_status verify_status;
5757
u32 val;
5858

59-
mutex_lock(&mm->lock);
60-
6159
val = ocelot_port_readl(ocelot_port, DEV_MM_STATUS);
6260

6361
verify_status = ocelot_mm_verify_status(val);
@@ -88,16 +86,18 @@ static void ocelot_mm_update_port_status(struct ocelot *ocelot, int port)
8886
}
8987

9088
ocelot_port_writel(ocelot_port, val, DEV_MM_STATUS);
91-
92-
mutex_unlock(&mm->lock);
9389
}
9490

9591
void ocelot_mm_irq(struct ocelot *ocelot)
9692
{
9793
int port;
9894

95+
mutex_lock(&ocelot->fwd_domain_lock);
96+
9997
for (port = 0; port < ocelot->num_phys_ports; port++)
10098
ocelot_mm_update_port_status(ocelot, port);
99+
100+
mutex_unlock(&ocelot->fwd_domain_lock);
101101
}
102102
EXPORT_SYMBOL_GPL(ocelot_mm_irq);
103103

@@ -107,14 +107,11 @@ int ocelot_port_set_mm(struct ocelot *ocelot, int port,
107107
{
108108
struct ocelot_port *ocelot_port = ocelot->ports[port];
109109
u32 mm_enable = 0, verify_disable = 0, add_frag_size;
110-
struct ocelot_mm_state *mm;
111110
int err;
112111

113112
if (!ocelot->mm_supported)
114113
return -EOPNOTSUPP;
115114

116-
mm = &ocelot->mm[port];
117-
118115
err = ethtool_mm_frag_size_min_to_add(cfg->tx_min_frag_size,
119116
&add_frag_size, extack);
120117
if (err)
@@ -129,7 +126,7 @@ int ocelot_port_set_mm(struct ocelot *ocelot, int port,
129126
if (!cfg->verify_enabled)
130127
verify_disable = DEV_MM_CONFIG_VERIF_CONFIG_PRM_VERIFY_DIS;
131128

132-
mutex_lock(&mm->lock);
129+
mutex_lock(&ocelot->fwd_domain_lock);
133130

134131
ocelot_port_rmwl(ocelot_port, mm_enable,
135132
DEV_MM_CONFIG_ENABLE_CONFIG_MM_TX_ENA |
@@ -148,7 +145,7 @@ int ocelot_port_set_mm(struct ocelot *ocelot, int port,
148145
QSYS_PREEMPTION_CFG,
149146
port);
150147

151-
mutex_unlock(&mm->lock);
148+
mutex_unlock(&ocelot->fwd_domain_lock);
152149

153150
return 0;
154151
}
@@ -166,7 +163,7 @@ int ocelot_port_get_mm(struct ocelot *ocelot, int port,
166163

167164
mm = &ocelot->mm[port];
168165

169-
mutex_lock(&mm->lock);
166+
mutex_lock(&ocelot->fwd_domain_lock);
170167

171168
val = ocelot_port_readl(ocelot_port, DEV_MM_ENABLE_CONFIG);
172169
state->pmac_enabled = !!(val & DEV_MM_CONFIG_ENABLE_CONFIG_MM_RX_ENA);
@@ -185,7 +182,7 @@ int ocelot_port_get_mm(struct ocelot *ocelot, int port,
185182
state->verify_status = mm->verify_status;
186183
state->tx_active = mm->tx_active;
187184

188-
mutex_unlock(&mm->lock);
185+
mutex_unlock(&ocelot->fwd_domain_lock);
189186

190187
return 0;
191188
}
@@ -209,7 +206,6 @@ int ocelot_mm_init(struct ocelot *ocelot)
209206
u32 val;
210207

211208
mm = &ocelot->mm[port];
212-
mutex_init(&mm->lock);
213209
ocelot_port = ocelot->ports[port];
214210

215211
/* Update initial status variable for the

include/soc/mscc/ocelot.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,6 @@ struct ocelot_mirror {
744744
};
745745

746746
struct ocelot_mm_state {
747-
struct mutex lock;
748747
enum ethtool_mm_verify_status verify_status;
749748
bool tx_active;
750749
};

0 commit comments

Comments
 (0)