diff options
author | Julian Wiedmann <jwi@linux.ibm.com> | 2020-03-18 13:54:49 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-03-18 16:33:35 -0700 |
commit | 66cddf101901a6cfcd21c840f0535e8f1c8c5186 (patch) | |
tree | 4da44babbd507b5797611e5e0957906d74c42d8d /drivers | |
parent | fcc2df8b8777c960c8125bc157423c76415a5419 (diff) |
s390/qeth: allow configuration of TX queues for IQD devices
Similar to the support for z/VM NICs, but we need to take extra care
about the dedicated mcast queue:
1. netdev_pick_tx() is unaware of this limitation and might select the
mcast txq. Catch this.
2. require at least _two_ TX queues - one for ucast, one for mcast.
3. when reducing the number of TX queues, there's a potential race
where netdev_cap_txqueue() over-rules the selected txq index and
falls back to index 0. This would place ucast traffic on the mcast
queue, and result in TX errors.
So for IQD, reject a reduction while the interface is running.
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 6 | ||||
-rw-r--r-- | drivers/s390/net/qeth_ethtool.c | 19 |
2 files changed, 21 insertions, 4 deletions
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index f13495d9209b..aa493edc0082 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -6644,9 +6644,13 @@ EXPORT_SYMBOL_GPL(qeth_get_stats64); u16 qeth_iqd_select_queue(struct net_device *dev, struct sk_buff *skb, u8 cast_type, struct net_device *sb_dev) { + u16 txq; + if (cast_type != RTN_UNICAST) return QETH_IQD_MCAST_TXQ; - return QETH_IQD_MIN_UCAST_TXQ; + + txq = netdev_pick_tx(dev, skb, sb_dev); + return (txq == QETH_IQD_MCAST_TXQ) ? QETH_IQD_MIN_UCAST_TXQ : txq; } EXPORT_SYMBOL_GPL(qeth_iqd_select_queue); diff --git a/drivers/s390/net/qeth_ethtool.c b/drivers/s390/net/qeth_ethtool.c index 19b9c8302d36..715ee0015847 100644 --- a/drivers/s390/net/qeth_ethtool.c +++ b/drivers/s390/net/qeth_ethtool.c @@ -180,14 +180,27 @@ static int qeth_set_channels(struct net_device *dev, { struct qeth_card *card = dev->ml_priv; - if (IS_IQD(card) || !IS_VM_NIC(card)) - return -EOPNOTSUPP; - if (channels->rx_count == 0 || channels->tx_count == 0) return -EINVAL; if (channels->tx_count > card->qdio.no_out_queues) return -EINVAL; + if (IS_IQD(card)) { + if (channels->tx_count < QETH_IQD_MIN_TXQ) + return -EINVAL; + + /* Reject downgrade while running. It could push displaced + * ucast flows onto txq0, which is reserved for mcast. + */ + if (netif_running(dev) && + channels->tx_count < dev->real_num_tx_queues) + return -EPERM; + } else { + /* OSA still uses the legacy prio-queue mechanism: */ + if (!IS_VM_NIC(card)) + return -EOPNOTSUPP; + } + return netif_set_real_num_tx_queues(dev, channels->tx_count); } |