ice: Delay netdev registration

Once a netdev is registered, the corresponding network interface can
be immediately used by userspace utilities (like say NetworkManager).
This can be problematic if the driver technically isn't fully up yet.

Move netdev registration to the end of probe, as by this time the
driver data structures and device will be initialized as expected.

However, delaying netdev registration causes a failure in the aRFS flow
where netdev->reg_state == NETREG_REGISTERED condition is checked. It's
not clear why this check was added to begin with, so remove it.
Local testing didn't indicate any issues with this change.

The state bit check in ice_open was put in as a stop-gap measure to
prevent a premature interface up operation. This is no longer needed,
so remove it.

Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
Anirudh Venkataramanan 2021-03-02 10:12:03 -08:00 committed by Tony Nguyen
parent 634da4c118
commit 1e23f076b2
2 changed files with 47 additions and 52 deletions

View file

@ -581,8 +581,7 @@ void ice_free_cpu_rx_rmap(struct ice_vsi *vsi)
return;
netdev = vsi->netdev;
if (!netdev || !netdev->rx_cpu_rmap ||
netdev->reg_state != NETREG_REGISTERED)
if (!netdev || !netdev->rx_cpu_rmap)
return;
free_irq_cpu_rmap(netdev->rx_cpu_rmap);
@ -604,8 +603,7 @@ int ice_set_cpu_rx_rmap(struct ice_vsi *vsi)
pf = vsi->back;
netdev = vsi->netdev;
if (!pf || !netdev || !vsi->num_q_vectors ||
vsi->netdev->reg_state != NETREG_REGISTERED)
if (!pf || !netdev || !vsi->num_q_vectors)
return -EINVAL;
netdev_dbg(netdev, "Setup CPU RMAP: vsi type 0x%x, ifname %s, q_vectors %d\n",

View file

@ -140,21 +140,10 @@ static int ice_init_mac_fltr(struct ice_pf *pf)
perm_addr = vsi->port_info->mac.perm_addr;
status = ice_fltr_add_mac_and_broadcast(vsi, perm_addr, ICE_FWD_TO_VSI);
if (!status)
return 0;
if (status)
return -EIO;
/* We aren't useful with no MAC filters, so unregister if we
* had an error
*/
if (vsi->netdev->reg_state == NETREG_REGISTERED) {
dev_err(ice_pf_to_dev(pf), "Could not add MAC filters error %s. Unregistering device\n",
ice_stat_str(status));
unregister_netdev(vsi->netdev);
free_netdev(vsi->netdev);
vsi->netdev = NULL;
}
return -EIO;
return 0;
}
/**
@ -2982,18 +2971,11 @@ static int ice_cfg_netdev(struct ice_vsi *vsi)
struct ice_netdev_priv *np;
struct net_device *netdev;
u8 mac_addr[ETH_ALEN];
int err;
err = ice_devlink_create_port(vsi);
if (err)
return err;
netdev = alloc_etherdev_mqs(sizeof(*np), vsi->alloc_txq,
vsi->alloc_rxq);
if (!netdev) {
err = -ENOMEM;
goto err_destroy_devlink_port;
}
if (!netdev)
return -ENOMEM;
vsi->netdev = netdev;
np = netdev_priv(netdev);
@ -3021,25 +3003,7 @@ static int ice_cfg_netdev(struct ice_vsi *vsi)
netdev->min_mtu = ETH_MIN_MTU;
netdev->max_mtu = ICE_MAX_MTU;
err = register_netdev(vsi->netdev);
if (err)
goto err_free_netdev;
devlink_port_type_eth_set(&vsi->devlink_port, vsi->netdev);
netif_carrier_off(vsi->netdev);
/* make sure transmit queues start off as stopped */
netif_tx_stop_all_queues(vsi->netdev);
return 0;
err_free_netdev:
free_netdev(vsi->netdev);
vsi->netdev = NULL;
err_destroy_devlink_port:
ice_devlink_destroy_port(vsi);
return err;
}
/**
@ -3237,8 +3201,6 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
if (vsi) {
ice_napi_del(vsi);
if (vsi->netdev) {
if (vsi->netdev->reg_state == NETREG_REGISTERED)
unregister_netdev(vsi->netdev);
free_netdev(vsi->netdev);
vsi->netdev = NULL;
}
@ -3992,6 +3954,40 @@ static void ice_print_wake_reason(struct ice_pf *pf)
dev_info(ice_pf_to_dev(pf), "Wake reason: %s", wake_str);
}
/**
* ice_register_netdev - register netdev and devlink port
* @pf: pointer to the PF struct
*/
static int ice_register_netdev(struct ice_pf *pf)
{
struct ice_vsi *vsi;
int err = 0;
vsi = ice_get_main_vsi(pf);
if (!vsi || !vsi->netdev)
return -EIO;
err = register_netdev(vsi->netdev);
if (err)
goto err_register_netdev;
netif_carrier_off(vsi->netdev);
netif_tx_stop_all_queues(vsi->netdev);
err = ice_devlink_create_port(vsi);
if (err)
goto err_devlink_create;
devlink_port_type_eth_set(&vsi->devlink_port, vsi->netdev);
return 0;
err_devlink_create:
unregister_netdev(vsi->netdev);
err_register_netdev:
free_netdev(vsi->netdev);
vsi->netdev = NULL;
return err;
}
/**
* ice_probe - Device initialization routine
* @pdev: PCI device information struct
@ -4272,10 +4268,16 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent)
pcie_print_link_status(pf->pdev);
probe_done:
err = ice_register_netdev(pf);
if (err)
goto err_netdev_reg;
/* ready to go, so clear down state bit */
clear_bit(__ICE_DOWN, pf->state);
return 0;
err_netdev_reg:
err_send_version_unroll:
ice_vsi_release_all(pf);
err_alloc_sw_unroll:
@ -6654,11 +6656,6 @@ int ice_open(struct net_device *netdev)
return -EIO;
}
if (test_bit(__ICE_DOWN, pf->state)) {
netdev_err(netdev, "device is not ready yet\n");
return -EBUSY;
}
netif_carrier_off(netdev);
pi = vsi->port_info;