Skip to content

Commit 8ddb332

Browse files
jbrandebJeff Kirsher
authored andcommitted
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>
1 parent 6e80a18 commit 8ddb332

File tree

4 files changed

+20
-13
lines changed

4 files changed

+20
-13
lines changed

drivers/net/ethernet/intel/i40e/i40e_adminq.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -567,10 +567,6 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
567567
goto init_adminq_exit;
568568
}
569569

570-
/* initialize locks */
571-
mutex_init(&hw->aq.asq_mutex);
572-
mutex_init(&hw->aq.arq_mutex);
573-
574570
/* Set up register offsets */
575571
i40e_adminq_init_regs(hw);
576572

@@ -664,8 +660,6 @@ i40e_status i40e_shutdown_adminq(struct i40e_hw *hw)
664660
i40e_shutdown_asq(hw);
665661
i40e_shutdown_arq(hw);
666662

667-
/* destroy the locks */
668-
669663
if (hw->nvm_buff.va)
670664
i40e_free_virt_mem(hw, &hw->nvm_buff);
671665

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10295,6 +10295,12 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1029510295
/* set up a default setting for link flow control */
1029610296
pf->hw.fc.requested_mode = I40E_FC_NONE;
1029710297

10298+
/* set up the locks for the AQ, do this only once in probe
10299+
* and destroy them only once in remove
10300+
*/
10301+
mutex_init(&hw->aq.asq_mutex);
10302+
mutex_init(&hw->aq.arq_mutex);
10303+
1029810304
err = i40e_init_adminq(hw);
1029910305

1030010306
/* provide nvm, fw, api versions */
@@ -10697,7 +10703,6 @@ static void i40e_remove(struct pci_dev *pdev)
1069710703
set_bit(__I40E_DOWN, &pf->state);
1069810704
del_timer_sync(&pf->service_timer);
1069910705
cancel_work_sync(&pf->service_task);
10700-
i40e_fdir_teardown(pf);
1070110706

1070210707
if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
1070310708
i40e_free_vfs(pf);
@@ -10740,6 +10745,10 @@ static void i40e_remove(struct pci_dev *pdev)
1074010745
"Failed to destroy the Admin Queue resources: %d\n",
1074110746
ret_code);
1074210747

10748+
/* destroy the locks only once, here */
10749+
mutex_destroy(&hw->aq.arq_mutex);
10750+
mutex_destroy(&hw->aq.asq_mutex);
10751+
1074310752
/* Clear all dynamic memory lists of rings, q_vectors, and VSIs */
1074410753
i40e_clear_interrupt_scheme(pf);
1074510754
for (i = 0; i < pf->num_alloc_vsi; i++) {

drivers/net/ethernet/intel/i40evf/i40e_adminq.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -551,10 +551,6 @@ i40e_status i40evf_init_adminq(struct i40e_hw *hw)
551551
goto init_adminq_exit;
552552
}
553553

554-
/* initialize locks */
555-
mutex_init(&hw->aq.asq_mutex);
556-
mutex_init(&hw->aq.arq_mutex);
557-
558554
/* Set up register offsets */
559555
i40e_adminq_init_regs(hw);
560556

@@ -596,8 +592,6 @@ i40e_status i40evf_shutdown_adminq(struct i40e_hw *hw)
596592
i40e_shutdown_asq(hw);
597593
i40e_shutdown_arq(hw);
598594

599-
/* destroy the locks */
600-
601595
if (hw->nvm_buff.va)
602596
i40e_free_virt_mem(hw, &hw->nvm_buff);
603597

drivers/net/ethernet/intel/i40evf/i40evf_main.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2476,6 +2476,12 @@ static int i40evf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
24762476
hw->bus.device = PCI_SLOT(pdev->devfn);
24772477
hw->bus.func = PCI_FUNC(pdev->devfn);
24782478

2479+
/* set up the locks for the AQ, do this only once in probe
2480+
* and destroy them only once in remove
2481+
*/
2482+
mutex_init(&hw->aq.asq_mutex);
2483+
mutex_init(&hw->aq.arq_mutex);
2484+
24792485
INIT_LIST_HEAD(&adapter->mac_filter_list);
24802486
INIT_LIST_HEAD(&adapter->vlan_filter_list);
24812487

@@ -2629,6 +2635,10 @@ static void i40evf_remove(struct pci_dev *pdev)
26292635
if (hw->aq.asq.count)
26302636
i40evf_shutdown_adminq(hw);
26312637

2638+
/* destroy the locks only once, here */
2639+
mutex_destroy(&hw->aq.arq_mutex);
2640+
mutex_destroy(&hw->aq.asq_mutex);
2641+
26322642
iounmap(hw->hw_addr);
26332643
pci_release_regions(pdev);
26342644

0 commit comments

Comments
 (0)