aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffrey Huang <huangjw@broadcom.com>2015-11-05 16:25:51 -0500
committerDavid S. Miller <davem@davemloft.net>2015-11-05 16:33:09 -0500
commit4bb6cdce386d620d10d2588ea5bf4093a3b21ab9 (patch)
treeee700f7eb3c31f92b3bcfd292e56c1891ea06982
parent84e86b98f6515aaeaac053b234be158b25457184 (diff)
bnxt_en: More robust SRIOV cleanup sequence.
Instead of always calling pci_sriov_disable() in remove_one(), the driver should detect whether VFs are currently assigned to the VMs. If the VFs are active in VMs, then it should not disable SRIOV as it is catastrophic to the VMs. Instead, it just leaves the VFs alone and continues to unload the PF. The user can then cleanup the VMs even after the PF driver has been unloaded. Signed-off-by: Jeffrey Huang <huangjw@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
index 60989e7e266a..f4cf68861069 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
@@ -258,7 +258,7 @@ static int bnxt_set_vf_attr(struct bnxt *bp, int num_vfs)
258 return 0; 258 return 0;
259} 259}
260 260
261static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp) 261static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp, int num_vfs)
262{ 262{
263 int i, rc = 0; 263 int i, rc = 0;
264 struct bnxt_pf_info *pf = &bp->pf; 264 struct bnxt_pf_info *pf = &bp->pf;
@@ -267,7 +267,7 @@ static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp)
267 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_RESC_FREE, -1, -1); 267 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_RESC_FREE, -1, -1);
268 268
269 mutex_lock(&bp->hwrm_cmd_lock); 269 mutex_lock(&bp->hwrm_cmd_lock);
270 for (i = pf->first_vf_id; i < pf->first_vf_id + pf->active_vfs; i++) { 270 for (i = pf->first_vf_id; i < pf->first_vf_id + num_vfs; i++) {
271 req.vf_id = cpu_to_le16(i); 271 req.vf_id = cpu_to_le16(i);
272 rc = _hwrm_send_message(bp, &req, sizeof(req), 272 rc = _hwrm_send_message(bp, &req, sizeof(req),
273 HWRM_CMD_TIMEOUT); 273 HWRM_CMD_TIMEOUT);
@@ -509,7 +509,7 @@ static int bnxt_sriov_enable(struct bnxt *bp, int *num_vfs)
509 509
510err_out2: 510err_out2:
511 /* Free the resources reserved for various VF's */ 511 /* Free the resources reserved for various VF's */
512 bnxt_hwrm_func_vf_resource_free(bp); 512 bnxt_hwrm_func_vf_resource_free(bp, *num_vfs);
513 513
514err_out1: 514err_out1:
515 bnxt_free_vf_resources(bp); 515 bnxt_free_vf_resources(bp);
@@ -519,13 +519,19 @@ err_out1:
519 519
520void bnxt_sriov_disable(struct bnxt *bp) 520void bnxt_sriov_disable(struct bnxt *bp)
521{ 521{
522 if (!bp->pf.active_vfs) 522 u16 num_vfs = pci_num_vf(bp->pdev);
523 return;
524 523
525 pci_disable_sriov(bp->pdev); 524 if (!num_vfs)
525 return;
526 526
527 /* Free the resources reserved for various VF's */ 527 if (pci_vfs_assigned(bp->pdev)) {
528 bnxt_hwrm_func_vf_resource_free(bp); 528 netdev_warn(bp->dev, "Unable to free %d VFs because some are assigned to VMs.\n",
529 num_vfs);
530 } else {
531 pci_disable_sriov(bp->pdev);
532 /* Free the HW resources reserved for various VF's */
533 bnxt_hwrm_func_vf_resource_free(bp, num_vfs);
534 }
529 535
530 bnxt_free_vf_resources(bp); 536 bnxt_free_vf_resources(bp);
531 537
@@ -552,17 +558,25 @@ int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs)
552 } 558 }
553 bp->sriov_cfg = true; 559 bp->sriov_cfg = true;
554 rtnl_unlock(); 560 rtnl_unlock();
555 if (!num_vfs) { 561
556 bnxt_sriov_disable(bp); 562 if (pci_vfs_assigned(bp->pdev)) {
557 return 0; 563 netdev_warn(dev, "Unable to configure SRIOV since some VFs are assigned to VMs.\n");
564 num_vfs = 0;
565 goto sriov_cfg_exit;
558 } 566 }
559 567
560 /* Check if enabled VFs is same as requested */ 568 /* Check if enabled VFs is same as requested */
561 if (num_vfs == bp->pf.active_vfs) 569 if (num_vfs && num_vfs == bp->pf.active_vfs)
562 return 0; 570 goto sriov_cfg_exit;
571
572 /* if there are previous existing VFs, clean them up */
573 bnxt_sriov_disable(bp);
574 if (!num_vfs)
575 goto sriov_cfg_exit;
563 576
564 bnxt_sriov_enable(bp, &num_vfs); 577 bnxt_sriov_enable(bp, &num_vfs);
565 578
579sriov_cfg_exit:
566 bp->sriov_cfg = false; 580 bp->sriov_cfg = false;
567 wake_up(&bp->sriov_cfg_wait); 581 wake_up(&bp->sriov_cfg_wait);
568 582