Commit 8ddb3326 authored by Jesse Brandeburg's avatar Jesse Brandeburg Committed by Jeff Kirsher

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: default avatarStefan Assmann <sassmann@redhat.com>
Signed-off-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 6e80a18c
...@@ -567,10 +567,6 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment