aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMitch Williams <mitch.a.williams@intel.com>2015-01-09 06:18:15 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-02-08 23:11:44 -0500
commit3ba9bcb4b68fa63f38bca910ccd4a1bf3cb4195f (patch)
tree283c7c13f9397dfce443ef0ee97e097921db6d04 /drivers/net
parent07574897d3fefb7f6af5c4128c322a5a05491e62 (diff)
i40e: add locking around VF reset
During VF deallocation, we need to lock out the VF reset code. However, we cannot depend on simply masking the interrupt, as this does not lock out the service task, which can still call the reset routine. Instead, leave the interrupt enabled, but add locking around the VF disable and reset routines. For the disable code, we wait to get the lock, as the reset code will take a finite amount of time to run. For the reset code, we just return if we fail to get the lock. Since we know that the VFs are being disabled, we don't need to handle the reset. This fixes a panic when disabling SR-IOV. Change-ID: Iea0a6cdef35c331f48c6d5b2f8e6f0e86322e7d8 Signed-off-by: Mitch Williams <mitch.a.williams@intel.com> Tested-by: Jim Young <james.m.young@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e.h1
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c13
2 files changed, 8 insertions, 6 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index b35413d25860..2b65cdcad6ba 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -148,6 +148,7 @@ enum i40e_state_t {
148 __I40E_FD_FLUSH_REQUESTED, 148 __I40E_FD_FLUSH_REQUESTED,
149 __I40E_RESET_FAILED, 149 __I40E_RESET_FAILED,
150 __I40E_PORT_TX_SUSPENDED, 150 __I40E_PORT_TX_SUSPENDED,
151 __I40E_VF_DISABLE,
151}; 152};
152 153
153enum i40e_interrupt_policy { 154enum i40e_interrupt_policy {
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 4e4232a58843..40f042af4131 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -647,6 +647,9 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
647 int i; 647 int i;
648 u32 reg; 648 u32 reg;
649 649
650 if (test_and_set_bit(__I40E_VF_DISABLE, &pf->state))
651 return;
652
650 /* warn the VF */ 653 /* warn the VF */
651 clear_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states); 654 clear_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states);
652 655
@@ -706,6 +709,7 @@ complete_reset:
706 /* tell the VF the reset is done */ 709 /* tell the VF the reset is done */
707 wr32(hw, I40E_VFGEN_RSTAT1(vf->vf_id), I40E_VFR_VFACTIVE); 710 wr32(hw, I40E_VFGEN_RSTAT1(vf->vf_id), I40E_VFR_VFACTIVE);
708 i40e_flush(hw); 711 i40e_flush(hw);
712 clear_bit(__I40E_VF_DISABLE, &pf->state);
709} 713}
710 714
711/** 715/**
@@ -790,6 +794,8 @@ void i40e_free_vfs(struct i40e_pf *pf)
790 794
791 if (!pf->vf) 795 if (!pf->vf)
792 return; 796 return;
797 while (test_and_set_bit(__I40E_VF_DISABLE, &pf->state))
798 usleep_range(1000, 2000);
793 799
794 /* Disable IOV before freeing resources. This lets any VF drivers 800 /* Disable IOV before freeing resources. This lets any VF drivers
795 * running in the host get themselves cleaned up before we yank 801 * running in the host get themselves cleaned up before we yank
@@ -800,9 +806,6 @@ void i40e_free_vfs(struct i40e_pf *pf)
800 806
801 msleep(20); /* let any messages in transit get finished up */ 807 msleep(20); /* let any messages in transit get finished up */
802 808
803 /* Disable interrupt 0 so we don't try to handle the VFLR. */
804 i40e_irq_dynamic_disable_icr0(pf);
805
806 /* free up vf resources */ 809 /* free up vf resources */
807 tmp = pf->num_alloc_vfs; 810 tmp = pf->num_alloc_vfs;
808 pf->num_alloc_vfs = 0; 811 pf->num_alloc_vfs = 0;
@@ -834,9 +837,7 @@ void i40e_free_vfs(struct i40e_pf *pf)
834 dev_warn(&pf->pdev->dev, 837 dev_warn(&pf->pdev->dev,
835 "unable to disable SR-IOV because VFs are assigned.\n"); 838 "unable to disable SR-IOV because VFs are assigned.\n");
836 } 839 }
837 840 clear_bit(__I40E_VF_DISABLE, &pf->state);
838 /* Re-enable interrupt 0. */
839 i40e_irq_dynamic_enable_icr0(pf);
840} 841}
841 842
842#ifdef CONFIG_PCI_IOV 843#ifdef CONFIG_PCI_IOV