Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2fa9b26 authored by Faisal Latif's avatar Faisal Latif Committed by Roland Dreier
Browse files

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: default avatarFaisal Latif <faisal.latif@intel.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent fd000e12
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@
#include <linux/random.h>
#include <linux/list.h>
#include <linux/threads.h>
#include <linux/highmem.h>
#include <net/arp.h>
#include <net/neighbour.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 +
			sizeof(struct ietf_mpa_frame));
		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 |=
			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_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 */
		nesqp->nesqp_context->ird_ord_sizes &=
			cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
+8 −2
Original line number Diff line number Diff line
@@ -1015,6 +1015,7 @@ static int nes_setup_virt_qp(struct nes_qp *nesqp, struct nes_pbl *nespbl,
		kunmap(nesqp->page);
		return -ENOMEM;
	}
	nesqp->sq_kmapped = 1;
	nesqp->hwqp.q2_vbase = mem;
	mem += 256;
	memset(nesqp->hwqp.q2_vbase, 0, 256);
@@ -1092,9 +1093,12 @@ 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, 256, nesqp->pbl_vbase, nesqp->pbl_pbase );
		nesqp->pbl_vbase = NULL;
		if (nesqp->sq_kmapped) {
			nesqp->sq_kmapped = 0;
			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;
			}
		}
		if (nesqp->pbl_pbase)
		if (nesqp->pbl_pbase && nesqp->sq_kmapped) {
			nesqp->sq_kmapped = 0;
			kunmap(nesqp->page);
		}
	} else {
		/* Clean any pending completions from the cq(s) */
		if (nesqp->nesscq)
+1 −0
Original line number Diff line number Diff line
@@ -175,5 +175,6 @@ struct nes_qp {
	u8                    hw_iwarp_state;
	u8                    hw_tcp_state;
	u8                    term_flags;
	u8                    sq_kmapped;
};
#endif			/* NES_VERBS_H */