linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Remove use of kmap()
@ 2021-06-22  6:14 ira.weiny
  2021-06-22  6:14 ` [PATCH 1/4] RDMA/hfi1: " ira.weiny
                   ` (4 more replies)
  0 siblings, 5 replies; 22+ messages in thread
From: ira.weiny @ 2021-06-22  6:14 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Ira Weiny, Mike Marciniszyn, Dennis Dalessandro, Doug Ledford,
	Faisal Latif, Shiraz Saleem, Bernard Metzler, Kamal Heib,
	linux-rdma, linux-kernel

From: Ira Weiny <ira.weiny@intel.com>

kmap() is being deprecated and will break uses of device dax after PKS
protection is introduced.[1]

These kmap() usages don't need to be global and work fine as thread local
mappings.

Replace these kmap() calls with kmap_local_page() which is more appropriate.

The only final use of kmap() in the RDMA subsystem is in the qib driver which
is pretty old at this point.  The use is pretty convoluted and I doubt systems
using that driver are using persistent memory.  So it is left as is.  If this
is a problem I can dig into converting it as well.

[1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/

Ira Weiny (4):
  RDMA/hfi1: Remove use of kmap()
  RDMA/i40iw: Remove use of kmap()
  RDMA/siw: Remove kmap()
  RDMA/siw: Convert siw_tx_hdt() to kmap_local_page()

 drivers/infiniband/hw/hfi1/sdma.c      |  4 +--
 drivers/infiniband/hw/i40iw/i40iw_cm.c | 10 +++---
 drivers/infiniband/sw/siw/siw_qp_tx.c  | 47 +++++++++++++++-----------
 3 files changed, 34 insertions(+), 27 deletions(-)

-- 
2.28.0.rc0.12.gb6a658bd00c9


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 1/4] RDMA/hfi1: Remove use of kmap()
  2021-06-22  6:14 [PATCH 0/4] Remove use of kmap() ira.weiny
@ 2021-06-22  6:14 ` ira.weiny
  2021-06-24 18:13   ` Jason Gunthorpe
  2021-06-22  6:14 ` [PATCH 2/4] RDMA/i40iw: " ira.weiny
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 22+ messages in thread
From: ira.weiny @ 2021-06-22  6:14 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Ira Weiny, Mike Marciniszyn, Dennis Dalessandro, Doug Ledford,
	Faisal Latif, Shiraz Saleem, Bernard Metzler, Kamal Heib,
	linux-rdma, linux-kernel

From: Ira Weiny <ira.weiny@intel.com>

kmap() is being deprecated and will break uses of device dax after PKS
protection is introduced.[1]

The kmap() used in sdma does not need to be global.  Use the new
kmap_local_page() which works with PKS and may provide better
performance for this thread local mapping anyway.

[1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/

Signed-off-by: Ira Weiny <ira.weiny@intel.com>
---
 drivers/infiniband/hw/hfi1/sdma.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c
index 46b5290b2839..af43dcbb0928 100644
--- a/drivers/infiniband/hw/hfi1/sdma.c
+++ b/drivers/infiniband/hw/hfi1/sdma.c
@@ -3130,7 +3130,7 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
 		}
 
 		if (type == SDMA_MAP_PAGE) {
-			kvaddr = kmap(page);
+			kvaddr = kmap_local_page(page);
 			kvaddr += offset;
 		} else if (WARN_ON(!kvaddr)) {
 			__sdma_txclean(dd, tx);
@@ -3140,7 +3140,7 @@ int ext_coal_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx,
 		memcpy(tx->coalesce_buf + tx->coalesce_idx, kvaddr, len);
 		tx->coalesce_idx += len;
 		if (type == SDMA_MAP_PAGE)
-			kunmap(page);
+			kunmap_local(kvaddr);
 
 		/* If there is more data, return */
 		if (tx->tlen - tx->coalesce_idx)
-- 
2.28.0.rc0.12.gb6a658bd00c9


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 2/4] RDMA/i40iw: Remove use of kmap()
  2021-06-22  6:14 [PATCH 0/4] Remove use of kmap() ira.weiny
  2021-06-22  6:14 ` [PATCH 1/4] RDMA/hfi1: " ira.weiny
@ 2021-06-22  6:14 ` ira.weiny
  2021-06-22 12:14   ` Jason Gunthorpe
  2021-06-22 16:56   ` [PATCH V2] RDMA/irdma: " ira.weiny
  2021-06-22  6:14 ` [PATCH 3/4] RDMA/siw: Remove kmap() ira.weiny
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 22+ messages in thread
From: ira.weiny @ 2021-06-22  6:14 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Ira Weiny, Mike Marciniszyn, Dennis Dalessandro, Doug Ledford,
	Faisal Latif, Shiraz Saleem, Bernard Metzler, Kamal Heib,
	linux-rdma, linux-kernel

From: Ira Weiny <ira.weiny@intel.com>

kmap() is being deprecated and will break uses of device dax after PKS
protection is introduced.[1]

The kmap() used in the i40iw CM driver is thread local.  Therefore
kmap_local_page() sufficient to use and may provide performance benefits
as well.  kmap_local_page() will work with device dax and pgmap
protected pages.

Use kmap_local_page() instead of kmap().

[1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/

Signed-off-by: Ira Weiny <ira.weiny@intel.com>
---
 drivers/infiniband/hw/i40iw/i40iw_cm.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c
index ac65c8237b2e..13e40ebd5322 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_cm.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c
@@ -3725,7 +3725,7 @@ int i40iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 		ibmr->device = iwpd->ibpd.device;
 		iwqp->lsmm_mr = ibmr;
 		if (iwqp->page)
-			iwqp->sc_qp.qp_uk.sq_base = kmap(iwqp->page);
+			iwqp->sc_qp.qp_uk.sq_base = kmap_local_page(iwqp->page);
 		dev->iw_priv_qp_ops->qp_send_lsmm(&iwqp->sc_qp,
 							iwqp->ietf_mem.va,
 							(accept.size + conn_param->private_data_len),
@@ -3733,12 +3733,12 @@ int i40iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 
 	} else {
 		if (iwqp->page)
-			iwqp->sc_qp.qp_uk.sq_base = kmap(iwqp->page);
+			iwqp->sc_qp.qp_uk.sq_base = kmap_local_page(iwqp->page);
 		dev->iw_priv_qp_ops->qp_send_lsmm(&iwqp->sc_qp, NULL, 0, 0);
 	}
 
 	if (iwqp->page)
-		kunmap(iwqp->page);
+		kunmap_local(iwqp->sc_qp.qp_uk.sq_base);
 
 	iwqp->cm_id = cm_id;
 	cm_node->cm_id = cm_id;
@@ -4106,10 +4106,10 @@ static void i40iw_cm_event_connected(struct i40iw_cm_event *event)
 	i40iw_cm_init_tsa_conn(iwqp, cm_node);
 	read0 = (cm_node->send_rdma0_op == SEND_RDMA_READ_ZERO);
 	if (iwqp->page)
-		iwqp->sc_qp.qp_uk.sq_base = kmap(iwqp->page);
+		iwqp->sc_qp.qp_uk.sq_base = kmap_local_page(iwqp->page);
 	dev->iw_priv_qp_ops->qp_send_rtt(&iwqp->sc_qp, read0);
 	if (iwqp->page)
-		kunmap(iwqp->page);
+		kunmap_local(iwqp->sc_qp.qp_uk.sq_base);
 
 	memset(&attr, 0, sizeof(attr));
 	attr.qp_state = IB_QPS_RTS;
-- 
2.28.0.rc0.12.gb6a658bd00c9


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 3/4] RDMA/siw: Remove kmap()
  2021-06-22  6:14 [PATCH 0/4] Remove use of kmap() ira.weiny
  2021-06-22  6:14 ` [PATCH 1/4] RDMA/hfi1: " ira.weiny
  2021-06-22  6:14 ` [PATCH 2/4] RDMA/i40iw: " ira.weiny
@ 2021-06-22  6:14 ` ira.weiny
  2021-07-15 18:00   ` Jason Gunthorpe
  2021-06-22  6:14 ` [PATCH 4/4] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page() ira.weiny
  2021-06-22 16:42 ` [PATCH 4/4] " Bernard Metzler
  4 siblings, 1 reply; 22+ messages in thread
From: ira.weiny @ 2021-06-22  6:14 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Ira Weiny, Mike Marciniszyn, Dennis Dalessandro, Doug Ledford,
	Faisal Latif, Shiraz Saleem, Bernard Metzler, Kamal Heib,
	linux-rdma, linux-kernel

From: Ira Weiny <ira.weiny@intel.com>

kmap() is being deprecated and will break uses of device dax after PKS
protection is introduced.[1]

These uses of kmap() in the SIW driver are thread local.  Therefore
kmap_local_page() is sufficient to use and will work with pgmap
protected pages when those are implemnted.

There is one more use of kmap() in this driver which is split into its
own patch because kmap_local_page() has strict ordering rules and the
use of the kmap_mask over multiple segments must be handled carefully.
Therefore, that conversion is handled in a stand alone patch.

Use kmap_local_page() instead of kmap() in the 'easy' cases.

[1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/

Signed-off-by: Ira Weiny <ira.weiny@intel.com>
---
 drivers/infiniband/sw/siw/siw_qp_tx.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c
index 7989c4043db4..db68a10d12cd 100644
--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
+++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
@@ -76,7 +76,7 @@ static int siw_try_1seg(struct siw_iwarp_tx *c_tx, void *paddr)
 			if (unlikely(!p))
 				return -EFAULT;
 
-			buffer = kmap(p);
+			buffer = kmap_local_page(p);
 
 			if (likely(PAGE_SIZE - off >= bytes)) {
 				memcpy(paddr, buffer + off, bytes);
@@ -84,7 +84,7 @@ static int siw_try_1seg(struct siw_iwarp_tx *c_tx, void *paddr)
 				unsigned long part = bytes - (PAGE_SIZE - off);
 
 				memcpy(paddr, buffer + off, part);
-				kunmap(p);
+				kunmap_local(buffer);
 
 				if (!mem->is_pbl)
 					p = siw_get_upage(mem->umem,
@@ -96,10 +96,10 @@ static int siw_try_1seg(struct siw_iwarp_tx *c_tx, void *paddr)
 				if (unlikely(!p))
 					return -EFAULT;
 
-				buffer = kmap(p);
+				buffer = kmap_local_page(p);
 				memcpy(paddr + part, buffer, bytes - part);
 			}
-			kunmap(p);
+			kunmap_local(buffer);
 		}
 	}
 	return (int)bytes;
@@ -485,6 +485,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 
 		while (sge_len) {
 			size_t plen = min((int)PAGE_SIZE - fp_off, sge_len);
+			void *kaddr;
 
 			if (!is_kva) {
 				struct page *p;
@@ -517,10 +518,11 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 							iov[seg].iov_base,
 							plen);
 				} else if (do_crc) {
+					kaddr = kmap_local_page(p);
 					crypto_shash_update(c_tx->mpa_crc_hd,
-							    kmap(p) + fp_off,
+							    kaddr + fp_off,
 							    plen);
-					kunmap(p);
+					kunmap_local(kaddr);
 				}
 			} else {
 				u64 va = sge->laddr + sge_off;
-- 
2.28.0.rc0.12.gb6a658bd00c9


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 4/4] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page()
  2021-06-22  6:14 [PATCH 0/4] Remove use of kmap() ira.weiny
                   ` (2 preceding siblings ...)
  2021-06-22  6:14 ` [PATCH 3/4] RDMA/siw: Remove kmap() ira.weiny
@ 2021-06-22  6:14 ` ira.weiny
  2021-06-22 20:34   ` [PATCH V2] " ira.weiny
  2021-06-23 14:36   ` [PATCH V2] " Bernard Metzler
  2021-06-22 16:42 ` [PATCH 4/4] " Bernard Metzler
  4 siblings, 2 replies; 22+ messages in thread
From: ira.weiny @ 2021-06-22  6:14 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Ira Weiny, Mike Marciniszyn, Dennis Dalessandro, Doug Ledford,
	Faisal Latif, Shiraz Saleem, Bernard Metzler, Kamal Heib,
	linux-rdma, linux-kernel

From: Ira Weiny <ira.weiny@intel.com>

kmap() is being deprecated and will break uses of device dax after PKS
protection is introduced.[1]

The use of kmap() in siw_tx_hdt() is all thread local therefore
kmap_local_page() is a sufficient replacement and will work with pgmap
protected pages when those are implemented.

kmap_local_page() mappings are tracked in a stack and must be unmapped
in the opposite order they were mapped in.

siw_tx_hdt() tracks pages used in a page_array.  It uses that array to
unmap pages which were mapped on function exit.  Not all entries in the
array are mapped and this is tracked in kmap_mask.

kunmap_local() takes a mapped address rather than a page.  Declare a
mapped address array, page_array_addr, of the same size as the page
array to be used for unmapping.

Use kmap_local_page() instead of kmap() to map pages in the page_array.

Because segments are mapped into the page array in increasing index
order, modify siw_unmap_pages() to unmap pages in decreasing order.

The kmap_mask is no longer needed as the lack of an address in the
address array can indicate no unmap is required.

[1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/

Signed-off-by: Ira Weiny <ira.weiny@intel.com>
---
 drivers/infiniband/sw/siw/siw_qp_tx.c | 35 +++++++++++++++------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c
index db68a10d12cd..e70aba23f6e7 100644
--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
+++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
@@ -396,13 +396,17 @@ static int siw_0copy_tx(struct socket *s, struct page **page,
 
 #define MAX_TRAILER (MPA_CRC_SIZE + 4)
 
-static void siw_unmap_pages(struct page **pp, unsigned long kmap_mask)
+static void siw_unmap_pages(void **addrs, int len)
 {
-	while (kmap_mask) {
-		if (kmap_mask & BIT(0))
-			kunmap(*pp);
-		pp++;
-		kmap_mask >>= 1;
+	int i;
+
+	/*
+	 * Work backwards through the array to honor the kmap_local_page()
+	 * ordering requirements.
+	 */
+	for (i = (len-1); i >= 0; i--) {
+		if (addrs[i])
+			kunmap_local(addrs[i]);
 	}
 }
 
@@ -427,13 +431,15 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 	struct siw_sge *sge = &wqe->sqe.sge[c_tx->sge_idx];
 	struct kvec iov[MAX_ARRAY];
 	struct page *page_array[MAX_ARRAY];
+	void *page_array_addr[MAX_ARRAY];
 	struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_EOR };
 
 	int seg = 0, do_crc = c_tx->do_crc, is_kva = 0, rv;
 	unsigned int data_len = c_tx->bytes_unsent, hdr_len = 0, trl_len = 0,
 		     sge_off = c_tx->sge_off, sge_idx = c_tx->sge_idx,
 		     pbl_idx = c_tx->pbl_idx;
-	unsigned long kmap_mask = 0L;
+
+	memset(page_array_addr, 0, sizeof(page_array_addr));
 
 	if (c_tx->state == SIW_SEND_HDR) {
 		if (c_tx->use_sendpage) {
@@ -498,7 +504,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 					p = siw_get_upage(mem->umem,
 							  sge->laddr + sge_off);
 				if (unlikely(!p)) {
-					siw_unmap_pages(page_array, kmap_mask);
+					siw_unmap_pages(page_array_addr, MAX_ARRAY);
 					wqe->processed -= c_tx->bytes_unsent;
 					rv = -EFAULT;
 					goto done_crc;
@@ -506,11 +512,10 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 				page_array[seg] = p;
 
 				if (!c_tx->use_sendpage) {
-					iov[seg].iov_base = kmap(p) + fp_off;
-					iov[seg].iov_len = plen;
+					page_array_addr[seg] = kmap_local_page(page_array[seg]);
 
-					/* Remember for later kunmap() */
-					kmap_mask |= BIT(seg);
+					iov[seg].iov_base = page_array_addr[seg] + fp_off;
+					iov[seg].iov_len = plen;
 
 					if (do_crc)
 						crypto_shash_update(
@@ -518,7 +523,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 							iov[seg].iov_base,
 							plen);
 				} else if (do_crc) {
-					kaddr = kmap_local_page(p);
+					kaddr = kmap_local_page(page_array[seg]);
 					crypto_shash_update(c_tx->mpa_crc_hd,
 							    kaddr + fp_off,
 							    plen);
@@ -542,7 +547,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 
 			if (++seg > (int)MAX_ARRAY) {
 				siw_dbg_qp(tx_qp(c_tx), "to many fragments\n");
-				siw_unmap_pages(page_array, kmap_mask);
+				siw_unmap_pages(page_array_addr, MAX_ARRAY);
 				wqe->processed -= c_tx->bytes_unsent;
 				rv = -EMSGSIZE;
 				goto done_crc;
@@ -593,7 +598,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 	} else {
 		rv = kernel_sendmsg(s, &msg, iov, seg + 1,
 				    hdr_len + data_len + trl_len);
-		siw_unmap_pages(page_array, kmap_mask);
+		siw_unmap_pages(page_array_addr, MAX_ARRAY);
 	}
 	if (rv < (int)hdr_len) {
 		/* Not even complete hdr pushed or negative rv */
-- 
2.28.0.rc0.12.gb6a658bd00c9


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/4] RDMA/i40iw: Remove use of kmap()
  2021-06-22  6:14 ` [PATCH 2/4] RDMA/i40iw: " ira.weiny
@ 2021-06-22 12:14   ` Jason Gunthorpe
  2021-06-22 16:56   ` [PATCH V2] RDMA/irdma: " ira.weiny
  1 sibling, 0 replies; 22+ messages in thread
From: Jason Gunthorpe @ 2021-06-22 12:14 UTC (permalink / raw)
  To: ira.weiny
  Cc: Mike Marciniszyn, Dennis Dalessandro, Doug Ledford, Faisal Latif,
	Shiraz Saleem, Bernard Metzler, Kamal Heib, linux-rdma,
	linux-kernel

On Mon, Jun 21, 2021 at 11:14:20PM -0700, ira.weiny@intel.com wrote:
> From: Ira Weiny <ira.weiny@intel.com>
> 
> kmap() is being deprecated and will break uses of device dax after PKS
> protection is introduced.[1]
> 
> The kmap() used in the i40iw CM driver is thread local.  Therefore
> kmap_local_page() sufficient to use and may provide performance benefits
> as well.  kmap_local_page() will work with device dax and pgmap
> protected pages.
> 
> Use kmap_local_page() instead of kmap().
> 
> [1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/
> 
> Signed-off-by: Ira Weiny <ira.weiny@intel.com>
> ---
>  drivers/infiniband/hw/i40iw/i40iw_cm.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)

This needs to be resent against irdma instead

Jason

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 4/4] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page()
  2021-06-22  6:14 [PATCH 0/4] Remove use of kmap() ira.weiny
                   ` (3 preceding siblings ...)
  2021-06-22  6:14 ` [PATCH 4/4] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page() ira.weiny
@ 2021-06-22 16:42 ` Bernard Metzler
  2021-06-22 20:39   ` Ira Weiny
  4 siblings, 1 reply; 22+ messages in thread
From: Bernard Metzler @ 2021-06-22 16:42 UTC (permalink / raw)
  To: ira.weiny
  Cc: Jason Gunthorpe, Mike Marciniszyn, Dennis Dalessandro,
	Doug Ledford, Faisal Latif, Shiraz Saleem, Kamal Heib,
	linux-rdma, linux-kernel

-----ira.weiny@intel.com wrote: -----

>To: "Jason Gunthorpe" <jgg@ziepe.ca>
>From: ira.weiny@intel.com
>Date: 06/22/2021 08:14AM
>Cc: "Ira Weiny" <ira.weiny@intel.com>, "Mike Marciniszyn"
><mike.marciniszyn@cornelisnetworks.com>, "Dennis Dalessandro"
><dennis.dalessandro@cornelisnetworks.com>, "Doug Ledford"
><dledford@redhat.com>, "Faisal Latif" <faisal.latif@intel.com>,
>"Shiraz Saleem" <shiraz.saleem@intel.com>, "Bernard Metzler"
><bmt@zurich.ibm.com>, "Kamal Heib" <kheib@redhat.com>,
>linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org
>Subject: [EXTERNAL] [PATCH 4/4] RDMA/siw: Convert siw_tx_hdt() to
>kmap_local_page()
>
>From: Ira Weiny <ira.weiny@intel.com>
>
>kmap() is being deprecated and will break uses of device dax after
>PKS
>protection is introduced.[1]
>
>The use of kmap() in siw_tx_hdt() is all thread local therefore
>kmap_local_page() is a sufficient replacement and will work with
>pgmap
>protected pages when those are implemented.
>
>kmap_local_page() mappings are tracked in a stack and must be
>unmapped
>in the opposite order they were mapped in.
>
>siw_tx_hdt() tracks pages used in a page_array.  It uses that array
>to
>unmap pages which were mapped on function exit.  Not all entries in
>the
>array are mapped and this is tracked in kmap_mask.
>
>kunmap_local() takes a mapped address rather than a page.  Declare a
>mapped address array, page_array_addr, of the same size as the page
>array to be used for unmapping.
>

Hi Ira, thanks for taking care of that!

I think we can avoid introducing another 'page_array_addr[]' array
here, which must be zeroed first and completely searched for
valid mappings during unmap, and also further bloats the
stack size of siw_tx_hdt(). I think we can go away with the
already available iov[].iov_base addresses array, masking addresses
with PAGE_MASK during unmapping to mask any first byte offset.
All kmap_local_page() mapping end up at that list. For unmapping
we can still rely on the kmap_mask bit field, which is more
efficient to initialize and search for valid mappings. Ordering
during unmapping can be guaranteed if we parse the bitmask
in reverse order. Let me know if you prefer me to propose
a change -- that siw_tx_hdt() thing became rather complex I
have to admit!

Best,
Bernard.

>Use kmap_local_page() instead of kmap() to map pages in the
>page_array.
>
>Because segments are mapped into the page array in increasing index
>order, modify siw_unmap_pages() to unmap pages in decreasing order.
>
>The kmap_mask is no longer needed as the lack of an address in the
>address array can indicate no unmap is required.
>
>[1]
>INVALID URI REMOVED
>lkml_20201009195033.3208459-2D59-2Dira.weiny-40intel.com_&d=DwIDAg&c=
>jf_iaSHvJObTbx-siA1ZOg&r=2TaYXQ0T-r8ZO1PP1alNwU_QJcRRLfmYTAgd3QCvqSc&
>m=wnRcc-qyXV_X7kyQfFYL6XPgmmakQxmo44BmjIon-w0&s=Y0aiKJ4EHZY8FJlI-uiPr
>xcBE95kmgn3iEz3p8d5VF4&e= 
>
>Signed-off-by: Ira Weiny <ira.weiny@intel.com>
>---
> drivers/infiniband/sw/siw/siw_qp_tx.c | 35
>+++++++++++++++------------
> 1 file changed, 20 insertions(+), 15 deletions(-)
>
>diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c
>b/drivers/infiniband/sw/siw/siw_qp_tx.c
>index db68a10d12cd..e70aba23f6e7 100644
>--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
>+++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
>@@ -396,13 +396,17 @@ static int siw_0copy_tx(struct socket *s,
>struct page **page,
> 
> #define MAX_TRAILER (MPA_CRC_SIZE + 4)
> 
>-static void siw_unmap_pages(struct page **pp, unsigned long
>kmap_mask)
>+static void siw_unmap_pages(void **addrs, int len)
> {
>-	while (kmap_mask) {
>-		if (kmap_mask & BIT(0))
>-			kunmap(*pp);
>-		pp++;
>-		kmap_mask >>= 1;
>+	int i;
>+
>+	/*
>+	 * Work backwards through the array to honor the kmap_local_page()
>+	 * ordering requirements.
>+	 */
>+	for (i = (len-1); i >= 0; i--) {
>+		if (addrs[i])
>+			kunmap_local(addrs[i]);
> 	}
> }
> 
>@@ -427,13 +431,15 @@ static int siw_tx_hdt(struct siw_iwarp_tx
>*c_tx, struct socket *s)
> 	struct siw_sge *sge = &wqe->sqe.sge[c_tx->sge_idx];
> 	struct kvec iov[MAX_ARRAY];
> 	struct page *page_array[MAX_ARRAY];
>+	void *page_array_addr[MAX_ARRAY];
> 	struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_EOR };
> 
> 	int seg = 0, do_crc = c_tx->do_crc, is_kva = 0, rv;
> 	unsigned int data_len = c_tx->bytes_unsent, hdr_len = 0, trl_len =
>0,
> 		     sge_off = c_tx->sge_off, sge_idx = c_tx->sge_idx,
> 		     pbl_idx = c_tx->pbl_idx;
>-	unsigned long kmap_mask = 0L;
>+
>+	memset(page_array_addr, 0, sizeof(page_array_addr));
> 
> 	if (c_tx->state == SIW_SEND_HDR) {
> 		if (c_tx->use_sendpage) {
>@@ -498,7 +504,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
>struct socket *s)
> 					p = siw_get_upage(mem->umem,
> 							  sge->laddr + sge_off);
> 				if (unlikely(!p)) {
>-					siw_unmap_pages(page_array, kmap_mask);
>+					siw_unmap_pages(page_array_addr, MAX_ARRAY);
> 					wqe->processed -= c_tx->bytes_unsent;
> 					rv = -EFAULT;
> 					goto done_crc;
>@@ -506,11 +512,10 @@ static int siw_tx_hdt(struct siw_iwarp_tx
>*c_tx, struct socket *s)
> 				page_array[seg] = p;
> 
> 				if (!c_tx->use_sendpage) {
>-					iov[seg].iov_base = kmap(p) + fp_off;
>-					iov[seg].iov_len = plen;
>+					page_array_addr[seg] = kmap_local_page(page_array[seg]);
> 
>-					/* Remember for later kunmap() */
>-					kmap_mask |= BIT(seg);
>+					iov[seg].iov_base = page_array_addr[seg] + fp_off;
>+					iov[seg].iov_len = plen;
> 
> 					if (do_crc)
> 						crypto_shash_update(
>@@ -518,7 +523,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
>struct socket *s)
> 							iov[seg].iov_base,
> 							plen);
> 				} else if (do_crc) {
>-					kaddr = kmap_local_page(p);
>+					kaddr = kmap_local_page(page_array[seg]);
> 					crypto_shash_update(c_tx->mpa_crc_hd,
> 							    kaddr + fp_off,
> 							    plen);
>@@ -542,7 +547,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
>struct socket *s)
> 
> 			if (++seg > (int)MAX_ARRAY) {
> 				siw_dbg_qp(tx_qp(c_tx), "to many fragments\n");
>-				siw_unmap_pages(page_array, kmap_mask);
>+				siw_unmap_pages(page_array_addr, MAX_ARRAY);
> 				wqe->processed -= c_tx->bytes_unsent;
> 				rv = -EMSGSIZE;
> 				goto done_crc;
>@@ -593,7 +598,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
>struct socket *s)
> 	} else {
> 		rv = kernel_sendmsg(s, &msg, iov, seg + 1,
> 				    hdr_len + data_len + trl_len);
>-		siw_unmap_pages(page_array, kmap_mask);
>+		siw_unmap_pages(page_array_addr, MAX_ARRAY);
> 	}
> 	if (rv < (int)hdr_len) {
> 		/* Not even complete hdr pushed or negative rv */
>-- 
>2.28.0.rc0.12.gb6a658bd00c9
>
>


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH V2] RDMA/irdma: Remove use of kmap()
  2021-06-22  6:14 ` [PATCH 2/4] RDMA/i40iw: " ira.weiny
  2021-06-22 12:14   ` Jason Gunthorpe
@ 2021-06-22 16:56   ` ira.weiny
  2021-06-24 18:13     ` Jason Gunthorpe
  1 sibling, 1 reply; 22+ messages in thread
From: ira.weiny @ 2021-06-22 16:56 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Ira Weiny, Mike Marciniszyn, Dennis Dalessandro, Doug Ledford,
	Faisal Latif, Shiraz Saleem, Bernard Metzler, Kamal Heib,
	linux-rdma, linux-kernel

From: Ira Weiny <ira.weiny@intel.com>

kmap() is being deprecated and will break uses of device dax after PKS
protection is introduced.[1]

The kmap() used in the irdma CM driver is thread local.  Therefore
kmap_local_page() is sufficient to use and may provide performance benefits
as well.  kmap_local_page() will work with device dax and pgmap
protected pages.

Use kmap_local_page() instead of kmap().

[1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/

Signed-off-by: Ira Weiny <ira.weiny@intel.com>

---
Changes for V2:
	Move to the new irdma driver for 5.14
---
 drivers/infiniband/hw/irdma/cm.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c
index 3d2bdb033a54..6b62299abfbb 100644
--- a/drivers/infiniband/hw/irdma/cm.c
+++ b/drivers/infiniband/hw/irdma/cm.c
@@ -3675,14 +3675,14 @@ int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 	ibmr->device = iwpd->ibpd.device;
 	iwqp->lsmm_mr = ibmr;
 	if (iwqp->page)
-		iwqp->sc_qp.qp_uk.sq_base = kmap(iwqp->page);
+		iwqp->sc_qp.qp_uk.sq_base = kmap_local_page(iwqp->page);
 
 	cm_node->lsmm_size = accept.size + conn_param->private_data_len;
 	irdma_sc_send_lsmm(&iwqp->sc_qp, iwqp->ietf_mem.va, cm_node->lsmm_size,
 			   ibmr->lkey);
 
 	if (iwqp->page)
-		kunmap(iwqp->page);
+		kunmap_local(iwqp->sc_qp.qp_uk.sq_base);
 
 	iwqp->cm_id = cm_id;
 	cm_node->cm_id = cm_id;
@@ -4093,10 +4093,10 @@ static void irdma_cm_event_connected(struct irdma_cm_event *event)
 	irdma_cm_init_tsa_conn(iwqp, cm_node);
 	read0 = (cm_node->send_rdma0_op == SEND_RDMA_READ_ZERO);
 	if (iwqp->page)
-		iwqp->sc_qp.qp_uk.sq_base = kmap(iwqp->page);
+		iwqp->sc_qp.qp_uk.sq_base = kmap_local_page(iwqp->page);
 	irdma_sc_send_rtt(&iwqp->sc_qp, read0);
 	if (iwqp->page)
-		kunmap(iwqp->page);
+		kunmap_local(iwqp->sc_qp.qp_uk.sq_base);
 
 	attr.qp_state = IB_QPS_RTS;
 	cm_node->qhash_set = false;
-- 
2.28.0.rc0.12.gb6a658bd00c9


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH V2] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page()
  2021-06-22  6:14 ` [PATCH 4/4] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page() ira.weiny
@ 2021-06-22 20:34   ` ira.weiny
  2021-06-23 22:15     ` [PATCH V3] " ira.weiny
  2021-06-24 15:45     ` [PATCH V3] " Bernard Metzler
  2021-06-23 14:36   ` [PATCH V2] " Bernard Metzler
  1 sibling, 2 replies; 22+ messages in thread
From: ira.weiny @ 2021-06-22 20:34 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Ira Weiny, Mike Marciniszyn, Dennis Dalessandro, Doug Ledford,
	Faisal Latif, Shiraz Saleem, Bernard Metzler, Kamal Heib,
	linux-rdma, linux-kernel

From: Ira Weiny <ira.weiny@intel.com>

kmap() is being deprecated and will break uses of device dax after PKS
protection is introduced.[1]

The use of kmap() in siw_tx_hdt() is all thread local therefore
kmap_local_page() is a sufficient replacement and will work with pgmap
protected pages when those are implemented.

siw_tx_hdt() tracks pages used in a page_array.  It uses that array to
unmap pages which were mapped on function exit.  Not all entries in the
array are mapped and this is tracked in kmap_mask.

kunmap_local() takes a mapped address rather than a page.  Alter
siw_unmap_pages() to take the iov array to reuse the iov_base address of
each mapping.  Use PAGE_MASK to get the proper address for
kunmap_local().

kmap_local_page() mappings are tracked in a stack and must be unmapped
in the opposite order they were mapped in.  Because segments are mapped
into the page array in increasing index order, modify siw_unmap_pages()
to unmap pages in decreasing order.

Use kmap_local_page() instead of kmap() to map pages in the page_array.

[1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/

Signed-off-by: Ira Weiny <ira.weiny@intel.com>

---
Changes for V2:
	From Bernard
		Reuse iov[].iov_base rather than declaring another array of
		pointers and preserve the use of kmap_mask to know which iov's
		were kmapped.

---
 drivers/infiniband/sw/siw/siw_qp_tx.c | 32 +++++++++++++++++----------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c
index db68a10d12cd..fd3b9e6a67d7 100644
--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
+++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
@@ -396,13 +396,20 @@ static int siw_0copy_tx(struct socket *s, struct page **page,
 
 #define MAX_TRAILER (MPA_CRC_SIZE + 4)
 
-static void siw_unmap_pages(struct page **pp, unsigned long kmap_mask)
+static void siw_unmap_pages(struct kvec *iov, unsigned long kmap_mask, int len)
 {
-	while (kmap_mask) {
-		if (kmap_mask & BIT(0))
-			kunmap(*pp);
-		pp++;
-		kmap_mask >>= 1;
+	int i;
+
+	/*
+	 * Work backwards through the array to honor the kmap_local_page()
+	 * ordering requirements.
+	 */
+	for (i = (len-1); i >= 0; i--) {
+		if (kmap_mask & BIT(i)) {
+			unsigned long addr = (unsigned long)iov[i].iov_base;
+
+			kunmap_local((void *)(addr & PAGE_MASK));
+		}
 	}
 }
 
@@ -498,7 +505,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 					p = siw_get_upage(mem->umem,
 							  sge->laddr + sge_off);
 				if (unlikely(!p)) {
-					siw_unmap_pages(page_array, kmap_mask);
+					siw_unmap_pages(iov, kmap_mask, MAX_ARRAY);
 					wqe->processed -= c_tx->bytes_unsent;
 					rv = -EFAULT;
 					goto done_crc;
@@ -506,11 +513,12 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 				page_array[seg] = p;
 
 				if (!c_tx->use_sendpage) {
-					iov[seg].iov_base = kmap(p) + fp_off;
-					iov[seg].iov_len = plen;
+					void *kaddr = kmap_local_page(page_array[seg]);
 
 					/* Remember for later kunmap() */
 					kmap_mask |= BIT(seg);
+					iov[seg].iov_base = kaddr + fp_off;
+					iov[seg].iov_len = plen;
 
 					if (do_crc)
 						crypto_shash_update(
@@ -518,7 +526,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 							iov[seg].iov_base,
 							plen);
 				} else if (do_crc) {
-					kaddr = kmap_local_page(p);
+					kaddr = kmap_local_page(page_array[seg]);
 					crypto_shash_update(c_tx->mpa_crc_hd,
 							    kaddr + fp_off,
 							    plen);
@@ -542,7 +550,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 
 			if (++seg > (int)MAX_ARRAY) {
 				siw_dbg_qp(tx_qp(c_tx), "to many fragments\n");
-				siw_unmap_pages(page_array, kmap_mask);
+				siw_unmap_pages(iov, kmap_mask, MAX_ARRAY);
 				wqe->processed -= c_tx->bytes_unsent;
 				rv = -EMSGSIZE;
 				goto done_crc;
@@ -593,7 +601,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 	} else {
 		rv = kernel_sendmsg(s, &msg, iov, seg + 1,
 				    hdr_len + data_len + trl_len);
-		siw_unmap_pages(page_array, kmap_mask);
+		siw_unmap_pages(iov, kmap_mask, MAX_ARRAY);
 	}
 	if (rv < (int)hdr_len) {
 		/* Not even complete hdr pushed or negative rv */
-- 
2.28.0.rc0.12.gb6a658bd00c9


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 4/4] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page()
  2021-06-22 16:42 ` [PATCH 4/4] " Bernard Metzler
@ 2021-06-22 20:39   ` Ira Weiny
  0 siblings, 0 replies; 22+ messages in thread
From: Ira Weiny @ 2021-06-22 20:39 UTC (permalink / raw)
  To: Bernard Metzler
  Cc: Jason Gunthorpe, Mike Marciniszyn, Dennis Dalessandro,
	Doug Ledford, Faisal Latif, Shiraz Saleem, Kamal Heib,
	linux-rdma, linux-kernel

On Tue, Jun 22, 2021 at 04:42:49PM +0000, Bernard Metzler wrote:
> -----ira.weiny@intel.com wrote: -----
> 
> >To: "Jason Gunthorpe" <jgg@ziepe.ca>
> >From: ira.weiny@intel.com
> >Date: 06/22/2021 08:14AM
> >Cc: "Ira Weiny" <ira.weiny@intel.com>, "Mike Marciniszyn"
> ><mike.marciniszyn@cornelisnetworks.com>, "Dennis Dalessandro"
> ><dennis.dalessandro@cornelisnetworks.com>, "Doug Ledford"
> ><dledford@redhat.com>, "Faisal Latif" <faisal.latif@intel.com>,
> >"Shiraz Saleem" <shiraz.saleem@intel.com>, "Bernard Metzler"
> ><bmt@zurich.ibm.com>, "Kamal Heib" <kheib@redhat.com>,
> >linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org
> >Subject: [EXTERNAL] [PATCH 4/4] RDMA/siw: Convert siw_tx_hdt() to
> >kmap_local_page()
> >
> >From: Ira Weiny <ira.weiny@intel.com>
> >
> >kmap() is being deprecated and will break uses of device dax after
> >PKS
> >protection is introduced.[1]
> >
> >The use of kmap() in siw_tx_hdt() is all thread local therefore
> >kmap_local_page() is a sufficient replacement and will work with
> >pgmap
> >protected pages when those are implemented.
> >
> >kmap_local_page() mappings are tracked in a stack and must be
> >unmapped
> >in the opposite order they were mapped in.
> >
> >siw_tx_hdt() tracks pages used in a page_array.  It uses that array
> >to
> >unmap pages which were mapped on function exit.  Not all entries in
> >the
> >array are mapped and this is tracked in kmap_mask.
> >
> >kunmap_local() takes a mapped address rather than a page.  Declare a
> >mapped address array, page_array_addr, of the same size as the page
> >array to be used for unmapping.
> >
> 
> Hi Ira, thanks for taking care of that!
> 
> I think we can avoid introducing another 'page_array_addr[]' array
> here, which must be zeroed first and completely searched for
> valid mappings during unmap, and also further bloats the
> stack size of siw_tx_hdt(). I think we can go away with the
> already available iov[].iov_base addresses array, masking addresses
> with PAGE_MASK during unmapping to mask any first byte offset.
> All kmap_local_page() mapping end up at that list. For unmapping
> we can still rely on the kmap_mask bit field, which is more
> efficient to initialize and search for valid mappings. Ordering
> during unmapping can be guaranteed if we parse the bitmask
> in reverse order. Let me know if you prefer me to propose
> a change -- that siw_tx_hdt() thing became rather complex I
> have to admit!

Seems not too bad, V2 sent.

I was concerned with the additional stack size but only 28 pointers (If I did
my math right) did not seem too bad.  It is redundant though so lets see if
I've gotten V2 right.

Thanks!
Ira

> 
> Best,
> Bernard.
> 
> >Use kmap_local_page() instead of kmap() to map pages in the
> >page_array.
> >
> >Because segments are mapped into the page array in increasing index
> >order, modify siw_unmap_pages() to unmap pages in decreasing order.
> >
> >The kmap_mask is no longer needed as the lack of an address in the
> >address array can indicate no unmap is required.
> >
> >[1]
> >INVALID URI REMOVED
> >lkml_20201009195033.3208459-2D59-2Dira.weiny-40intel.com_&d=DwIDAg&c=
> >jf_iaSHvJObTbx-siA1ZOg&r=2TaYXQ0T-r8ZO1PP1alNwU_QJcRRLfmYTAgd3QCvqSc&
> >m=wnRcc-qyXV_X7kyQfFYL6XPgmmakQxmo44BmjIon-w0&s=Y0aiKJ4EHZY8FJlI-uiPr
> >xcBE95kmgn3iEz3p8d5VF4&e= 
> >
> >Signed-off-by: Ira Weiny <ira.weiny@intel.com>
> >---
> > drivers/infiniband/sw/siw/siw_qp_tx.c | 35
> >+++++++++++++++------------
> > 1 file changed, 20 insertions(+), 15 deletions(-)
> >
> >diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c
> >b/drivers/infiniband/sw/siw/siw_qp_tx.c
> >index db68a10d12cd..e70aba23f6e7 100644
> >--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
> >+++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
> >@@ -396,13 +396,17 @@ static int siw_0copy_tx(struct socket *s,
> >struct page **page,
> > 
> > #define MAX_TRAILER (MPA_CRC_SIZE + 4)
> > 
> >-static void siw_unmap_pages(struct page **pp, unsigned long
> >kmap_mask)
> >+static void siw_unmap_pages(void **addrs, int len)
> > {
> >-	while (kmap_mask) {
> >-		if (kmap_mask & BIT(0))
> >-			kunmap(*pp);
> >-		pp++;
> >-		kmap_mask >>= 1;
> >+	int i;
> >+
> >+	/*
> >+	 * Work backwards through the array to honor the kmap_local_page()
> >+	 * ordering requirements.
> >+	 */
> >+	for (i = (len-1); i >= 0; i--) {
> >+		if (addrs[i])
> >+			kunmap_local(addrs[i]);
> > 	}
> > }
> > 
> >@@ -427,13 +431,15 @@ static int siw_tx_hdt(struct siw_iwarp_tx
> >*c_tx, struct socket *s)
> > 	struct siw_sge *sge = &wqe->sqe.sge[c_tx->sge_idx];
> > 	struct kvec iov[MAX_ARRAY];
> > 	struct page *page_array[MAX_ARRAY];
> >+	void *page_array_addr[MAX_ARRAY];
> > 	struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_EOR };
> > 
> > 	int seg = 0, do_crc = c_tx->do_crc, is_kva = 0, rv;
> > 	unsigned int data_len = c_tx->bytes_unsent, hdr_len = 0, trl_len =
> >0,
> > 		     sge_off = c_tx->sge_off, sge_idx = c_tx->sge_idx,
> > 		     pbl_idx = c_tx->pbl_idx;
> >-	unsigned long kmap_mask = 0L;
> >+
> >+	memset(page_array_addr, 0, sizeof(page_array_addr));
> > 
> > 	if (c_tx->state == SIW_SEND_HDR) {
> > 		if (c_tx->use_sendpage) {
> >@@ -498,7 +504,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
> >struct socket *s)
> > 					p = siw_get_upage(mem->umem,
> > 							  sge->laddr + sge_off);
> > 				if (unlikely(!p)) {
> >-					siw_unmap_pages(page_array, kmap_mask);
> >+					siw_unmap_pages(page_array_addr, MAX_ARRAY);
> > 					wqe->processed -= c_tx->bytes_unsent;
> > 					rv = -EFAULT;
> > 					goto done_crc;
> >@@ -506,11 +512,10 @@ static int siw_tx_hdt(struct siw_iwarp_tx
> >*c_tx, struct socket *s)
> > 				page_array[seg] = p;
> > 
> > 				if (!c_tx->use_sendpage) {
> >-					iov[seg].iov_base = kmap(p) + fp_off;
> >-					iov[seg].iov_len = plen;
> >+					page_array_addr[seg] = kmap_local_page(page_array[seg]);
> > 
> >-					/* Remember for later kunmap() */
> >-					kmap_mask |= BIT(seg);
> >+					iov[seg].iov_base = page_array_addr[seg] + fp_off;
> >+					iov[seg].iov_len = plen;
> > 
> > 					if (do_crc)
> > 						crypto_shash_update(
> >@@ -518,7 +523,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
> >struct socket *s)
> > 							iov[seg].iov_base,
> > 							plen);
> > 				} else if (do_crc) {
> >-					kaddr = kmap_local_page(p);
> >+					kaddr = kmap_local_page(page_array[seg]);
> > 					crypto_shash_update(c_tx->mpa_crc_hd,
> > 							    kaddr + fp_off,
> > 							    plen);
> >@@ -542,7 +547,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
> >struct socket *s)
> > 
> > 			if (++seg > (int)MAX_ARRAY) {
> > 				siw_dbg_qp(tx_qp(c_tx), "to many fragments\n");
> >-				siw_unmap_pages(page_array, kmap_mask);
> >+				siw_unmap_pages(page_array_addr, MAX_ARRAY);
> > 				wqe->processed -= c_tx->bytes_unsent;
> > 				rv = -EMSGSIZE;
> > 				goto done_crc;
> >@@ -593,7 +598,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
> >struct socket *s)
> > 	} else {
> > 		rv = kernel_sendmsg(s, &msg, iov, seg + 1,
> > 				    hdr_len + data_len + trl_len);
> >-		siw_unmap_pages(page_array, kmap_mask);
> >+		siw_unmap_pages(page_array_addr, MAX_ARRAY);
> > 	}
> > 	if (rv < (int)hdr_len) {
> > 		/* Not even complete hdr pushed or negative rv */
> >-- 
> >2.28.0.rc0.12.gb6a658bd00c9
> >
> >
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V2] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page()
  2021-06-22  6:14 ` [PATCH 4/4] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page() ira.weiny
  2021-06-22 20:34   ` [PATCH V2] " ira.weiny
@ 2021-06-23 14:36   ` Bernard Metzler
  2021-06-23 15:34     ` Ira Weiny
  1 sibling, 1 reply; 22+ messages in thread
From: Bernard Metzler @ 2021-06-23 14:36 UTC (permalink / raw)
  To: ira.weiny
  Cc: Jason Gunthorpe, Mike Marciniszyn, Dennis Dalessandro,
	Doug Ledford, Faisal Latif, Shiraz Saleem, Kamal Heib,
	linux-rdma, linux-kernel

-----ira.weiny@intel.com wrote: -----

>To: "Jason Gunthorpe" <jgg@ziepe.ca>
>From: ira.weiny@intel.com
>Date: 06/22/2021 10:35PM
>Cc: "Ira Weiny" <ira.weiny@intel.com>, "Mike Marciniszyn"
><mike.marciniszyn@cornelisnetworks.com>, "Dennis Dalessandro"
><dennis.dalessandro@cornelisnetworks.com>, "Doug Ledford"
><dledford@redhat.com>, "Faisal Latif" <faisal.latif@intel.com>,
>"Shiraz Saleem" <shiraz.saleem@intel.com>, "Bernard Metzler"
><bmt@zurich.ibm.com>, "Kamal Heib" <kheib@redhat.com>,
>linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org
>Subject: [EXTERNAL] [PATCH V2] RDMA/siw: Convert siw_tx_hdt() to
>kmap_local_page()
>
>From: Ira Weiny <ira.weiny@intel.com>
>
>kmap() is being deprecated and will break uses of device dax after
>PKS
>protection is introduced.[1]
>
>The use of kmap() in siw_tx_hdt() is all thread local therefore
>kmap_local_page() is a sufficient replacement and will work with
>pgmap
>protected pages when those are implemented.
>
>siw_tx_hdt() tracks pages used in a page_array.  It uses that array
>to
>unmap pages which were mapped on function exit.  Not all entries in
>the
>array are mapped and this is tracked in kmap_mask.
>
>kunmap_local() takes a mapped address rather than a page.  Alter
>siw_unmap_pages() to take the iov array to reuse the iov_base address
>of
>each mapping.  Use PAGE_MASK to get the proper address for
>kunmap_local().
>
>kmap_local_page() mappings are tracked in a stack and must be
>unmapped
>in the opposite order they were mapped in.  Because segments are
>mapped
>into the page array in increasing index order, modify
>siw_unmap_pages()
>to unmap pages in decreasing order.
>
>Use kmap_local_page() instead of kmap() to map pages in the
>page_array.
>
>[1]
>INVALID URI REMOVED
>lkml_20201009195033.3208459-2D59-2Dira.weiny-40intel.com_&d=DwIDAg&c=
>jf_iaSHvJObTbx-siA1ZOg&r=2TaYXQ0T-r8ZO1PP1alNwU_QJcRRLfmYTAgd3QCvqSc&
>m=ujJBVqPLdVdVxXvOu_PlFL3NVC0Znds3FgxyrtWJtwM&s=WZIBAdwlCqPIRjsNOGlly
>gQ6Hsug6ObgrWgO_nvBGyc&e= 
>
>Signed-off-by: Ira Weiny <ira.weiny@intel.com>
>
>---
>Changes for V2:
>	From Bernard
>		Reuse iov[].iov_base rather than declaring another array of
>		pointers and preserve the use of kmap_mask to know which iov's
>		were kmapped.
>
>---
> drivers/infiniband/sw/siw/siw_qp_tx.c | 32
>+++++++++++++++++----------
> 1 file changed, 20 insertions(+), 12 deletions(-)
>
>diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c
>b/drivers/infiniband/sw/siw/siw_qp_tx.c
>index db68a10d12cd..fd3b9e6a67d7 100644
>--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
>+++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
>@@ -396,13 +396,20 @@ static int siw_0copy_tx(struct socket *s,
>struct page **page,
> 
> #define MAX_TRAILER (MPA_CRC_SIZE + 4)
> 
>-static void siw_unmap_pages(struct page **pp, unsigned long
>kmap_mask)
>+static void siw_unmap_pages(struct kvec *iov, unsigned long
>kmap_mask, int len)
> {
>-	while (kmap_mask) {
>-		if (kmap_mask & BIT(0))
>-			kunmap(*pp);
>-		pp++;
>-		kmap_mask >>= 1;
>+	int i;
>+
>+	/*
>+	 * Work backwards through the array to honor the kmap_local_page()
>+	 * ordering requirements.
>+	 */
>+	for (i = (len-1); i >= 0; i--) {
>+		if (kmap_mask & BIT(i)) {
>+			unsigned long addr = (unsigned long)iov[i].iov_base;
>+
>+			kunmap_local((void *)(addr & PAGE_MASK));
>+		}
> 	}
> }
> 
>@@ -498,7 +505,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
>struct socket *s)
> 					p = siw_get_upage(mem->umem,
> 							  sge->laddr + sge_off);
> 				if (unlikely(!p)) {
>-					siw_unmap_pages(page_array, kmap_mask);
>+					siw_unmap_pages(iov, kmap_mask, MAX_ARRAY);
> 					wqe->processed -= c_tx->bytes_unsent;
> 					rv = -EFAULT;
> 					goto done_crc;
>@@ -506,11 +513,12 @@ static int siw_tx_hdt(struct siw_iwarp_tx
>*c_tx, struct socket *s)
> 				page_array[seg] = p;
> 
> 				if (!c_tx->use_sendpage) {
>-					iov[seg].iov_base = kmap(p) + fp_off;
>-					iov[seg].iov_len = plen;
>+					void *kaddr = kmap_local_page(page_array[seg]);

we can use 'kmap_local_page(p)' here
> 
> 					/* Remember for later kunmap() */
> 					kmap_mask |= BIT(seg);
>+					iov[seg].iov_base = kaddr + fp_off;
>+					iov[seg].iov_len = plen;
> 
> 					if (do_crc)
> 						crypto_shash_update(
>@@ -518,7 +526,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
>struct socket *s)
> 							iov[seg].iov_base,
> 							plen);

This patch does not apply for me. Would I have to install first
your [Patch 3/4] -- since the current patch references kmap_local_page()
already? Maybe it is better to apply if it would be just one siw
related patch in that series?



> 				} else if (do_crc) {
>-					kaddr = kmap_local_page(p);
>+					kaddr = kmap_local_page(page_array[seg]);

using 'kmap_local_page(p)' as you had it is straightforward
and I would prefer it.

> 					crypto_shash_update(c_tx->mpa_crc_hd,
> 							    kaddr + fp_off,
> 							    plen);
>@@ -542,7 +550,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
>struct socket *s)
> 
> 			if (++seg > (int)MAX_ARRAY) {
> 				siw_dbg_qp(tx_qp(c_tx), "to many fragments\n");
>-				siw_unmap_pages(page_array, kmap_mask);
>+				siw_unmap_pages(iov, kmap_mask, MAX_ARRAY);

to minimize the iterations over the byte array in 'siw_unmap_pages()',
we may pass seg-1 instead of MAX_ARRAY


> 				wqe->processed -= c_tx->bytes_unsent;
> 				rv = -EMSGSIZE;
> 				goto done_crc;
>@@ -593,7 +601,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
>struct socket *s)
> 	} else {
> 		rv = kernel_sendmsg(s, &msg, iov, seg + 1,
> 				    hdr_len + data_len + trl_len);
>-		siw_unmap_pages(page_array, kmap_mask);
>+		siw_unmap_pages(iov, kmap_mask, MAX_ARRAY);

to minimize the iterations over the byte array in 'siw_unmap_pages()',
we may pass seg instead of MAX_ARRAY

> 	}
> 	if (rv < (int)hdr_len) {
> 		/* Not even complete hdr pushed or negative rv */
>-- 
>2.28.0.rc0.12.gb6a658bd00c9
>
>


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V2] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page()
  2021-06-23 14:36   ` [PATCH V2] " Bernard Metzler
@ 2021-06-23 15:34     ` Ira Weiny
  0 siblings, 0 replies; 22+ messages in thread
From: Ira Weiny @ 2021-06-23 15:34 UTC (permalink / raw)
  To: Bernard Metzler
  Cc: Jason Gunthorpe, Mike Marciniszyn, Dennis Dalessandro,
	Doug Ledford, Faisal Latif, Shiraz Saleem, Kamal Heib,
	linux-rdma, linux-kernel

On Wed, Jun 23, 2021 at 02:36:45PM +0000, Bernard Metzler wrote:
> -----ira.weiny@intel.com wrote: -----
> 
> >@@ -506,11 +513,12 @@ static int siw_tx_hdt(struct siw_iwarp_tx
> >*c_tx, struct socket *s)
> > 				page_array[seg] = p;
> > 
> > 				if (!c_tx->use_sendpage) {
> >-					iov[seg].iov_base = kmap(p) + fp_off;
> >-					iov[seg].iov_len = plen;
> >+					void *kaddr = kmap_local_page(page_array[seg]);
> 
> we can use 'kmap_local_page(p)' here

Yes but I actually did this on purpose as it makes the code read clearly that
the mapping is 'seg' element of the array.  Do you prefer 'p' because this is a
performant path?

> > 
> > 					/* Remember for later kunmap() */
> > 					kmap_mask |= BIT(seg);
> >+					iov[seg].iov_base = kaddr + fp_off;
> >+					iov[seg].iov_len = plen;
> > 
> > 					if (do_crc)
> > 						crypto_shash_update(
> >@@ -518,7 +526,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
> >struct socket *s)
> > 							iov[seg].iov_base,
> > 							plen);
> 
> This patch does not apply for me. Would I have to install first
> your [Patch 3/4] -- since the current patch references kmap_local_page()
> already? Maybe it is better to apply if it would be just one siw
> related patch in that series?

Yes the other patch goes first.  I split it out to make this more difficult
change more reviewable.  I could squash them as it is probably straight forward
enough but I've been careful with this in other subsystems.

Jason, do you have any issue with squashing the 2 patches?

> 
> 
> 
> > 				} else if (do_crc) {
> >-					kaddr = kmap_local_page(p);
> >+					kaddr = kmap_local_page(page_array[seg]);
> 
> using 'kmap_local_page(p)' as you had it is straightforward
> and I would prefer it.

OK.  I think this reads cleaner but I can see 'p' being more performant.

> 
> > 					crypto_shash_update(c_tx->mpa_crc_hd,
> > 							    kaddr + fp_off,
> > 							    plen);
> >@@ -542,7 +550,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
> >struct socket *s)
> > 
> > 			if (++seg > (int)MAX_ARRAY) {
> > 				siw_dbg_qp(tx_qp(c_tx), "to many fragments\n");
> >-				siw_unmap_pages(page_array, kmap_mask);
> >+				siw_unmap_pages(iov, kmap_mask, MAX_ARRAY);
> 
> to minimize the iterations over the byte array in 'siw_unmap_pages()',
> we may pass seg-1 instead of MAX_ARRAY

Sounds good.

> 
> 
> > 				wqe->processed -= c_tx->bytes_unsent;
> > 				rv = -EMSGSIZE;
> > 				goto done_crc;
> >@@ -593,7 +601,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
> >struct socket *s)
> > 	} else {
> > 		rv = kernel_sendmsg(s, &msg, iov, seg + 1,
> > 				    hdr_len + data_len + trl_len);
> >-		siw_unmap_pages(page_array, kmap_mask);
> >+		siw_unmap_pages(iov, kmap_mask, MAX_ARRAY);
> 
> to minimize the iterations over the byte array in 'siw_unmap_pages()',
> we may pass seg instead of MAX_ARRAY

Will do.

Thanks for the review!  :-D
Ira

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH V3] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page()
  2021-06-22 20:34   ` [PATCH V2] " ira.weiny
@ 2021-06-23 22:15     ` ira.weiny
  2021-06-24 17:48       ` [PATCH V4] " ira.weiny
  2021-06-29 14:11       ` Bernard Metzler
  2021-06-24 15:45     ` [PATCH V3] " Bernard Metzler
  1 sibling, 2 replies; 22+ messages in thread
From: ira.weiny @ 2021-06-23 22:15 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Ira Weiny, Mike Marciniszyn, Dennis Dalessandro, Doug Ledford,
	Faisal Latif, Shiraz Saleem, Bernard Metzler, Kamal Heib,
	linux-rdma, linux-kernel

From: Ira Weiny <ira.weiny@intel.com>

kmap() is being deprecated and will break uses of device dax after PKS
protection is introduced.[1]

The use of kmap() in siw_tx_hdt() is all thread local therefore
kmap_local_page() is a sufficient replacement and will work with pgmap
protected pages when those are implemented.

siw_tx_hdt() tracks pages used in a page_array.  It uses that array to
unmap pages which were mapped on function exit.  Not all entries in the
array are mapped and this is tracked in kmap_mask.

kunmap_local() takes a mapped address rather than a page.  Alter
siw_unmap_pages() to take the iov array to reuse the iov_base address of
each mapping.  Use PAGE_MASK to get the proper address for
kunmap_local().

kmap_local_page() mappings are tracked in a stack and must be unmapped
in the opposite order they were mapped in.  Because segments are mapped
into the page array in increasing index order, modify siw_unmap_pages()
to unmap pages in decreasing order.

Use kmap_local_page() instead of kmap() to map pages in the page_array.

[1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/

Signed-off-by: Ira Weiny <ira.weiny@intel.com>

---
Jason, I went ahead and left this a separate patch.  Let me know if you really
want this and the other siw squashed.

Changes for V3:
	From Bernard
		Use 'p' in kmap_local_page()
		Use seg as length to siw_unmap_pages()

Changes for V2:
	From Bernard
		Reuse iov[].iov_base rather than declaring another array
		of pointers and preserve the use of kmap_mask to know
		which iov's were kmapped.
---
 drivers/infiniband/sw/siw/siw_qp_tx.c | 30 +++++++++++++++++----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c
index db68a10d12cd..89a5b75f7254 100644
--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
+++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
@@ -396,13 +396,20 @@ static int siw_0copy_tx(struct socket *s, struct page **page,
 
 #define MAX_TRAILER (MPA_CRC_SIZE + 4)
 
-static void siw_unmap_pages(struct page **pp, unsigned long kmap_mask)
+static void siw_unmap_pages(struct kvec *iov, unsigned long kmap_mask, int len)
 {
-	while (kmap_mask) {
-		if (kmap_mask & BIT(0))
-			kunmap(*pp);
-		pp++;
-		kmap_mask >>= 1;
+	int i;
+
+	/*
+	 * Work backwards through the array to honor the kmap_local_page()
+	 * ordering requirements.
+	 */
+	for (i = (len-1); i >= 0; i--) {
+		if (kmap_mask & BIT(i)) {
+			unsigned long addr = (unsigned long)iov[i].iov_base;
+
+			kunmap_local((void *)(addr & PAGE_MASK));
+		}
 	}
 }
 
@@ -498,7 +505,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 					p = siw_get_upage(mem->umem,
 							  sge->laddr + sge_off);
 				if (unlikely(!p)) {
-					siw_unmap_pages(page_array, kmap_mask);
+					siw_unmap_pages(iov, kmap_mask, seg);
 					wqe->processed -= c_tx->bytes_unsent;
 					rv = -EFAULT;
 					goto done_crc;
@@ -506,11 +513,12 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 				page_array[seg] = p;
 
 				if (!c_tx->use_sendpage) {
-					iov[seg].iov_base = kmap(p) + fp_off;
-					iov[seg].iov_len = plen;
+					void *kaddr = kmap_local_page(p);
 
 					/* Remember for later kunmap() */
 					kmap_mask |= BIT(seg);
+					iov[seg].iov_base = kaddr + fp_off;
+					iov[seg].iov_len = plen;
 
 					if (do_crc)
 						crypto_shash_update(
@@ -542,7 +550,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 
 			if (++seg > (int)MAX_ARRAY) {
 				siw_dbg_qp(tx_qp(c_tx), "to many fragments\n");
-				siw_unmap_pages(page_array, kmap_mask);
+				siw_unmap_pages(iov, kmap_mask, seg-1);
 				wqe->processed -= c_tx->bytes_unsent;
 				rv = -EMSGSIZE;
 				goto done_crc;
@@ -593,7 +601,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 	} else {
 		rv = kernel_sendmsg(s, &msg, iov, seg + 1,
 				    hdr_len + data_len + trl_len);
-		siw_unmap_pages(page_array, kmap_mask);
+		siw_unmap_pages(iov, kmap_mask, seg+1);
 	}
 	if (rv < (int)hdr_len) {
 		/* Not even complete hdr pushed or negative rv */
-- 
2.28.0.rc0.12.gb6a658bd00c9


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH V3] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page()
  2021-06-22 20:34   ` [PATCH V2] " ira.weiny
  2021-06-23 22:15     ` [PATCH V3] " ira.weiny
@ 2021-06-24 15:45     ` Bernard Metzler
  2021-06-24 17:33       ` Ira Weiny
  1 sibling, 1 reply; 22+ messages in thread
From: Bernard Metzler @ 2021-06-24 15:45 UTC (permalink / raw)
  To: ira.weiny
  Cc: Jason Gunthorpe, Mike Marciniszyn, Dennis Dalessandro,
	Doug Ledford, Faisal Latif, Shiraz Saleem, Kamal Heib,
	linux-rdma, linux-kernel


-----ira.weiny@intel.com wrote: -----

>To: "Jason Gunthorpe" <jgg@ziepe.ca>
>From: ira.weiny@intel.com
>Date: 06/24/2021 12:16AM
>Cc: "Ira Weiny" <ira.weiny@intel.com>, "Mike Marciniszyn"
><mike.marciniszyn@cornelisnetworks.com>, "Dennis Dalessandro"
><dennis.dalessandro@cornelisnetworks.com>, "Doug Ledford"
><dledford@redhat.com>, "Faisal Latif" <faisal.latif@intel.com>,
>"Shiraz Saleem" <shiraz.saleem@intel.com>, "Bernard Metzler"
><bmt@zurich.ibm.com>, "Kamal Heib" <kheib@redhat.com>,
>linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org
>Subject: [EXTERNAL] [PATCH V3] RDMA/siw: Convert siw_tx_hdt() to
>kmap_local_page()
>
>From: Ira Weiny <ira.weiny@intel.com>
>
>kmap() is being deprecated and will break uses of device dax after
>PKS
>protection is introduced.[1]
>
>The use of kmap() in siw_tx_hdt() is all thread local therefore
>kmap_local_page() is a sufficient replacement and will work with
>pgmap
>protected pages when those are implemented.
>
>siw_tx_hdt() tracks pages used in a page_array.  It uses that array
>to
>unmap pages which were mapped on function exit.  Not all entries in
>the
>array are mapped and this is tracked in kmap_mask.
>
>kunmap_local() takes a mapped address rather than a page.  Alter
>siw_unmap_pages() to take the iov array to reuse the iov_base address
>of
>each mapping.  Use PAGE_MASK to get the proper address for
>kunmap_local().
>
>kmap_local_page() mappings are tracked in a stack and must be
>unmapped
>in the opposite order they were mapped in.  Because segments are
>mapped
>into the page array in increasing index order, modify
>siw_unmap_pages()
>to unmap pages in decreasing order.
>
>Use kmap_local_page() instead of kmap() to map pages in the
>page_array.
>
>[1]
>INVALID URI REMOVED
>lkml_20201009195033.3208459-2D59-2Dira.weiny-40intel.com_&d=DwIDAg&c=
>jf_iaSHvJObTbx-siA1ZOg&r=2TaYXQ0T-r8ZO1PP1alNwU_QJcRRLfmYTAgd3QCvqSc&
>m=eI4Db7iSlEKRl4l5pYKwY5rL5WXWWxahhxNciwy2lRA&s=vo11VhOvYbAkABdhV6htX
>TmXgFZeWbBZAFnPDvg7Bzs&e= 
>
>Signed-off-by: Ira Weiny <ira.weiny@intel.com>
>
>---
>Jason, I went ahead and left this a separate patch.  Let me know if
>you really
>want this and the other siw squashed.
>
>Changes for V3:
>	From Bernard
>		Use 'p' in kmap_local_page()
>		Use seg as length to siw_unmap_pages()
>
>Changes for V2:
>	From Bernard
>		Reuse iov[].iov_base rather than declaring another array
>		of pointers and preserve the use of kmap_mask to know
>		which iov's were kmapped.
>---
> drivers/infiniband/sw/siw/siw_qp_tx.c | 30
>+++++++++++++++++----------
> 1 file changed, 19 insertions(+), 11 deletions(-)
>
>diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c
>b/drivers/infiniband/sw/siw/siw_qp_tx.c
>index db68a10d12cd..89a5b75f7254 100644
>--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
>+++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
>@@ -396,13 +396,20 @@ static int siw_0copy_tx(struct socket *s,
>struct page **page,
> 
> #define MAX_TRAILER (MPA_CRC_SIZE + 4)
> 
>-static void siw_unmap_pages(struct page **pp, unsigned long
>kmap_mask)
>+static void siw_unmap_pages(struct kvec *iov, unsigned long
>kmap_mask, int len)
> {
>-	while (kmap_mask) {
>-		if (kmap_mask & BIT(0))
>-			kunmap(*pp);
>-		pp++;
>-		kmap_mask >>= 1;
>+	int i;
>+
>+	/*
>+	 * Work backwards through the array to honor the kmap_local_page()
>+	 * ordering requirements.
>+	 */
>+	for (i = (len-1); i >= 0; i--) {
>+		if (kmap_mask & BIT(i)) {
>+			unsigned long addr = (unsigned long)iov[i].iov_base;
>+
>+			kunmap_local((void *)(addr & PAGE_MASK));
>+		}
> 	}
> }
> 
>@@ -498,7 +505,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
>struct socket *s)
> 					p = siw_get_upage(mem->umem,
> 							  sge->laddr + sge_off);
> 				if (unlikely(!p)) {
>-					siw_unmap_pages(page_array, kmap_mask);
>+					siw_unmap_pages(iov, kmap_mask, seg);
> 					wqe->processed -= c_tx->bytes_unsent;
> 					rv = -EFAULT;
> 					goto done_crc;
>@@ -506,11 +513,12 @@ static int siw_tx_hdt(struct siw_iwarp_tx
>*c_tx, struct socket *s)
> 				page_array[seg] = p;
> 
> 				if (!c_tx->use_sendpage) {
>-					iov[seg].iov_base = kmap(p) + fp_off;
>-					iov[seg].iov_len = plen;
>+					void *kaddr = kmap_local_page(p);
> 
> 					/* Remember for later kunmap() */
> 					kmap_mask |= BIT(seg);
>+					iov[seg].iov_base = kaddr + fp_off;
>+					iov[seg].iov_len = plen;
> 
> 					if (do_crc)
> 						crypto_shash_update(
>@@ -542,7 +550,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
>struct socket *s)
> 
> 			if (++seg > (int)MAX_ARRAY) {
> 				siw_dbg_qp(tx_qp(c_tx), "to many fragments\n");
>-				siw_unmap_pages(page_array, kmap_mask);
>+				siw_unmap_pages(iov, kmap_mask, seg-1);
> 				wqe->processed -= c_tx->bytes_unsent;
> 				rv = -EMSGSIZE;
> 				goto done_crc;
>@@ -593,7 +601,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
>struct socket *s)
> 	} else {
> 		rv = kernel_sendmsg(s, &msg, iov, seg + 1,
> 				    hdr_len + data_len + trl_len);
>-		siw_unmap_pages(page_array, kmap_mask);
>+		siw_unmap_pages(iov, kmap_mask, seg+1);

seg+1 is one to many, since the last segment references the iWarp
trailer (CRC). There are 2 reason for this multi-segment processing
in the transmit path. (1) efficiency and (2) MTU based packet framing.
The iov contains the complete iWarp frame with header, (potentially
multiple) data fragments, and the CRC. It gets pushed to TCP in one
go, praying for iWarp framing stays intact (which most time works).
So the code can collect data form multiple SGE's of a WRITE or
SEND and tries putting those into one frame, if MTU allows, and
adds header and trailer. 
The last segment (seg + 1) references the CRC, which is never kmap'ed.

I'll try the code next days, but it looks good otherwise!

Thanks very much!
> 	}
> 	if (rv < (int)hdr_len) {
> 		/* Not even complete hdr pushed or negative rv */
>-- 
>2.28.0.rc0.12.gb6a658bd00c9
>
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V3] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page()
  2021-06-24 15:45     ` [PATCH V3] " Bernard Metzler
@ 2021-06-24 17:33       ` Ira Weiny
  0 siblings, 0 replies; 22+ messages in thread
From: Ira Weiny @ 2021-06-24 17:33 UTC (permalink / raw)
  To: Bernard Metzler
  Cc: Jason Gunthorpe, Mike Marciniszyn, Dennis Dalessandro,
	Doug Ledford, Faisal Latif, Shiraz Saleem, Kamal Heib,
	linux-rdma, linux-kernel

On Thu, Jun 24, 2021 at 03:45:55PM +0000, Bernard Metzler wrote:
> 
> >@@ -593,7 +601,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
> >struct socket *s)
> > 	} else {
> > 		rv = kernel_sendmsg(s, &msg, iov, seg + 1,
> > 				    hdr_len + data_len + trl_len);
> >-		siw_unmap_pages(page_array, kmap_mask);
> >+		siw_unmap_pages(iov, kmap_mask, seg+1);
> 
> seg+1 is one to many, since the last segment references the iWarp
> trailer (CRC). There are 2 reason for this multi-segment processing
> in the transmit path. (1) efficiency and (2) MTU based packet framing.
> The iov contains the complete iWarp frame with header, (potentially
> multiple) data fragments, and the CRC. It gets pushed to TCP in one
> go, praying for iWarp framing stays intact (which most time works).
> So the code can collect data form multiple SGE's of a WRITE or
> SEND and tries putting those into one frame, if MTU allows, and
> adds header and trailer. 
>
> The last segment (seg + 1) references the CRC, which is never kmap'ed.

siw_unmap_pages() take a length and seg is the index...

But ok so a further optimization...

Fair enough.

> 
> I'll try the code next days, but it looks good otherwise!
 
I believe this will work though.

Ira

> Thanks very much!
> > 	}
> > 	if (rv < (int)hdr_len) {
> > 		/* Not even complete hdr pushed or negative rv */
> >-- 
> >2.28.0.rc0.12.gb6a658bd00c9
> >
> >

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH V4] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page()
  2021-06-23 22:15     ` [PATCH V3] " ira.weiny
@ 2021-06-24 17:48       ` ira.weiny
  2021-07-15 18:00         ` Jason Gunthorpe
  2021-06-29 14:11       ` Bernard Metzler
  1 sibling, 1 reply; 22+ messages in thread
From: ira.weiny @ 2021-06-24 17:48 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Ira Weiny, Mike Marciniszyn, Dennis Dalessandro, Doug Ledford,
	Faisal Latif, Shiraz Saleem, Bernard Metzler, Kamal Heib,
	linux-rdma, linux-kernel

From: Ira Weiny <ira.weiny@intel.com>

kmap() is being deprecated and will break uses of device dax after PKS
protection is introduced.[1]

The use of kmap() in siw_tx_hdt() is all thread local therefore
kmap_local_page() is a sufficient replacement and will work with pgmap
protected pages when those are implemented.

siw_tx_hdt() tracks pages used in a page_array.  It uses that array to
unmap pages which were mapped on function exit.  Not all entries in the
array are mapped and this is tracked in kmap_mask.

kunmap_local() takes a mapped address rather than a page.  Alter
siw_unmap_pages() to take the iov array to reuse the iov_base address of
each mapping.  Use PAGE_MASK to get the proper address for
kunmap_local().

kmap_local_page() mappings are tracked in a stack and must be unmapped
in the opposite order they were mapped in.  Because segments are mapped
into the page array in increasing index order, modify siw_unmap_pages()
to unmap pages in decreasing order.

Use kmap_local_page() instead of kmap() to map pages in the page_array.

[1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/

Signed-off-by: Ira Weiny <ira.weiny@intel.com>

---
Changes for V4:
	From Bernard
		Further optimize siw_unmap_pages() by eliminating the
		CRC page from the iov array.

Changes for V3:
	From Bernard
		Use 'p' in kmap_local_page()
		Use seg as length to siw_unmap_pages()

Changes for V2:
	From Bernard
		Reuse iov[].iov_base rather than declaring another array
		of pointers and preserve the use of kmap_mask to know
		which iov's were kmapped.
---
 drivers/infiniband/sw/siw/siw_qp_tx.c | 30 +++++++++++++++++----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c
index db68a10d12cd..1f4e60257700 100644
--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
+++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
@@ -396,13 +396,20 @@ static int siw_0copy_tx(struct socket *s, struct page **page,
 
 #define MAX_TRAILER (MPA_CRC_SIZE + 4)
 
-static void siw_unmap_pages(struct page **pp, unsigned long kmap_mask)
+static void siw_unmap_pages(struct kvec *iov, unsigned long kmap_mask, int len)
 {
-	while (kmap_mask) {
-		if (kmap_mask & BIT(0))
-			kunmap(*pp);
-		pp++;
-		kmap_mask >>= 1;
+	int i;
+
+	/*
+	 * Work backwards through the array to honor the kmap_local_page()
+	 * ordering requirements.
+	 */
+	for (i = (len-1); i >= 0; i--) {
+		if (kmap_mask & BIT(i)) {
+			unsigned long addr = (unsigned long)iov[i].iov_base;
+
+			kunmap_local((void *)(addr & PAGE_MASK));
+		}
 	}
 }
 
@@ -498,7 +505,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 					p = siw_get_upage(mem->umem,
 							  sge->laddr + sge_off);
 				if (unlikely(!p)) {
-					siw_unmap_pages(page_array, kmap_mask);
+					siw_unmap_pages(iov, kmap_mask, seg);
 					wqe->processed -= c_tx->bytes_unsent;
 					rv = -EFAULT;
 					goto done_crc;
@@ -506,11 +513,12 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 				page_array[seg] = p;
 
 				if (!c_tx->use_sendpage) {
-					iov[seg].iov_base = kmap(p) + fp_off;
-					iov[seg].iov_len = plen;
+					void *kaddr = kmap_local_page(p);
 
 					/* Remember for later kunmap() */
 					kmap_mask |= BIT(seg);
+					iov[seg].iov_base = kaddr + fp_off;
+					iov[seg].iov_len = plen;
 
 					if (do_crc)
 						crypto_shash_update(
@@ -542,7 +550,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 
 			if (++seg > (int)MAX_ARRAY) {
 				siw_dbg_qp(tx_qp(c_tx), "to many fragments\n");
-				siw_unmap_pages(page_array, kmap_mask);
+				siw_unmap_pages(iov, kmap_mask, seg-1);
 				wqe->processed -= c_tx->bytes_unsent;
 				rv = -EMSGSIZE;
 				goto done_crc;
@@ -593,7 +601,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
 	} else {
 		rv = kernel_sendmsg(s, &msg, iov, seg + 1,
 				    hdr_len + data_len + trl_len);
-		siw_unmap_pages(page_array, kmap_mask);
+		siw_unmap_pages(iov, kmap_mask, seg);
 	}
 	if (rv < (int)hdr_len) {
 		/* Not even complete hdr pushed or negative rv */
-- 
2.28.0.rc0.12.gb6a658bd00c9


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 1/4] RDMA/hfi1: Remove use of kmap()
  2021-06-22  6:14 ` [PATCH 1/4] RDMA/hfi1: " ira.weiny
@ 2021-06-24 18:13   ` Jason Gunthorpe
  0 siblings, 0 replies; 22+ messages in thread
From: Jason Gunthorpe @ 2021-06-24 18:13 UTC (permalink / raw)
  To: ira.weiny
  Cc: Mike Marciniszyn, Dennis Dalessandro, Doug Ledford, Faisal Latif,
	Shiraz Saleem, Bernard Metzler, Kamal Heib, linux-rdma,
	linux-kernel

On Mon, Jun 21, 2021 at 11:14:19PM -0700, ira.weiny@intel.com wrote:
> From: Ira Weiny <ira.weiny@intel.com>
> 
> kmap() is being deprecated and will break uses of device dax after PKS
> protection is introduced.[1]
> 
> The kmap() used in sdma does not need to be global.  Use the new
> kmap_local_page() which works with PKS and may provide better
> performance for this thread local mapping anyway.
> 
> [1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/
> 
> Signed-off-by: Ira Weiny <ira.weiny@intel.com>
> ---
>  drivers/infiniband/hw/hfi1/sdma.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Applied to for-next, thanks

Jason

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V2] RDMA/irdma: Remove use of kmap()
  2021-06-22 16:56   ` [PATCH V2] RDMA/irdma: " ira.weiny
@ 2021-06-24 18:13     ` Jason Gunthorpe
  0 siblings, 0 replies; 22+ messages in thread
From: Jason Gunthorpe @ 2021-06-24 18:13 UTC (permalink / raw)
  To: ira.weiny
  Cc: Mike Marciniszyn, Dennis Dalessandro, Doug Ledford, Faisal Latif,
	Shiraz Saleem, Bernard Metzler, Kamal Heib, linux-rdma,
	linux-kernel

On Tue, Jun 22, 2021 at 09:56:22AM -0700, ira.weiny@intel.com wrote:
> From: Ira Weiny <ira.weiny@intel.com>
> 
> kmap() is being deprecated and will break uses of device dax after PKS
> protection is introduced.[1]
> 
> The kmap() used in the irdma CM driver is thread local.  Therefore
> kmap_local_page() is sufficient to use and may provide performance benefits
> as well.  kmap_local_page() will work with device dax and pgmap
> protected pages.
> 
> Use kmap_local_page() instead of kmap().
> 
> [1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/
> 
> Signed-off-by: Ira Weiny <ira.weiny@intel.com>
> ---
> Changes for V2:
> 	Move to the new irdma driver for 5.14
> ---
>  drivers/infiniband/hw/irdma/cm.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)

Applied to for-next, thanks

Jason

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V4] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page()
  2021-06-23 22:15     ` [PATCH V3] " ira.weiny
  2021-06-24 17:48       ` [PATCH V4] " ira.weiny
@ 2021-06-29 14:11       ` Bernard Metzler
  2021-06-29 22:13         ` Ira Weiny
  1 sibling, 1 reply; 22+ messages in thread
From: Bernard Metzler @ 2021-06-29 14:11 UTC (permalink / raw)
  To: ira.weiny
  Cc: Jason Gunthorpe, Mike Marciniszyn, Dennis Dalessandro,
	Doug Ledford, Faisal Latif, Shiraz Saleem, Kamal Heib,
	linux-rdma, linux-kernel

-----ira.weiny@intel.com wrote: -----

>To: "Jason Gunthorpe" <jgg@ziepe.ca>
>From: ira.weiny@intel.com
>Date: 06/24/2021 07:48PM
>Cc: "Ira Weiny" <ira.weiny@intel.com>, "Mike Marciniszyn"
><mike.marciniszyn@cornelisnetworks.com>, "Dennis Dalessandro"
><dennis.dalessandro@cornelisnetworks.com>, "Doug Ledford"
><dledford@redhat.com>, "Faisal Latif" <faisal.latif@intel.com>,
>"Shiraz Saleem" <shiraz.saleem@intel.com>, "Bernard Metzler"
><bmt@zurich.ibm.com>, "Kamal Heib" <kheib@redhat.com>,
>linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org
>Subject: [EXTERNAL] [PATCH V4] RDMA/siw: Convert siw_tx_hdt() to
>kmap_local_page()
>
>From: Ira Weiny <ira.weiny@intel.com>
>
>kmap() is being deprecated and will break uses of device dax after
>PKS
>protection is introduced.[1]
>
>The use of kmap() in siw_tx_hdt() is all thread local therefore
>kmap_local_page() is a sufficient replacement and will work with
>pgmap
>protected pages when those are implemented.
>
>siw_tx_hdt() tracks pages used in a page_array.  It uses that array
>to
>unmap pages which were mapped on function exit.  Not all entries in
>the
>array are mapped and this is tracked in kmap_mask.
>
>kunmap_local() takes a mapped address rather than a page.  Alter
>siw_unmap_pages() to take the iov array to reuse the iov_base address
>of
>each mapping.  Use PAGE_MASK to get the proper address for
>kunmap_local().
>
>kmap_local_page() mappings are tracked in a stack and must be
>unmapped
>in the opposite order they were mapped in.  Because segments are
>mapped
>into the page array in increasing index order, modify
>siw_unmap_pages()
>to unmap pages in decreasing order.
>
>Use kmap_local_page() instead of kmap() to map pages in the
>page_array.
>
>[1]
>INVALID URI REMOVED
>lkml_20201009195033.3208459-2D59-2Dira.weiny-40intel.com_&d=DwIDAg&c=
>jf_iaSHvJObTbx-siA1ZOg&r=2TaYXQ0T-r8ZO1PP1alNwU_QJcRRLfmYTAgd3QCvqSc&
>m=01QnZvj05j7vvgDChewVpHJlDytiIFuttai7VRUdJMs&s=zS4nDlvF_3MDi9wu7GaL6
>qooDhiboqP5ii5ozBeDpLE&e= 
>
>Signed-off-by: Ira Weiny <ira.weiny@intel.com>
>
>---
>Changes for V4:
>	From Bernard
>		Further optimize siw_unmap_pages() by eliminating the
>		CRC page from the iov array.
>
>Changes for V3:
>	From Bernard
>		Use 'p' in kmap_local_page()
>		Use seg as length to siw_unmap_pages()
>
>Changes for V2:
>	From Bernard
>		Reuse iov[].iov_base rather than declaring another array
>		of pointers and preserve the use of kmap_mask to know
>		which iov's were kmapped.
>---
> drivers/infiniband/sw/siw/siw_qp_tx.c | 30
>+++++++++++++++++----------
> 1 file changed, 19 insertions(+), 11 deletions(-)
>
>diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c
>b/drivers/infiniband/sw/siw/siw_qp_tx.c
>index db68a10d12cd..1f4e60257700 100644
>--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
>+++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
>@@ -396,13 +396,20 @@ static int siw_0copy_tx(struct socket *s,
>struct page **page,
> 
> #define MAX_TRAILER (MPA_CRC_SIZE + 4)
> 
>-static void siw_unmap_pages(struct page **pp, unsigned long
>kmap_mask)
>+static void siw_unmap_pages(struct kvec *iov, unsigned long
>kmap_mask, int len)
> {
>-	while (kmap_mask) {
>-		if (kmap_mask & BIT(0))
>-			kunmap(*pp);
>-		pp++;
>-		kmap_mask >>= 1;
>+	int i;
>+
>+	/*
>+	 * Work backwards through the array to honor the kmap_local_page()
>+	 * ordering requirements.
>+	 */
>+	for (i = (len-1); i >= 0; i--) {
>+		if (kmap_mask & BIT(i)) {
>+			unsigned long addr = (unsigned long)iov[i].iov_base;
>+
>+			kunmap_local((void *)(addr & PAGE_MASK));
>+		}
> 	}
> }
> 
>@@ -498,7 +505,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
>struct socket *s)
> 					p = siw_get_upage(mem->umem,
> 							  sge->laddr + sge_off);
> 				if (unlikely(!p)) {
>-					siw_unmap_pages(page_array, kmap_mask);
>+					siw_unmap_pages(iov, kmap_mask, seg);
> 					wqe->processed -= c_tx->bytes_unsent;
> 					rv = -EFAULT;
> 					goto done_crc;
>@@ -506,11 +513,12 @@ static int siw_tx_hdt(struct siw_iwarp_tx
>*c_tx, struct socket *s)
> 				page_array[seg] = p;
> 
> 				if (!c_tx->use_sendpage) {
>-					iov[seg].iov_base = kmap(p) + fp_off;
>-					iov[seg].iov_len = plen;
>+					void *kaddr = kmap_local_page(p);
> 
> 					/* Remember for later kunmap() */
> 					kmap_mask |= BIT(seg);
>+					iov[seg].iov_base = kaddr + fp_off;
>+					iov[seg].iov_len = plen;
> 
> 					if (do_crc)
> 						crypto_shash_update(
>@@ -542,7 +550,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
>struct socket *s)
> 
> 			if (++seg > (int)MAX_ARRAY) {
> 				siw_dbg_qp(tx_qp(c_tx), "to many fragments\n");
>-				siw_unmap_pages(page_array, kmap_mask);
>+				siw_unmap_pages(iov, kmap_mask, seg-1);
> 				wqe->processed -= c_tx->bytes_unsent;
> 				rv = -EMSGSIZE;
> 				goto done_crc;
>@@ -593,7 +601,7 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx,
>struct socket *s)
> 	} else {
> 		rv = kernel_sendmsg(s, &msg, iov, seg + 1,
> 				    hdr_len + data_len + trl_len);
>-		siw_unmap_pages(page_array, kmap_mask);
>+		siw_unmap_pages(iov, kmap_mask, seg);
> 	}
> 	if (rv < (int)hdr_len) {
> 		/* Not even complete hdr pushed or negative rv */
>-- 
>2.28.0.rc0.12.gb6a658bd00c9
>
>
Sry my misconfigured email attached some HTML crap. So I did not
reach the list.

Tested V4 which works as intended. Thanks, Ira!

Reviewed-by: Bernard Metzler <bmt@zurich.ibm.com>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V4] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page()
  2021-06-29 14:11       ` Bernard Metzler
@ 2021-06-29 22:13         ` Ira Weiny
  0 siblings, 0 replies; 22+ messages in thread
From: Ira Weiny @ 2021-06-29 22:13 UTC (permalink / raw)
  To: Bernard Metzler
  Cc: Jason Gunthorpe, Mike Marciniszyn, Dennis Dalessandro,
	Doug Ledford, Faisal Latif, Shiraz Saleem, Kamal Heib,
	linux-rdma, linux-kernel

> >
> Sry my misconfigured email attached some HTML crap. So I did not
> reach the list.

NP...

> 
> Tested V4 which works as intended. Thanks, Ira!
> 
> Reviewed-by: Bernard Metzler <bmt@zurich.ibm.com>

Thanks!
Ira


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 3/4] RDMA/siw: Remove kmap()
  2021-06-22  6:14 ` [PATCH 3/4] RDMA/siw: Remove kmap() ira.weiny
@ 2021-07-15 18:00   ` Jason Gunthorpe
  0 siblings, 0 replies; 22+ messages in thread
From: Jason Gunthorpe @ 2021-07-15 18:00 UTC (permalink / raw)
  To: ira.weiny
  Cc: Mike Marciniszyn, Dennis Dalessandro, Doug Ledford, Faisal Latif,
	Shiraz Saleem, Bernard Metzler, Kamal Heib, linux-rdma,
	linux-kernel

On Mon, Jun 21, 2021 at 11:14:21PM -0700, ira.weiny@intel.com wrote:
> From: Ira Weiny <ira.weiny@intel.com>
> 
> kmap() is being deprecated and will break uses of device dax after PKS
> protection is introduced.[1]
> 
> These uses of kmap() in the SIW driver are thread local.  Therefore
> kmap_local_page() is sufficient to use and will work with pgmap
> protected pages when those are implemnted.
> 
> There is one more use of kmap() in this driver which is split into its
> own patch because kmap_local_page() has strict ordering rules and the
> use of the kmap_mask over multiple segments must be handled carefully.
> Therefore, that conversion is handled in a stand alone patch.
> 
> Use kmap_local_page() instead of kmap() in the 'easy' cases.
> 
> [1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/
> 
> Signed-off-by: Ira Weiny <ira.weiny@intel.com>
> ---
>  drivers/infiniband/sw/siw/siw_qp_tx.c | 14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)

Applied to for-next, thanks

Jason

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH V4] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page()
  2021-06-24 17:48       ` [PATCH V4] " ira.weiny
@ 2021-07-15 18:00         ` Jason Gunthorpe
  0 siblings, 0 replies; 22+ messages in thread
From: Jason Gunthorpe @ 2021-07-15 18:00 UTC (permalink / raw)
  To: ira.weiny
  Cc: Mike Marciniszyn, Dennis Dalessandro, Doug Ledford, Faisal Latif,
	Shiraz Saleem, Bernard Metzler, Kamal Heib, linux-rdma,
	linux-kernel

On Thu, Jun 24, 2021 at 10:48:14AM -0700, ira.weiny@intel.com wrote:
> From: Ira Weiny <ira.weiny@intel.com>
> 
> kmap() is being deprecated and will break uses of device dax after PKS
> protection is introduced.[1]
> 
> The use of kmap() in siw_tx_hdt() is all thread local therefore
> kmap_local_page() is a sufficient replacement and will work with pgmap
> protected pages when those are implemented.
> 
> siw_tx_hdt() tracks pages used in a page_array.  It uses that array to
> unmap pages which were mapped on function exit.  Not all entries in the
> array are mapped and this is tracked in kmap_mask.
> 
> kunmap_local() takes a mapped address rather than a page.  Alter
> siw_unmap_pages() to take the iov array to reuse the iov_base address of
> each mapping.  Use PAGE_MASK to get the proper address for
> kunmap_local().
> 
> kmap_local_page() mappings are tracked in a stack and must be unmapped
> in the opposite order they were mapped in.  Because segments are mapped
> into the page array in increasing index order, modify siw_unmap_pages()
> to unmap pages in decreasing order.
> 
> Use kmap_local_page() instead of kmap() to map pages in the page_array.
> 
> [1] https://lore.kernel.org/lkml/20201009195033.3208459-59-ira.weiny@intel.com/
> 
> Signed-off-by: Ira Weiny <ira.weiny@intel.com>
> Reviewed-by: Bernard Metzler <bmt@zurich.ibm.com>
> ---
> Changes for V4:
> 	From Bernard
> 		Further optimize siw_unmap_pages() by eliminating the
> 		CRC page from the iov array.
> 
> Changes for V3:
> 	From Bernard
> 		Use 'p' in kmap_local_page()
> 		Use seg as length to siw_unmap_pages()
> 
> Changes for V2:
> 	From Bernard
> 		Reuse iov[].iov_base rather than declaring another array
> 		of pointers and preserve the use of kmap_mask to know
> 		which iov's were kmapped.
> ---
>  drivers/infiniband/sw/siw/siw_qp_tx.c | 30 +++++++++++++++++----------
>  1 file changed, 19 insertions(+), 11 deletions(-)

Applied to for-next, thanks

Jason 

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2021-07-15 18:01 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-22  6:14 [PATCH 0/4] Remove use of kmap() ira.weiny
2021-06-22  6:14 ` [PATCH 1/4] RDMA/hfi1: " ira.weiny
2021-06-24 18:13   ` Jason Gunthorpe
2021-06-22  6:14 ` [PATCH 2/4] RDMA/i40iw: " ira.weiny
2021-06-22 12:14   ` Jason Gunthorpe
2021-06-22 16:56   ` [PATCH V2] RDMA/irdma: " ira.weiny
2021-06-24 18:13     ` Jason Gunthorpe
2021-06-22  6:14 ` [PATCH 3/4] RDMA/siw: Remove kmap() ira.weiny
2021-07-15 18:00   ` Jason Gunthorpe
2021-06-22  6:14 ` [PATCH 4/4] RDMA/siw: Convert siw_tx_hdt() to kmap_local_page() ira.weiny
2021-06-22 20:34   ` [PATCH V2] " ira.weiny
2021-06-23 22:15     ` [PATCH V3] " ira.weiny
2021-06-24 17:48       ` [PATCH V4] " ira.weiny
2021-07-15 18:00         ` Jason Gunthorpe
2021-06-29 14:11       ` Bernard Metzler
2021-06-29 22:13         ` Ira Weiny
2021-06-24 15:45     ` [PATCH V3] " Bernard Metzler
2021-06-24 17:33       ` Ira Weiny
2021-06-23 14:36   ` [PATCH V2] " Bernard Metzler
2021-06-23 15:34     ` Ira Weiny
2021-06-22 16:42 ` [PATCH 4/4] " Bernard Metzler
2021-06-22 20:39   ` Ira Weiny

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).