aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFaisal Latif <faisal.latif@intel.com>2009-12-09 18:54:28 -0500
committerRoland Dreier <rolandd@cisco.com>2009-12-09 18:54:28 -0500
commitd2fa9b26e181d1e3c3df06a57fa13b04afee0e16 (patch)
treedfac5f80c0a1b0e1ef38a1a6580b7faaf5f1f348
parentfd000e12a564bdeaec5e5a438d341d9132409f26 (diff)
RDMA/nes: Free kmap() resources
We fail when creating many qps as kmap() fails for sq_vbase. Fix this by doing kunmap() as soon as we are done with sq_vbase. We do kunmap() in one of the locations below: (1) nes_destroy_qp() (2) nes_accept() (3) nes_connect_event We keep a flag to avoid multiple calls to kunmap(). Signed-off-by: Faisal Latif <faisal.latif@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c10
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c10
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.h1
3 files changed, 19 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index a25816812ced..b139806a9667 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -52,6 +52,7 @@
52#include <linux/random.h> 52#include <linux/random.h>
53#include <linux/list.h> 53#include <linux/list.h>
54#include <linux/threads.h> 54#include <linux/threads.h>
55#include <linux/highmem.h>
55#include <net/arp.h> 56#include <net/arp.h>
56#include <net/neighbour.h> 57#include <net/neighbour.h>
57#include <net/route.h> 58#include <net/route.h>
@@ -2836,6 +2837,10 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2836 cpu_to_le32(conn_param->private_data_len + 2837 cpu_to_le32(conn_param->private_data_len +
2837 sizeof(struct ietf_mpa_frame)); 2838 sizeof(struct ietf_mpa_frame));
2838 wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = ibmr->lkey; 2839 wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = ibmr->lkey;
2840 if (nesqp->sq_kmapped) {
2841 nesqp->sq_kmapped = 0;
2842 kunmap(nesqp->page);
2843 }
2839 2844
2840 nesqp->nesqp_context->ird_ord_sizes |= 2845 nesqp->nesqp_context->ird_ord_sizes |=
2841 cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | 2846 cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
@@ -3304,6 +3309,11 @@ static void cm_event_connected(struct nes_cm_event *event)
3304 wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0; 3309 wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0;
3305 wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; 3310 wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0;
3306 3311
3312 if (nesqp->sq_kmapped) {
3313 nesqp->sq_kmapped = 0;
3314 kunmap(nesqp->page);
3315 }
3316
3307 /* use the reserved spot on the WQ for the extra first WQE */ 3317 /* use the reserved spot on the WQ for the extra first WQE */
3308 nesqp->nesqp_context->ird_ord_sizes &= 3318 nesqp->nesqp_context->ird_ord_sizes &=
3309 cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | 3319 cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 53dc39f43008..64d3136e3747 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -1015,6 +1015,7 @@ static int nes_setup_virt_qp(struct nes_qp *nesqp, struct nes_pbl *nespbl,
1015 kunmap(nesqp->page); 1015 kunmap(nesqp->page);
1016 return -ENOMEM; 1016 return -ENOMEM;
1017 } 1017 }
1018 nesqp->sq_kmapped = 1;
1018 nesqp->hwqp.q2_vbase = mem; 1019 nesqp->hwqp.q2_vbase = mem;
1019 mem += 256; 1020 mem += 256;
1020 memset(nesqp->hwqp.q2_vbase, 0, 256); 1021 memset(nesqp->hwqp.q2_vbase, 0, 256);
@@ -1092,7 +1093,10 @@ static inline void nes_free_qp_mem(struct nes_device *nesdev,
1092 pci_free_consistent(nesdev->pcidev, nesqp->qp_mem_size, nesqp->hwqp.q2_vbase, nesqp->hwqp.q2_pbase); 1093 pci_free_consistent(nesdev->pcidev, nesqp->qp_mem_size, nesqp->hwqp.q2_vbase, nesqp->hwqp.q2_pbase);
1093 pci_free_consistent(nesdev->pcidev, 256, nesqp->pbl_vbase, nesqp->pbl_pbase ); 1094 pci_free_consistent(nesdev->pcidev, 256, nesqp->pbl_vbase, nesqp->pbl_pbase );
1094 nesqp->pbl_vbase = NULL; 1095 nesqp->pbl_vbase = NULL;
1095 kunmap(nesqp->page); 1096 if (nesqp->sq_kmapped) {
1097 nesqp->sq_kmapped = 0;
1098 kunmap(nesqp->page);
1099 }
1096 } 1100 }
1097} 1101}
1098 1102
@@ -1501,8 +1505,10 @@ static int nes_destroy_qp(struct ib_qp *ibqp)
1501 nes_ucontext->first_free_wq = nesqp->mmap_sq_db_index; 1505 nes_ucontext->first_free_wq = nesqp->mmap_sq_db_index;
1502 } 1506 }
1503 } 1507 }
1504 if (nesqp->pbl_pbase) 1508 if (nesqp->pbl_pbase && nesqp->sq_kmapped) {
1509 nesqp->sq_kmapped = 0;
1505 kunmap(nesqp->page); 1510 kunmap(nesqp->page);
1511 }
1506 } else { 1512 } else {
1507 /* Clean any pending completions from the cq(s) */ 1513 /* Clean any pending completions from the cq(s) */
1508 if (nesqp->nesscq) 1514 if (nesqp->nesscq)
diff --git a/drivers/infiniband/hw/nes/nes_verbs.h b/drivers/infiniband/hw/nes/nes_verbs.h
index cc7a60481e50..2df9993e0cac 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.h
+++ b/drivers/infiniband/hw/nes/nes_verbs.h
@@ -175,5 +175,6 @@ struct nes_qp {
175 u8 hw_iwarp_state; 175 u8 hw_iwarp_state;
176 u8 hw_tcp_state; 176 u8 hw_tcp_state;
177 u8 term_flags; 177 u8 term_flags;
178 u8 sq_kmapped;
178}; 179};
179#endif /* NES_VERBS_H */ 180#endif /* NES_VERBS_H */