aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
authorDon Wood <donald.e.wood@intel.com>2009-03-06 18:12:09 -0500
committerRoland Dreier <rolandd@cisco.com>2009-03-06 18:12:09 -0500
commitdae5d13a7e6efcf6e0e00c0febb530b894fa13a3 (patch)
tree30a99560bc31bf1f8dcad716024ac503b844c625 /drivers/infiniband/hw
parentf3b8436ad9a8ad36b3c9fa1fe030c7f38e5d3d0b (diff)
RDMA/nes: Account for freed PBL after HW operation
Fix occurrences where the software PBL counts were changed before the hardware was updated. This bug allowed another thread to overallocate the hardware resources. Add proper PBL accounting in case nes_reg_mr() fails. Signed-off-by: Don Wood <donald.e.wood@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c70
1 files changed, 42 insertions, 28 deletions
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 4fdb72454f9..e66681349c9 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -551,6 +551,7 @@ static int nes_dealloc_fmr(struct ib_fmr *ibfmr)
551 struct nes_device *nesdev = nesvnic->nesdev; 551 struct nes_device *nesdev = nesvnic->nesdev;
552 struct nes_adapter *nesadapter = nesdev->nesadapter; 552 struct nes_adapter *nesadapter = nesdev->nesadapter;
553 int i = 0; 553 int i = 0;
554 int rc;
554 555
555 /* free the resources */ 556 /* free the resources */
556 if (nesfmr->leaf_pbl_cnt == 0) { 557 if (nesfmr->leaf_pbl_cnt == 0) {
@@ -572,7 +573,9 @@ static int nes_dealloc_fmr(struct ib_fmr *ibfmr)
572 nesmr->ibmw.rkey = ibfmr->rkey; 573 nesmr->ibmw.rkey = ibfmr->rkey;
573 nesmr->ibmw.uobject = NULL; 574 nesmr->ibmw.uobject = NULL;
574 575
575 if (nesfmr->nesmr.pbls_used != 0) { 576 rc = nes_dealloc_mw(&nesmr->ibmw);
577
578 if ((rc == 0) && (nesfmr->nesmr.pbls_used != 0)) {
576 spin_lock_irqsave(&nesadapter->pbl_lock, flags); 579 spin_lock_irqsave(&nesadapter->pbl_lock, flags);
577 if (nesfmr->nesmr.pbl_4k) { 580 if (nesfmr->nesmr.pbl_4k) {
578 nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used; 581 nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used;
@@ -584,7 +587,7 @@ static int nes_dealloc_fmr(struct ib_fmr *ibfmr)
584 spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 587 spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
585 } 588 }
586 589
587 return nes_dealloc_mw(&nesmr->ibmw); 590 return rc;
588} 591}
589 592
590 593
@@ -1993,7 +1996,16 @@ static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd,
1993 stag, ret, cqp_request->major_code, cqp_request->minor_code); 1996 stag, ret, cqp_request->major_code, cqp_request->minor_code);
1994 major_code = cqp_request->major_code; 1997 major_code = cqp_request->major_code;
1995 nes_put_cqp_request(nesdev, cqp_request); 1998 nes_put_cqp_request(nesdev, cqp_request);
1996 1999 if ((!ret || major_code) && pbl_count != 0) {
2000 spin_lock_irqsave(&nesadapter->pbl_lock, flags);
2001 if (pbl_count > 1)
2002 nesadapter->free_4kpbl += pbl_count+1;
2003 else if (residual_page_count > 32)
2004 nesadapter->free_4kpbl += pbl_count;
2005 else
2006 nesadapter->free_256pbl += pbl_count;
2007 spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
2008 }
1997 if (!ret) 2009 if (!ret)
1998 return -ETIME; 2010 return -ETIME;
1999 else if (major_code) 2011 else if (major_code)
@@ -2607,24 +2619,6 @@ static int nes_dereg_mr(struct ib_mr *ib_mr)
2607 cqp_request->waiting = 1; 2619 cqp_request->waiting = 1;
2608 cqp_wqe = &cqp_request->cqp_wqe; 2620 cqp_wqe = &cqp_request->cqp_wqe;
2609 2621
2610 spin_lock_irqsave(&nesadapter->pbl_lock, flags);
2611 if (nesmr->pbls_used != 0) {
2612 if (nesmr->pbl_4k) {
2613 nesadapter->free_4kpbl += nesmr->pbls_used;
2614 if (nesadapter->free_4kpbl > nesadapter->max_4kpbl) {
2615 printk(KERN_ERR PFX "free 4KB PBLs(%u) has exceeded the max(%u)\n",
2616 nesadapter->free_4kpbl, nesadapter->max_4kpbl);
2617 }
2618 } else {
2619 nesadapter->free_256pbl += nesmr->pbls_used;
2620 if (nesadapter->free_256pbl > nesadapter->max_256pbl) {
2621 printk(KERN_ERR PFX "free 256B PBLs(%u) has exceeded the max(%u)\n",
2622 nesadapter->free_256pbl, nesadapter->max_256pbl);
2623 }
2624 }
2625 }
2626
2627 spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
2628 nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 2622 nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
2629 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, 2623 set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
2630 NES_CQP_DEALLOCATE_STAG | NES_CQP_STAG_VA_TO | 2624 NES_CQP_DEALLOCATE_STAG | NES_CQP_STAG_VA_TO |
@@ -2642,11 +2636,6 @@ static int nes_dereg_mr(struct ib_mr *ib_mr)
2642 " CQP Major:Minor codes = 0x%04X:0x%04X\n", 2636 " CQP Major:Minor codes = 0x%04X:0x%04X\n",
2643 ib_mr->rkey, ret, cqp_request->major_code, cqp_request->minor_code); 2637 ib_mr->rkey, ret, cqp_request->major_code, cqp_request->minor_code);
2644 2638
2645 nes_free_resource(nesadapter, nesadapter->allocated_mrs,
2646 (ib_mr->rkey & 0x0fffff00) >> 8);
2647
2648 kfree(nesmr);
2649
2650 major_code = cqp_request->major_code; 2639 major_code = cqp_request->major_code;
2651 minor_code = cqp_request->minor_code; 2640 minor_code = cqp_request->minor_code;
2652 2641
@@ -2662,8 +2651,33 @@ static int nes_dereg_mr(struct ib_mr *ib_mr)
2662 " to destroy STag, ib_mr=%p, rkey = 0x%08X\n", 2651 " to destroy STag, ib_mr=%p, rkey = 0x%08X\n",
2663 major_code, minor_code, ib_mr, ib_mr->rkey); 2652 major_code, minor_code, ib_mr, ib_mr->rkey);
2664 return -EIO; 2653 return -EIO;
2665 } else 2654 }
2666 return 0; 2655
2656 if (nesmr->pbls_used != 0) {
2657 spin_lock_irqsave(&nesadapter->pbl_lock, flags);
2658 if (nesmr->pbl_4k) {
2659 nesadapter->free_4kpbl += nesmr->pbls_used;
2660 if (nesadapter->free_4kpbl > nesadapter->max_4kpbl)
2661 printk(KERN_ERR PFX "free 4KB PBLs(%u) has "
2662 "exceeded the max(%u)\n",
2663 nesadapter->free_4kpbl,
2664 nesadapter->max_4kpbl);
2665 } else {
2666 nesadapter->free_256pbl += nesmr->pbls_used;
2667 if (nesadapter->free_256pbl > nesadapter->max_256pbl)
2668 printk(KERN_ERR PFX "free 256B PBLs(%u) has "
2669 "exceeded the max(%u)\n",
2670 nesadapter->free_256pbl,
2671 nesadapter->max_256pbl);
2672 }
2673 spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
2674 }
2675 nes_free_resource(nesadapter, nesadapter->allocated_mrs,
2676 (ib_mr->rkey & 0x0fffff00) >> 8);
2677
2678 kfree(nesmr);
2679
2680 return 0;
2667} 2681}
2668 2682
2669 2683