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>
This commit is contained in:
parent
fd000e12a5
commit
d2fa9b26e1
|
@ -52,6 +52,7 @@
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/threads.h>
|
#include <linux/threads.h>
|
||||||
|
#include <linux/highmem.h>
|
||||||
#include <net/arp.h>
|
#include <net/arp.h>
|
||||||
#include <net/neighbour.h>
|
#include <net/neighbour.h>
|
||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
|
@ -2836,6 +2837,10 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
|
||||||
cpu_to_le32(conn_param->private_data_len +
|
cpu_to_le32(conn_param->private_data_len +
|
||||||
sizeof(struct ietf_mpa_frame));
|
sizeof(struct ietf_mpa_frame));
|
||||||
wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = ibmr->lkey;
|
wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = ibmr->lkey;
|
||||||
|
if (nesqp->sq_kmapped) {
|
||||||
|
nesqp->sq_kmapped = 0;
|
||||||
|
kunmap(nesqp->page);
|
||||||
|
}
|
||||||
|
|
||||||
nesqp->nesqp_context->ird_ord_sizes |=
|
nesqp->nesqp_context->ird_ord_sizes |=
|
||||||
cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
|
cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
|
||||||
|
@ -3304,6 +3309,11 @@ static void cm_event_connected(struct nes_cm_event *event)
|
||||||
wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0;
|
wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0;
|
||||||
wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0;
|
wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0;
|
||||||
|
|
||||||
|
if (nesqp->sq_kmapped) {
|
||||||
|
nesqp->sq_kmapped = 0;
|
||||||
|
kunmap(nesqp->page);
|
||||||
|
}
|
||||||
|
|
||||||
/* use the reserved spot on the WQ for the extra first WQE */
|
/* use the reserved spot on the WQ for the extra first WQE */
|
||||||
nesqp->nesqp_context->ird_ord_sizes &=
|
nesqp->nesqp_context->ird_ord_sizes &=
|
||||||
cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
|
cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
|
||||||
|
|
|
@ -1015,6 +1015,7 @@ static int nes_setup_virt_qp(struct nes_qp *nesqp, struct nes_pbl *nespbl,
|
||||||
kunmap(nesqp->page);
|
kunmap(nesqp->page);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
nesqp->sq_kmapped = 1;
|
||||||
nesqp->hwqp.q2_vbase = mem;
|
nesqp->hwqp.q2_vbase = mem;
|
||||||
mem += 256;
|
mem += 256;
|
||||||
memset(nesqp->hwqp.q2_vbase, 0, 256);
|
memset(nesqp->hwqp.q2_vbase, 0, 256);
|
||||||
|
@ -1092,8 +1093,11 @@ static inline void nes_free_qp_mem(struct nes_device *nesdev,
|
||||||
pci_free_consistent(nesdev->pcidev, nesqp->qp_mem_size, nesqp->hwqp.q2_vbase, nesqp->hwqp.q2_pbase);
|
pci_free_consistent(nesdev->pcidev, nesqp->qp_mem_size, nesqp->hwqp.q2_vbase, nesqp->hwqp.q2_pbase);
|
||||||
pci_free_consistent(nesdev->pcidev, 256, nesqp->pbl_vbase, nesqp->pbl_pbase );
|
pci_free_consistent(nesdev->pcidev, 256, nesqp->pbl_vbase, nesqp->pbl_pbase );
|
||||||
nesqp->pbl_vbase = NULL;
|
nesqp->pbl_vbase = NULL;
|
||||||
|
if (nesqp->sq_kmapped) {
|
||||||
|
nesqp->sq_kmapped = 0;
|
||||||
kunmap(nesqp->page);
|
kunmap(nesqp->page);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1501,8 +1505,10 @@ static int nes_destroy_qp(struct ib_qp *ibqp)
|
||||||
nes_ucontext->first_free_wq = nesqp->mmap_sq_db_index;
|
nes_ucontext->first_free_wq = nesqp->mmap_sq_db_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nesqp->pbl_pbase)
|
if (nesqp->pbl_pbase && nesqp->sq_kmapped) {
|
||||||
|
nesqp->sq_kmapped = 0;
|
||||||
kunmap(nesqp->page);
|
kunmap(nesqp->page);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Clean any pending completions from the cq(s) */
|
/* Clean any pending completions from the cq(s) */
|
||||||
if (nesqp->nesscq)
|
if (nesqp->nesscq)
|
||||||
|
|
|
@ -175,5 +175,6 @@ struct nes_qp {
|
||||||
u8 hw_iwarp_state;
|
u8 hw_iwarp_state;
|
||||||
u8 hw_tcp_state;
|
u8 hw_tcp_state;
|
||||||
u8 term_flags;
|
u8 term_flags;
|
||||||
|
u8 sq_kmapped;
|
||||||
};
|
};
|
||||||
#endif /* NES_VERBS_H */
|
#endif /* NES_VERBS_H */
|
||||||
|
|
Loading…
Reference in New Issue