i40e/i40evf: avoid mutex re-init
If the driver were to happen to have a mutex held while the i40e_init_adminq call was called, the init_adminq might inadvertently call mutex_init on a lock that was held which is a violation of the calling semantics. Fix this by avoiding adminq.c code allocating/freeing this memory, and then do the same work only once in probe/remove. Testing Hints (Required if no HSD): for VF, load i40evf in bare metal and echo 32 > sriov_numvfs; echo 0 > sriov_numvfs in a loop. Yes this is a horrible thing to do. Change-ID: Ida263c51b34e195252179e7e5e400d73a99be7a2 Reported-by: Stefan Assmann <sassmann@redhat.com> Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
6e80a18c56
commit
8ddb332689
|
@ -567,10 +567,6 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
|
||||||
goto init_adminq_exit;
|
goto init_adminq_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize locks */
|
|
||||||
mutex_init(&hw->aq.asq_mutex);
|
|
||||||
mutex_init(&hw->aq.arq_mutex);
|
|
||||||
|
|
||||||
/* Set up register offsets */
|
/* Set up register offsets */
|
||||||
i40e_adminq_init_regs(hw);
|
i40e_adminq_init_regs(hw);
|
||||||
|
|
||||||
|
@ -664,8 +660,6 @@ i40e_status i40e_shutdown_adminq(struct i40e_hw *hw)
|
||||||
i40e_shutdown_asq(hw);
|
i40e_shutdown_asq(hw);
|
||||||
i40e_shutdown_arq(hw);
|
i40e_shutdown_arq(hw);
|
||||||
|
|
||||||
/* destroy the locks */
|
|
||||||
|
|
||||||
if (hw->nvm_buff.va)
|
if (hw->nvm_buff.va)
|
||||||
i40e_free_virt_mem(hw, &hw->nvm_buff);
|
i40e_free_virt_mem(hw, &hw->nvm_buff);
|
||||||
|
|
||||||
|
|
|
@ -10295,6 +10295,12 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
/* set up a default setting for link flow control */
|
/* set up a default setting for link flow control */
|
||||||
pf->hw.fc.requested_mode = I40E_FC_NONE;
|
pf->hw.fc.requested_mode = I40E_FC_NONE;
|
||||||
|
|
||||||
|
/* set up the locks for the AQ, do this only once in probe
|
||||||
|
* and destroy them only once in remove
|
||||||
|
*/
|
||||||
|
mutex_init(&hw->aq.asq_mutex);
|
||||||
|
mutex_init(&hw->aq.arq_mutex);
|
||||||
|
|
||||||
err = i40e_init_adminq(hw);
|
err = i40e_init_adminq(hw);
|
||||||
|
|
||||||
/* provide nvm, fw, api versions */
|
/* provide nvm, fw, api versions */
|
||||||
|
@ -10697,7 +10703,6 @@ static void i40e_remove(struct pci_dev *pdev)
|
||||||
set_bit(__I40E_DOWN, &pf->state);
|
set_bit(__I40E_DOWN, &pf->state);
|
||||||
del_timer_sync(&pf->service_timer);
|
del_timer_sync(&pf->service_timer);
|
||||||
cancel_work_sync(&pf->service_task);
|
cancel_work_sync(&pf->service_task);
|
||||||
i40e_fdir_teardown(pf);
|
|
||||||
|
|
||||||
if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
|
if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
|
||||||
i40e_free_vfs(pf);
|
i40e_free_vfs(pf);
|
||||||
|
@ -10740,6 +10745,10 @@ static void i40e_remove(struct pci_dev *pdev)
|
||||||
"Failed to destroy the Admin Queue resources: %d\n",
|
"Failed to destroy the Admin Queue resources: %d\n",
|
||||||
ret_code);
|
ret_code);
|
||||||
|
|
||||||
|
/* destroy the locks only once, here */
|
||||||
|
mutex_destroy(&hw->aq.arq_mutex);
|
||||||
|
mutex_destroy(&hw->aq.asq_mutex);
|
||||||
|
|
||||||
/* Clear all dynamic memory lists of rings, q_vectors, and VSIs */
|
/* Clear all dynamic memory lists of rings, q_vectors, and VSIs */
|
||||||
i40e_clear_interrupt_scheme(pf);
|
i40e_clear_interrupt_scheme(pf);
|
||||||
for (i = 0; i < pf->num_alloc_vsi; i++) {
|
for (i = 0; i < pf->num_alloc_vsi; i++) {
|
||||||
|
|
|
@ -551,10 +551,6 @@ i40e_status i40evf_init_adminq(struct i40e_hw *hw)
|
||||||
goto init_adminq_exit;
|
goto init_adminq_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize locks */
|
|
||||||
mutex_init(&hw->aq.asq_mutex);
|
|
||||||
mutex_init(&hw->aq.arq_mutex);
|
|
||||||
|
|
||||||
/* Set up register offsets */
|
/* Set up register offsets */
|
||||||
i40e_adminq_init_regs(hw);
|
i40e_adminq_init_regs(hw);
|
||||||
|
|
||||||
|
@ -596,8 +592,6 @@ i40e_status i40evf_shutdown_adminq(struct i40e_hw *hw)
|
||||||
i40e_shutdown_asq(hw);
|
i40e_shutdown_asq(hw);
|
||||||
i40e_shutdown_arq(hw);
|
i40e_shutdown_arq(hw);
|
||||||
|
|
||||||
/* destroy the locks */
|
|
||||||
|
|
||||||
if (hw->nvm_buff.va)
|
if (hw->nvm_buff.va)
|
||||||
i40e_free_virt_mem(hw, &hw->nvm_buff);
|
i40e_free_virt_mem(hw, &hw->nvm_buff);
|
||||||
|
|
||||||
|
|
|
@ -2476,6 +2476,12 @@ static int i40evf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
hw->bus.device = PCI_SLOT(pdev->devfn);
|
hw->bus.device = PCI_SLOT(pdev->devfn);
|
||||||
hw->bus.func = PCI_FUNC(pdev->devfn);
|
hw->bus.func = PCI_FUNC(pdev->devfn);
|
||||||
|
|
||||||
|
/* set up the locks for the AQ, do this only once in probe
|
||||||
|
* and destroy them only once in remove
|
||||||
|
*/
|
||||||
|
mutex_init(&hw->aq.asq_mutex);
|
||||||
|
mutex_init(&hw->aq.arq_mutex);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&adapter->mac_filter_list);
|
INIT_LIST_HEAD(&adapter->mac_filter_list);
|
||||||
INIT_LIST_HEAD(&adapter->vlan_filter_list);
|
INIT_LIST_HEAD(&adapter->vlan_filter_list);
|
||||||
|
|
||||||
|
@ -2629,6 +2635,10 @@ static void i40evf_remove(struct pci_dev *pdev)
|
||||||
if (hw->aq.asq.count)
|
if (hw->aq.asq.count)
|
||||||
i40evf_shutdown_adminq(hw);
|
i40evf_shutdown_adminq(hw);
|
||||||
|
|
||||||
|
/* destroy the locks only once, here */
|
||||||
|
mutex_destroy(&hw->aq.arq_mutex);
|
||||||
|
mutex_destroy(&hw->aq.asq_mutex);
|
||||||
|
|
||||||
iounmap(hw->hw_addr);
|
iounmap(hw->hw_addr);
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue