Skip to content

Commit 3d8597d

Browse files
author
Paolo Abeni
committed
Merge branch 'intel-interpret-set_channels-input-differently'
Jacob Keller says: ==================== intel: Interpret .set_channels() input differently The ice and idpf drivers can trigger a crash with AF_XDP due to incorrect interpretation of the asymmetric Tx and Rx parameters in their .set_channels() implementations: 1. ethtool -l <IFNAME> -> combined: 40 2. Attach AF_XDP to queue 30 3. ethtool -L <IFNAME> rx 15 tx 15 combined number is not specified, so command becomes {rx_count = 15, tx_count = 15, combined_count = 40}. 4. ethnl_set_channels checks, if there are any AF_XDP of queues from the new (combined_count + rx_count) to the old one, so from 55 to 40, check does not trigger. 5. the driver interprets `rx 15 tx 15` as 15 combined channels and deletes the queue that AF_XDP is attached to. This is fundamentally a problem with interpreting a request for asymmetric queues as symmetric combined queues. Fix the ice and idpf drivers to stop interpreting such requests as a request for combined queues. Due to current driver design for both ice and idpf, it is not possible to support requests of the same count of Tx and Rx queues with independent interrupts, (i.e. ethtool -L <IFNAME> rx 15 tx 15) so such requests are now rejected. Signed-off-by: Jacob Keller <[email protected]> ==================== Link: https://lore.kernel.org/r/20240521-iwl-net-2024-05-14-set-channels-fixes-v2-0-7aa39e2e99f1@intel.com Signed-off-by: Paolo Abeni <[email protected]>
2 parents 6671e35 + 5e7695e commit 3d8597d

File tree

2 files changed

+8
-32
lines changed

2 files changed

+8
-32
lines changed

drivers/net/ethernet/intel/ice/ice_ethtool.c

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3593,7 +3593,6 @@ static int ice_set_channels(struct net_device *dev, struct ethtool_channels *ch)
35933593
struct ice_pf *pf = vsi->back;
35943594
int new_rx = 0, new_tx = 0;
35953595
bool locked = false;
3596-
u32 curr_combined;
35973596
int ret = 0;
35983597

35993598
/* do not support changing channels in Safe Mode */
@@ -3615,22 +3614,8 @@ static int ice_set_channels(struct net_device *dev, struct ethtool_channels *ch)
36153614
return -EOPNOTSUPP;
36163615
}
36173616

3618-
curr_combined = ice_get_combined_cnt(vsi);
3619-
3620-
/* these checks are for cases where user didn't specify a particular
3621-
* value on cmd line but we get non-zero value anyway via
3622-
* get_channels(); look at ethtool.c in ethtool repository (the user
3623-
* space part), particularly, do_schannels() routine
3624-
*/
3625-
if (ch->rx_count == vsi->num_rxq - curr_combined)
3626-
ch->rx_count = 0;
3627-
if (ch->tx_count == vsi->num_txq - curr_combined)
3628-
ch->tx_count = 0;
3629-
if (ch->combined_count == curr_combined)
3630-
ch->combined_count = 0;
3631-
3632-
if (!(ch->combined_count || (ch->rx_count && ch->tx_count))) {
3633-
netdev_err(dev, "Please specify at least 1 Rx and 1 Tx channel\n");
3617+
if (ch->rx_count && ch->tx_count) {
3618+
netdev_err(dev, "Dedicated RX or TX channels cannot be used simultaneously\n");
36343619
return -EINVAL;
36353620
}
36363621

drivers/net/ethernet/intel/idpf/idpf_ethtool.c

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -222,14 +222,19 @@ static int idpf_set_channels(struct net_device *netdev,
222222
struct ethtool_channels *ch)
223223
{
224224
struct idpf_vport_config *vport_config;
225-
u16 combined, num_txq, num_rxq;
226225
unsigned int num_req_tx_q;
227226
unsigned int num_req_rx_q;
228227
struct idpf_vport *vport;
228+
u16 num_txq, num_rxq;
229229
struct device *dev;
230230
int err = 0;
231231
u16 idx;
232232

233+
if (ch->rx_count && ch->tx_count) {
234+
netdev_err(netdev, "Dedicated RX or TX channels cannot be used simultaneously\n");
235+
return -EINVAL;
236+
}
237+
233238
idpf_vport_ctrl_lock(netdev);
234239
vport = idpf_netdev_to_vport(netdev);
235240

@@ -239,20 +244,6 @@ static int idpf_set_channels(struct net_device *netdev,
239244
num_txq = vport_config->user_config.num_req_tx_qs;
240245
num_rxq = vport_config->user_config.num_req_rx_qs;
241246

242-
combined = min(num_txq, num_rxq);
243-
244-
/* these checks are for cases where user didn't specify a particular
245-
* value on cmd line but we get non-zero value anyway via
246-
* get_channels(); look at ethtool.c in ethtool repository (the user
247-
* space part), particularly, do_schannels() routine
248-
*/
249-
if (ch->combined_count == combined)
250-
ch->combined_count = 0;
251-
if (ch->combined_count && ch->rx_count == num_rxq - combined)
252-
ch->rx_count = 0;
253-
if (ch->combined_count && ch->tx_count == num_txq - combined)
254-
ch->tx_count = 0;
255-
256247
num_req_tx_q = ch->combined_count + ch->tx_count;
257248
num_req_rx_q = ch->combined_count + ch->rx_count;
258249

0 commit comments

Comments
 (0)