net: stmmac: Re-work the queue selection for TSO packets
Ben Hutchings says:
"This is the wrong place to change the queue mapping.
stmmac_xmit() is called with a specific TX queue locked,
and accessing a different TX queue results in a data race
for all of that queue's state.
I think this commit should be reverted upstream and in all
stable branches. Instead, the driver should implement the
ndo_select_queue operation and override the queue mapping there."
Fixes: c5acdbee22
("net: stmmac: Send TSO packets always from Queue 0")
Suggested-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
36c4357c63
Коммит
4993e5b37e
|
@ -3045,17 +3045,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
/* Manage oversized TCP frames for GMAC4 device */
|
||||
if (skb_is_gso(skb) && priv->tso) {
|
||||
if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
|
||||
/*
|
||||
* There is no way to determine the number of TSO
|
||||
* capable Queues. Let's use always the Queue 0
|
||||
* because if TSO is supported then at least this
|
||||
* one will be capable.
|
||||
*/
|
||||
skb_set_queue_mapping(skb, 0);
|
||||
|
||||
if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))
|
||||
return stmmac_tso_xmit(skb, dev);
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely(stmmac_tx_avail(priv, queue) < nfrags + 1)) {
|
||||
|
@ -3872,6 +3863,22 @@ static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,
|
|||
}
|
||||
}
|
||||
|
||||
static u16 stmmac_select_queue(struct net_device *dev, struct sk_buff *skb,
|
||||
struct net_device *sb_dev)
|
||||
{
|
||||
if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
|
||||
/*
|
||||
* There is no way to determine the number of TSO
|
||||
* capable Queues. Let's use always the Queue 0
|
||||
* because if TSO is supported then at least this
|
||||
* one will be capable.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
return netdev_pick_tx(dev, skb, NULL) % dev->real_num_tx_queues;
|
||||
}
|
||||
|
||||
static int stmmac_set_mac_address(struct net_device *ndev, void *addr)
|
||||
{
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
|
@ -4088,6 +4095,7 @@ static const struct net_device_ops stmmac_netdev_ops = {
|
|||
.ndo_tx_timeout = stmmac_tx_timeout,
|
||||
.ndo_do_ioctl = stmmac_ioctl,
|
||||
.ndo_setup_tc = stmmac_setup_tc,
|
||||
.ndo_select_queue = stmmac_select_queue,
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
.ndo_poll_controller = stmmac_poll_controller,
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче