Skip to content

Commit d003462

Browse files
idoschdavem330
authored andcommitted
mlxsw: Simplify mlxsw_sx_port_xmit function
Previously we only checked if the transmission queue is not full in the middle of the xmit function. This lead to complex logic due to the fact that sometimes we need to reallocate the headroom for our Tx header. Allow the switch driver to know if the transmission queue is not full before sending the packet and remove this complex logic. Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7b7b9cf commit d003462

File tree

4 files changed

+40
-20
lines changed

4 files changed

+40
-20
lines changed

drivers/net/ethernet/mellanox/mlxsw/core.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,16 @@ static struct mlxsw_core *__mlxsw_core_get(void *driver_priv)
865865
return container_of(driver_priv, struct mlxsw_core, driver_priv);
866866
}
867867

868+
bool mlxsw_core_skb_transmit_busy(void *driver_priv,
869+
const struct mlxsw_tx_info *tx_info)
870+
{
871+
struct mlxsw_core *mlxsw_core = __mlxsw_core_get(driver_priv);
872+
873+
return mlxsw_core->bus->skb_transmit_busy(mlxsw_core->bus_priv,
874+
tx_info);
875+
}
876+
EXPORT_SYMBOL(mlxsw_core_skb_transmit_busy);
877+
868878
int mlxsw_core_skb_transmit(void *driver_priv, struct sk_buff *skb,
869879
const struct mlxsw_tx_info *tx_info)
870880
{

drivers/net/ethernet/mellanox/mlxsw/core.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ struct mlxsw_tx_info {
7373
bool is_emad;
7474
};
7575

76+
bool mlxsw_core_skb_transmit_busy(void *driver_priv,
77+
const struct mlxsw_tx_info *tx_info);
78+
7679
int mlxsw_core_skb_transmit(void *driver_priv, struct sk_buff *skb,
7780
const struct mlxsw_tx_info *tx_info);
7881

@@ -177,6 +180,8 @@ struct mlxsw_bus {
177180
int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core,
178181
const struct mlxsw_config_profile *profile);
179182
void (*fini)(void *bus_priv);
183+
bool (*skb_transmit_busy)(void *bus_priv,
184+
const struct mlxsw_tx_info *tx_info);
180185
int (*skb_transmit)(void *bus_priv, struct sk_buff *skb,
181186
const struct mlxsw_tx_info *tx_info);
182187
int (*cmd_exec)(void *bus_priv, u16 opcode, u8 opcode_mod,

drivers/net/ethernet/mellanox/mlxsw/pci.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,6 +1443,15 @@ mlxsw_pci_sdq_pick(struct mlxsw_pci *mlxsw_pci,
14431443
return mlxsw_pci_sdq_get(mlxsw_pci, sdqn);
14441444
}
14451445

1446+
static bool mlxsw_pci_skb_transmit_busy(void *bus_priv,
1447+
const struct mlxsw_tx_info *tx_info)
1448+
{
1449+
struct mlxsw_pci *mlxsw_pci = bus_priv;
1450+
struct mlxsw_pci_queue *q = mlxsw_pci_sdq_pick(mlxsw_pci, tx_info);
1451+
1452+
return !mlxsw_pci_queue_elem_info_producer_get(q);
1453+
}
1454+
14461455
static int mlxsw_pci_skb_transmit(void *bus_priv, struct sk_buff *skb,
14471456
const struct mlxsw_tx_info *tx_info)
14481457
{
@@ -1625,11 +1634,12 @@ static int mlxsw_pci_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod,
16251634
}
16261635

16271636
static const struct mlxsw_bus mlxsw_pci_bus = {
1628-
.kind = "pci",
1629-
.init = mlxsw_pci_init,
1630-
.fini = mlxsw_pci_fini,
1631-
.skb_transmit = mlxsw_pci_skb_transmit,
1632-
.cmd_exec = mlxsw_pci_cmd_exec,
1637+
.kind = "pci",
1638+
.init = mlxsw_pci_init,
1639+
.fini = mlxsw_pci_fini,
1640+
.skb_transmit_busy = mlxsw_pci_skb_transmit_busy,
1641+
.skb_transmit = mlxsw_pci_skb_transmit,
1642+
.cmd_exec = mlxsw_pci_cmd_exec,
16331643
};
16341644

16351645
static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci)

drivers/net/ethernet/mellanox/mlxsw/switchx2.c

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -300,31 +300,26 @@ static netdev_tx_t mlxsw_sx_port_xmit(struct sk_buff *skb,
300300
.local_port = mlxsw_sx_port->local_port,
301301
.is_emad = false,
302302
};
303-
struct sk_buff *skb_old = NULL;
304303
int err;
305304

305+
if (mlxsw_core_skb_transmit_busy(mlxsw_sx, &tx_info))
306+
return NETDEV_TX_BUSY;
307+
306308
if (unlikely(skb_headroom(skb) < MLXSW_TXHDR_LEN)) {
307-
struct sk_buff *skb_new;
309+
struct sk_buff *skb_orig = skb;
308310

309-
skb_old = skb;
310-
skb_new = skb_realloc_headroom(skb, MLXSW_TXHDR_LEN);
311-
if (!skb_new) {
311+
skb = skb_realloc_headroom(skb, MLXSW_TXHDR_LEN);
312+
if (!skb) {
312313
this_cpu_inc(mlxsw_sx_port->pcpu_stats->tx_dropped);
313-
dev_kfree_skb_any(skb_old);
314+
dev_kfree_skb_any(skb_orig);
314315
return NETDEV_TX_OK;
315316
}
316-
skb = skb_new;
317317
}
318318
mlxsw_sx_txhdr_construct(skb, &tx_info);
319+
/* Due to a race we might fail here because of a full queue. In that
320+
* unlikely case we simply drop the packet.
321+
*/
319322
err = mlxsw_core_skb_transmit(mlxsw_sx, skb, &tx_info);
320-
if (err == -EAGAIN) {
321-
if (skb_old)
322-
dev_kfree_skb_any(skb);
323-
return NETDEV_TX_BUSY;
324-
}
325-
326-
if (skb_old)
327-
dev_kfree_skb_any(skb_old);
328323

329324
if (!err) {
330325
pcpu_stats = this_cpu_ptr(mlxsw_sx_port->pcpu_stats);

0 commit comments

Comments
 (0)