Skip to content

Commit ebecca5

Browse files
sreedeviintelanguy11
authored andcommitted
idpf: Fix RSS LUT NULL ptr issue after soft reset
During soft reset, the RSS LUT is freed and not restored unless the interface is up. If an ethtool command that accesses the rss lut is attempted immediately after reset, it will result in NULL ptr dereference. Also, there is no need to reset the rss lut if the soft reset does not involve queue count change. After soft reset, set the RSS LUT to default values based on the updated queue count only if the reset was a result of a queue count change and the LUT was not configured by the user. In all other cases, don't touch the LUT. Steps to reproduce: ** Bring the interface down (if up) ifconfig eth1 down ** update the queue count (eg., 27->20) ethtool -L eth1 combined 20 ** display the RSS LUT ethtool -x eth1 [82375.558338] BUG: kernel NULL pointer dereference, address: 0000000000000000 [82375.558373] #PF: supervisor read access in kernel mode [82375.558391] #PF: error_code(0x0000) - not-present page [82375.558408] PGD 0 P4D 0 [82375.558421] Oops: Oops: 0000 [#1] SMP NOPTI <snip> [82375.558516] RIP: 0010:idpf_get_rxfh+0x108/0x150 [idpf] [82375.558786] Call Trace: [82375.558793] <TASK> [82375.558804] rss_prepare.isra.0+0x187/0x2a0 [82375.558827] rss_prepare_data+0x3a/0x50 [82375.558845] ethnl_default_doit+0x13d/0x3e0 [82375.558863] genl_family_rcv_msg_doit+0x11f/0x180 [82375.558886] genl_rcv_msg+0x1ad/0x2b0 [82375.558902] ? __pfx_ethnl_default_doit+0x10/0x10 [82375.558920] ? __pfx_genl_rcv_msg+0x10/0x10 [82375.558937] netlink_rcv_skb+0x58/0x100 [82375.558957] genl_rcv+0x2c/0x50 [82375.558971] netlink_unicast+0x289/0x3e0 [82375.558988] netlink_sendmsg+0x215/0x440 [82375.559005] __sys_sendto+0x234/0x240 [82375.559555] __x64_sys_sendto+0x28/0x30 [82375.560068] x64_sys_call+0x1909/0x1da0 [82375.560576] do_syscall_64+0x7a/0xfa0 [82375.561076] ? clear_bhb_loop+0x60/0xb0 [82375.561567] entry_SYSCALL_64_after_hwframe+0x76/0x7e <snip> Fixes: 02cbfba ("idpf: add ethtool callbacks") Signed-off-by: Sreedevi Joshi <sreedevi.joshi@intel.com> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com> Reviewed-by: Emil Tantilov <emil.s.tantilov@intel.com> Reviewed-by: Simon Horman <horms@kernel.org> Tested-by: Samuel Salin <Samuel.salin@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
1 parent 445b49d commit ebecca5

3 files changed

Lines changed: 6 additions & 17 deletions

File tree

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

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,8 +1484,6 @@ static int idpf_vport_open(struct idpf_vport *vport, bool rtnl)
14841484
{
14851485
struct idpf_netdev_priv *np = netdev_priv(vport->netdev);
14861486
struct idpf_adapter *adapter = vport->adapter;
1487-
struct idpf_vport_config *vport_config;
1488-
struct idpf_rss_data *rss_data;
14891487
int err;
14901488

14911489
if (test_bit(IDPF_VPORT_UP, np->state))
@@ -1579,19 +1577,6 @@ static int idpf_vport_open(struct idpf_vport *vport, bool rtnl)
15791577

15801578
idpf_restore_features(vport);
15811579

1582-
vport_config = adapter->vport_config[vport->idx];
1583-
rss_data = &vport_config->user_config.rss_data;
1584-
1585-
if (!rss_data->rss_lut) {
1586-
err = idpf_init_rss_lut(vport);
1587-
if (err) {
1588-
dev_err(&adapter->pdev->dev,
1589-
"Failed to initialize RSS LUT for vport %u: %d\n",
1590-
vport->vport_id, err);
1591-
goto disable_vport;
1592-
}
1593-
}
1594-
15951580
err = idpf_config_rss(vport);
15961581
if (err) {
15971582
dev_err(&adapter->pdev->dev, "Failed to configure RSS for vport %u: %d\n",
@@ -2068,7 +2053,6 @@ int idpf_initiate_soft_reset(struct idpf_vport *vport,
20682053
idpf_vport_stop(vport, false);
20692054
}
20702055

2071-
idpf_deinit_rss_lut(vport);
20722056
/* We're passing in vport here because we need its wait_queue
20732057
* to send a message and it should be getting all the vport
20742058
* config data out of the adapter but we need to be careful not
@@ -2094,6 +2078,10 @@ int idpf_initiate_soft_reset(struct idpf_vport *vport,
20942078
if (err)
20952079
goto err_open;
20962080

2081+
if (reset_cause == IDPF_SR_Q_CHANGE &&
2082+
!netif_is_rxfh_configured(vport->netdev))
2083+
idpf_fill_dflt_rss_lut(vport);
2084+
20972085
if (vport_is_up)
20982086
err = idpf_vport_open(vport, false);
20992087

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4641,7 +4641,7 @@ int idpf_config_rss(struct idpf_vport *vport)
46414641
* idpf_fill_dflt_rss_lut - Fill the indirection table with the default values
46424642
* @vport: virtual port structure
46434643
*/
4644-
static void idpf_fill_dflt_rss_lut(struct idpf_vport *vport)
4644+
void idpf_fill_dflt_rss_lut(struct idpf_vport *vport)
46454645
{
46464646
struct idpf_adapter *adapter = vport->adapter;
46474647
u16 num_active_rxq = vport->num_rxq;

drivers/net/ethernet/intel/idpf/idpf_txrx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,7 @@ void idpf_vport_intr_update_itr_ena_irq(struct idpf_q_vector *q_vector);
10851085
void idpf_vport_intr_deinit(struct idpf_vport *vport);
10861086
int idpf_vport_intr_init(struct idpf_vport *vport);
10871087
void idpf_vport_intr_ena(struct idpf_vport *vport);
1088+
void idpf_fill_dflt_rss_lut(struct idpf_vport *vport);
10881089
int idpf_config_rss(struct idpf_vport *vport);
10891090
int idpf_init_rss_lut(struct idpf_vport *vport);
10901091
void idpf_deinit_rss_lut(struct idpf_vport *vport);

0 commit comments

Comments
 (0)