Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1623387 > unrolled thread

[PATCH 00/22] Introduce common scatterlist map function

Started byLogan Gunthorpe <logang@deltatee.com>
First post2017-04-14 00:20 +0200
Last post2017-04-18 17:50 +0200
Articles 20 on this page of 26 — 6 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 00/22] Introduce common scatterlist map function Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 00:20 +0200
    [PATCH 18/22] mmc: spi: Make use of the new sg_map helper function Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 00:20 +0200
    [PATCH 06/22] crypto: hifn_795x: Make use of the new sg_map helper function Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 00:20 +0200
    [PATCH 04/22] target: Make use of the new sg_map function at 16 call sites Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 00:20 +0200
    [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper function Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 00:20 +0200
      RE: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper  function David Laight <David.Laight@ACULAB.COM> - 2017-04-18 16:20 +0200
        Re: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper  function Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> - 2017-04-18 16:40 +0200
          Re: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper  function Logan Gunthorpe <logang@deltatee.com> - 2017-04-18 17:50 +0200
            Re: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper  function Logan Gunthorpe <logang@deltatee.com> - 2017-04-18 18:00 +0200
            Re: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper  function Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> - 2017-04-18 18:00 +0200
    [PATCH 10/22] staging: unisys: visorbus: Make use of the new sg_map helper function Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 00:20 +0200
      RE: [PATCH 10/22] staging: unisys: visorbus: Make use of the new  sg_map helper function "Kershner, David A" <David.Kershner@unisys.com> - 2017-04-14 18:10 +0200
        Re: [PATCH 10/22] staging: unisys: visorbus: Make use of the new  sg_map helper function Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 18:20 +0200
    [PATCH 07/22] crypto: shash, caam: Make use of the new sg_map helper function Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 00:20 +0200
    [PATCH 12/22] scsi: ipr, pmcraid, isci: Make use of the new sg_map helper in 4 call sites Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 00:20 +0200
    [PATCH 15/22] scsi: libfc, csiostor: Change to sg_copy_buffer in two drivers Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 00:20 +0200
    [PATCH 17/22] mmc: sdhci: Make use of the new sg_map helper function Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 00:20 +0200
    [PATCH 22/22] memstick: Make use of the new sg_map helper function Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 00:20 +0200
    [PATCH 19/22] mmc: tmio: Make use of the new sg_map helper function Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 00:20 +0200
    [PATCH 02/22] nvmet: Make use of the new sg_map helper function Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 00:20 +0200
      Re: [PATCH 02/22] nvmet: Make use of the new sg_map helper function Christoph Hellwig <hch@lst.de> - 2017-04-14 07:10 +0200
        Re: [PATCH 02/22] nvmet: Make use of the new sg_map helper function Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 07:10 +0200
          Re: [PATCH 02/22] nvmet: Make use of the new sg_map helper function Christoph Hellwig <hch@lst.de> - 2017-04-14 07:20 +0200
    [PATCH 05/22] drm/i915: Make use of the new sg_map helper function Logan Gunthorpe <logang@deltatee.com> - 2017-04-14 00:20 +0200
      Re: [PATCH 05/22] drm/i915: Make use of the new sg_map helper  function Daniel Vetter <daniel@ffwll.ch> - 2017-04-18 08:50 +0200
        Re: [PATCH 05/22] drm/i915: Make use of the new sg_map helper  function Logan Gunthorpe <logang@deltatee.com> - 2017-04-18 17:50 +0200

Page 1 of 2  [1] 2  Next page →


#1623387 — [PATCH 00/22] Introduce common scatterlist map function

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-14 00:20 +0200
Subject[PATCH 00/22] Introduce common scatterlist map function
Message-ID<tvV69-P8-5@gated-at.bofh.it>
Hi Everyone,

As part of my effort to enable P2P DMA transactions with PCI cards,
we've identified the need to be able to safely put IO memory into
scatterlists (and eventually other spots). This probably involves a
conversion from struct page to pfn_t but that migration is a ways off
and those decisions are yet to be made.

As an initial step in that direction, I've started cleaning up some of the
scatterlist code by trying to carve out a better defined layer between it
and it's users. The longer term goal would be to remove sg_page or replace
it with something that can potentially fail.

This patchset is the first step in that effort. I've introduced
a common function to map scatterlist memory and converted all the common
kmap(sg_page()) cases. This removes about 66 sg_page calls (of ~331).

Seeing this is a fairly large cleanup set that touches a wide swath of
the kernel I have limited the people I've sent this to. I'd suggest we look
toward merging the first patch and then I can send the individual subsystem
patches on to their respective maintainers and get them merged
independantly. (This is to avoid the conflicts I created with my last
cleanup set... Sorry) Though, I'm certainly open to other suggestions to get
it merged.

The patchset is based on v4.11-rc6 and can be found in the sg_map
branch from this git tree:

https://github.com/sbates130272/linux-p2pmem.git

Thanks,

Logan


Logan Gunthorpe (22):
  scatterlist: Introduce sg_map helper functions
  nvmet: Make use of the new sg_map helper function
  libiscsi: Make use of new the sg_map helper function
  target: Make use of the new sg_map function at 16 call sites
  drm/i915: Make use of the new sg_map helper function
  crypto: hifn_795x: Make use of the new sg_map helper function
  crypto: shash, caam: Make use of the new sg_map helper function
  crypto: chcr: Make use of the new sg_map helper function
  dm-crypt: Make use of the new sg_map helper in 4 call sites
  staging: unisys: visorbus: Make use of the new sg_map helper function
  RDS: Make use of the new sg_map helper function
  scsi: ipr, pmcraid, isci: Make use of the new sg_map helper in 4 call
    sites
  scsi: hisi_sas, mvsas, gdth: Make use of the new sg_map helper
    function
  scsi: arcmsr, ips, megaraid: Make use of the new sg_map helper
    function
  scsi: libfc, csiostor: Change to sg_copy_buffer in two drivers
  xen-blkfront: Make use of the new sg_map helper function
  mmc: sdhci: Make use of the new sg_map helper function
  mmc: spi: Make use of the new sg_map helper function
  mmc: tmio: Make use of the new sg_map helper function
  mmc: sdricoh_cs: Make use of the new sg_map helper function
  mmc: tifm_sd: Make use of the new sg_map helper function
  memstick: Make use of the new sg_map helper function

 crypto/shash.c                                  |   9 +-
 drivers/block/xen-blkfront.c                    |  33 +++++--
 drivers/crypto/caam/caamalg.c                   |   8 +-
 drivers/crypto/chelsio/chcr_algo.c              |  28 +++---
 drivers/crypto/hifn_795x.c                      |  32 ++++---
 drivers/dma-buf/dma-buf.c                       |   3 +
 drivers/gpu/drm/i915/i915_gem.c                 |  27 +++---
 drivers/md/dm-crypt.c                           |  38 +++++---
 drivers/memstick/host/jmb38x_ms.c               |  23 ++++-
 drivers/memstick/host/tifm_ms.c                 |  22 ++++-
 drivers/mmc/host/mmc_spi.c                      |  26 +++--
 drivers/mmc/host/sdhci.c                        |  35 ++++++-
 drivers/mmc/host/sdricoh_cs.c                   |  14 ++-
 drivers/mmc/host/tifm_sd.c                      |  88 +++++++++++++----
 drivers/mmc/host/tmio_mmc.h                     |  12 ++-
 drivers/mmc/host/tmio_mmc_dma.c                 |   5 +
 drivers/mmc/host/tmio_mmc_pio.c                 |  24 +++++
 drivers/nvme/target/fabrics-cmd.c               |  16 +++-
 drivers/scsi/arcmsr/arcmsr_hba.c                |  16 +++-
 drivers/scsi/csiostor/csio_scsi.c               |  54 +----------
 drivers/scsi/cxgbi/libcxgbi.c                   |   5 +
 drivers/scsi/gdth.c                             |   9 +-
 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c          |  14 ++-
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c          |  13 ++-
 drivers/scsi/ipr.c                              |  27 +++---
 drivers/scsi/ips.c                              |   8 +-
 drivers/scsi/isci/request.c                     |  42 ++++----
 drivers/scsi/libfc/fc_libfc.c                   |  49 ++--------
 drivers/scsi/libiscsi_tcp.c                     |  32 ++++---
 drivers/scsi/megaraid.c                         |   9 +-
 drivers/scsi/mvsas/mv_sas.c                     |  10 +-
 drivers/scsi/pmcraid.c                          |  19 ++--
 drivers/staging/unisys/visorhba/visorhba_main.c |  12 ++-
 drivers/target/iscsi/iscsi_target.c             |  27 ++++--
 drivers/target/target_core_rd.c                 |   3 +-
 drivers/target/target_core_sbc.c                | 122 +++++++++++++++++-------
 drivers/target/target_core_transport.c          |  18 ++--
 drivers/target/target_core_user.c               |  43 ++++++---
 include/linux/scatterlist.h                     |  97 +++++++++++++++++++
 include/scsi/libiscsi_tcp.h                     |   3 +-
 include/target/target_core_backend.h            |   4 +-
 net/rds/ib_recv.c                               |  17 +++-
 42 files changed, 739 insertions(+), 357 deletions(-)

--
2.1.4

[toc] | [next] | [standalone]


#1623388 — [PATCH 18/22] mmc: spi: Make use of the new sg_map helper function

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-14 00:20 +0200
Subject[PATCH 18/22] mmc: spi: Make use of the new sg_map helper function
Message-ID<tvVfP-Tr-5@gated-at.bofh.it>
In reply to#1623387
We use the sg_map helper but it's slightly more complicated
as we only check for the error when the mapping actually gets used.
Such that if the mapping failed but wasn't needed then no
error occurs.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/mmc/host/mmc_spi.c | 26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index e77d79c..82f786d 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -676,9 +676,15 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
 	struct scratch		*scratch = host->data;
 	u32			pattern;
 
-	if (host->mmc->use_spi_crc)
+	if (host->mmc->use_spi_crc) {
+		if (IS_ERR(t->tx_buf))
+			return PTR_ERR(t->tx_buf);
+
 		scratch->crc_val = cpu_to_be16(
 				crc_itu_t(0, t->tx_buf, t->len));
+		t->tx_buf += t->len;
+	}
+
 	if (host->dma_dev)
 		dma_sync_single_for_device(host->dma_dev,
 				host->data_dma, sizeof(*scratch),
@@ -743,7 +749,6 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
 		return status;
 	}
 
-	t->tx_buf += t->len;
 	if (host->dma_dev)
 		t->tx_dma += t->len;
 
@@ -809,6 +814,11 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
 	}
 	leftover = status << 1;
 
+	if (bitshift || host->mmc->use_spi_crc) {
+		if (IS_ERR(t->rx_buf))
+			return PTR_ERR(t->rx_buf);
+	}
+
 	if (host->dma_dev) {
 		dma_sync_single_for_device(host->dma_dev,
 				host->data_dma, sizeof(*scratch),
@@ -860,9 +870,10 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
 					scratch->crc_val, crc, t->len);
 			return -EILSEQ;
 		}
+
+		t->rx_buf += t->len;
 	}
 
-	t->rx_buf += t->len;
 	if (host->dma_dev)
 		t->rx_dma += t->len;
 
@@ -936,11 +947,11 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 		}
 
 		/* allow pio too; we don't allow highmem */
-		kmap_addr = kmap(sg_page(sg));
+		kmap_addr = sg_map(sg, SG_KMAP);
 		if (direction == DMA_TO_DEVICE)
-			t->tx_buf = kmap_addr + sg->offset;
+			t->tx_buf = kmap_addr;
 		else
-			t->rx_buf = kmap_addr + sg->offset;
+			t->rx_buf = kmap_addr;
 
 		/* transfer each block, and update request status */
 		while (length) {
@@ -970,7 +981,8 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
 		/* discard mappings */
 		if (direction == DMA_FROM_DEVICE)
 			flush_kernel_dcache_page(sg_page(sg));
-		kunmap(sg_page(sg));
+		if (!IS_ERR(kmap_addr))
+			sg_unmap(sg, kmap_addr, SG_KMAP);
 		if (dma_dev)
 			dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
 
-- 
2.1.4

[toc] | [prev] | [next] | [standalone]


#1623389 — [PATCH 06/22] crypto: hifn_795x: Make use of the new sg_map helper function

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-14 00:20 +0200
Subject[PATCH 06/22] crypto: hifn_795x: Make use of the new sg_map helper function
Message-ID<tvVfQ-Tr-11@gated-at.bofh.it>
In reply to#1623387
Conversion of a couple kmap_atomic instances to the sg_map helper
function.

However, it looks like there was a bug in the original code: the source
scatter lists offset (t->offset) was passed to ablkcipher_get which
added it to the destination address. This doesn't make a lot of
sense, but t->offset is likely always zero anyway. So, this patch cleans
that brokeness up.

Also, a change to the error path: if ablkcipher_get failed, everything
seemed to proceed as if it hadn't. Setting 'error' should hopefully
clear that up.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/crypto/hifn_795x.c | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index e09d405..8e2c6a9 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -1619,7 +1619,7 @@ static int hifn_start_device(struct hifn_device *dev)
 	return 0;
 }
 
-static int ablkcipher_get(void *saddr, unsigned int *srestp, unsigned int offset,
+static int ablkcipher_get(void *saddr, unsigned int *srestp,
 		struct scatterlist *dst, unsigned int size, unsigned int *nbytesp)
 {
 	unsigned int srest = *srestp, nbytes = *nbytesp, copy;
@@ -1632,15 +1632,17 @@ static int ablkcipher_get(void *saddr, unsigned int *srestp, unsigned int offset
 	while (size) {
 		copy = min3(srest, dst->length, size);
 
-		daddr = kmap_atomic(sg_page(dst));
-		memcpy(daddr + dst->offset + offset, saddr, copy);
-		kunmap_atomic(daddr);
+		daddr = sg_map(dst, SG_KMAP_ATOMIC);
+		if (IS_ERR(daddr))
+			return PTR_ERR(daddr);
+
+		memcpy(daddr, saddr, copy);
+		sg_unmap(dst, daddr, SG_KMAP_ATOMIC);
 
 		nbytes -= copy;
 		size -= copy;
 		srest -= copy;
 		saddr += copy;
-		offset = 0;
 
 		pr_debug("%s: copy: %u, size: %u, srest: %u, nbytes: %u.\n",
 			 __func__, copy, size, srest, nbytes);
@@ -1671,11 +1673,12 @@ static inline void hifn_complete_sa(struct hifn_device *dev, int i)
 
 static void hifn_process_ready(struct ablkcipher_request *req, int error)
 {
+	int err;
 	struct hifn_request_context *rctx = ablkcipher_request_ctx(req);
 
 	if (rctx->walk.flags & ASYNC_FLAGS_MISALIGNED) {
 		unsigned int nbytes = req->nbytes;
-		int idx = 0, err;
+		int idx = 0;
 		struct scatterlist *dst, *t;
 		void *saddr;
 
@@ -1695,17 +1698,24 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error)
 				continue;
 			}
 
-			saddr = kmap_atomic(sg_page(t));
+			saddr = sg_map(t, SG_KMAP_ATOMIC);
+			if (IS_ERR(saddr)) {
+				if (!error)
+					error = PTR_ERR(saddr);
+				break;
+			}
+
+			err = ablkcipher_get(saddr, &t->length,
+					     dst, nbytes, &nbytes);
+			sg_unmap(t, saddr, SG_KMAP_ATOMIC);
 
-			err = ablkcipher_get(saddr, &t->length, t->offset,
-					dst, nbytes, &nbytes);
 			if (err < 0) {
-				kunmap_atomic(saddr);
+				if (!error)
+					error = err;
 				break;
 			}
 
 			idx += err;
-			kunmap_atomic(saddr);
 		}
 
 		hifn_cipher_walk_exit(&rctx->walk);
-- 
2.1.4

[toc] | [prev] | [next] | [standalone]


#1623390 — [PATCH 04/22] target: Make use of the new sg_map function at 16 call sites

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-14 00:20 +0200
Subject[PATCH 04/22] target: Make use of the new sg_map function at 16 call sites
Message-ID<tvVfQ-Tr-13@gated-at.bofh.it>
In reply to#1623387
Fairly straightforward conversions in all spots. In a couple of cases
any error gets propogated up should sg_map fail. In other
cases a warning is issued if the kmap fails seeing there's no
clear error path. This should not be an issue until someone tries to
use unmappable memory in the sgl with this driver.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/target/iscsi/iscsi_target.c    |  27 +++++---
 drivers/target/target_core_rd.c        |   3 +-
 drivers/target/target_core_sbc.c       | 122 +++++++++++++++++++++++----------
 drivers/target/target_core_transport.c |  18 +++--
 drivers/target/target_core_user.c      |  43 ++++++++----
 include/target/target_core_backend.h   |   4 +-
 6 files changed, 149 insertions(+), 68 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index a918024..e3e0d8f 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -579,7 +579,7 @@ iscsit_xmit_nondatain_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
 }
 
 static int iscsit_map_iovec(struct iscsi_cmd *, struct kvec *, u32, u32);
-static void iscsit_unmap_iovec(struct iscsi_cmd *);
+static void iscsit_unmap_iovec(struct iscsi_cmd *, struct kvec *);
 static u32 iscsit_do_crypto_hash_sg(struct ahash_request *, struct iscsi_cmd *,
 				    u32, u32, u32, u8 *);
 static int
@@ -646,7 +646,7 @@ iscsit_xmit_datain_pdu(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
 
 	ret = iscsit_fe_sendpage_sg(cmd, conn);
 
-	iscsit_unmap_iovec(cmd);
+	iscsit_unmap_iovec(cmd, &cmd->iov_data[1]);
 
 	if (ret < 0) {
 		iscsit_tx_thread_wait_for_tcp(conn);
@@ -925,7 +925,10 @@ static int iscsit_map_iovec(
 	while (data_length) {
 		u32 cur_len = min_t(u32, data_length, sg->length - page_off);
 
-		iov[i].iov_base = kmap(sg_page(sg)) + sg->offset + page_off;
+		iov[i].iov_base = sg_map_offset(sg, page_off, SG_KMAP);
+		if (IS_ERR(iov[i].iov_base))
+			goto map_err;
+
 		iov[i].iov_len = cur_len;
 
 		data_length -= cur_len;
@@ -937,17 +940,25 @@ static int iscsit_map_iovec(
 	cmd->kmapped_nents = i;
 
 	return i;
+
+map_err:
+	cmd->kmapped_nents = i - 1;
+	iscsit_unmap_iovec(cmd, iov);
+	return -1;
 }
 
-static void iscsit_unmap_iovec(struct iscsi_cmd *cmd)
+static void iscsit_unmap_iovec(struct iscsi_cmd *cmd, struct kvec *iov)
 {
 	u32 i;
 	struct scatterlist *sg;
+	unsigned int page_off = cmd->first_data_sg_off;
 
 	sg = cmd->first_data_sg;
 
-	for (i = 0; i < cmd->kmapped_nents; i++)
-		kunmap(sg_page(&sg[i]));
+	for (i = 0; i < cmd->kmapped_nents; i++) {
+		sg_unmap_offset(&sg[i], iov[i].iov_base, page_off, SG_KMAP);
+		page_off = 0;
+	}
 }
 
 static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn)
@@ -1610,7 +1621,7 @@ iscsit_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
 
 	rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size);
 
-	iscsit_unmap_iovec(cmd);
+	iscsit_unmap_iovec(cmd, iov);
 
 	if (rx_got != rx_size)
 		return -1;
@@ -2626,7 +2637,7 @@ static int iscsit_handle_immediate_data(
 
 	rx_got = rx_data(conn, &cmd->iov_data[0], iov_count, rx_size);
 
-	iscsit_unmap_iovec(cmd);
+	iscsit_unmap_iovec(cmd, cmd->iov_data);
 
 	if (rx_got != rx_size) {
 		iscsit_rx_thread_wait_for_tcp(conn);
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index ddc216c..22c5ad5 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -431,7 +431,8 @@ static sense_reason_t rd_do_prot_rw(struct se_cmd *cmd, bool is_read)
 				    cmd->t_prot_sg, 0);
 
 	if (!rc)
-		sbc_dif_copy_prot(cmd, sectors, is_read, prot_sg, prot_offset);
+		rc = sbc_dif_copy_prot(cmd, sectors, is_read, prot_sg,
+				       prot_offset);
 
 	return rc;
 }
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index c194063..67cb420 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -420,17 +420,17 @@ static sense_reason_t xdreadwrite_callback(struct se_cmd *cmd, bool success,
 
 	offset = 0;
 	for_each_sg(cmd->t_bidi_data_sg, sg, cmd->t_bidi_data_nents, count) {
-		addr = kmap_atomic(sg_page(sg));
-		if (!addr) {
+		addr = sg_map(sg, SG_KMAP_ATOMIC);
+		if (IS_ERR(addr)) {
 			ret = TCM_OUT_OF_RESOURCES;
 			goto out;
 		}
 
 		for (i = 0; i < sg->length; i++)
-			*(addr + sg->offset + i) ^= *(buf + offset + i);
+			*(addr + i) ^= *(buf + offset + i);
 
 		offset += sg->length;
-		kunmap_atomic(addr);
+		sg_unmap(sg, addr, SG_KMAP_ATOMIC);
 	}
 
 out:
@@ -541,8 +541,8 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool succes
 	 * Compare against SCSI READ payload against verify payload
 	 */
 	for_each_sg(cmd->t_bidi_data_sg, sg, cmd->t_bidi_data_nents, i) {
-		addr = (unsigned char *)kmap_atomic(sg_page(sg));
-		if (!addr) {
+		addr = sg_map(sg, SG_KMAP_ATOMIC);
+		if (IS_ERR(addr)) {
 			ret = TCM_OUT_OF_RESOURCES;
 			goto out;
 		}
@@ -552,10 +552,10 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool succes
 		if (memcmp(addr, buf + offset, len)) {
 			pr_warn("Detected MISCOMPARE for addr: %p buf: %p\n",
 				addr, buf + offset);
-			kunmap_atomic(addr);
+			sg_unmap(sg, addr, SG_KMAP_ATOMIC);
 			goto miscompare;
 		}
-		kunmap_atomic(addr);
+		sg_unmap(sg, addr, SG_KMAP_ATOMIC);
 
 		offset += len;
 		compare_len -= len;
@@ -1262,8 +1262,14 @@ sbc_dif_generate(struct se_cmd *cmd)
 	unsigned int block_size = dev->dev_attrib.block_size;
 
 	for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) {
-		paddr = kmap_atomic(sg_page(psg)) + psg->offset;
-		daddr = kmap_atomic(sg_page(dsg)) + dsg->offset;
+		paddr = sg_map(psg, SG_KMAP_ATOMIC);
+		if (IS_ERR(paddr))
+			goto sg_map_err;
+
+		daddr = sg_map(dsg, SG_KMAP_ATOMIC);
+		if (IS_ERR(daddr))
+			goto sg_map_err;
+
 
 		for (j = 0; j < psg->length;
 				j += sizeof(*sdt)) {
@@ -1272,26 +1278,32 @@ sbc_dif_generate(struct se_cmd *cmd)
 
 			if (offset >= dsg->length) {
 				offset -= dsg->length;
-				kunmap_atomic(daddr - dsg->offset);
+				sg_unmap(dsg, daddr, SG_KMAP_ATOMIC);
 				dsg = sg_next(dsg);
 				if (!dsg) {
-					kunmap_atomic(paddr - psg->offset);
+					sg_unmap(psg, paddr, SG_KMAP_ATOMIC);
 					return;
 				}
-				daddr = kmap_atomic(sg_page(dsg)) + dsg->offset;
+				daddr = sg_map(dsg, SG_KMAP_ATOMIC);
+				if (IS_ERR(daddr))
+					goto sg_map_err;
 			}
 
 			sdt = paddr + j;
 			avail = min(block_size, dsg->length - offset);
 			crc = crc_t10dif(daddr + offset, avail);
 			if (avail < block_size) {
-				kunmap_atomic(daddr - dsg->offset);
+				sg_unmap(dsg, daddr, SG_KMAP_ATOMIC);
 				dsg = sg_next(dsg);
 				if (!dsg) {
-					kunmap_atomic(paddr - psg->offset);
+					sg_unmap(psg, paddr, SG_KMAP_ATOMIC);
 					return;
 				}
-				daddr = kmap_atomic(sg_page(dsg)) + dsg->offset;
+
+				daddr = sg_map(dsg, SG_KMAP_ATOMIC);
+				if (IS_ERR(daddr))
+					goto sg_map_err;
+
 				offset = block_size - avail;
 				crc = crc_t10dif_update(crc, daddr, offset);
 			} else {
@@ -1313,9 +1325,24 @@ sbc_dif_generate(struct se_cmd *cmd)
 			sector++;
 		}
 
-		kunmap_atomic(daddr - dsg->offset);
-		kunmap_atomic(paddr - psg->offset);
+		sg_unmap(dsg, daddr, SG_KMAP_ATOMIC);
+		sg_unmap(psg, paddr, SG_KMAP_ATOMIC);
 	}
+
+	return;
+
+sg_map_err:
+	if (!IS_ERR_OR_NULL(paddr))
+		sg_unmap(psg, paddr, SG_KMAP_ATOMIC);
+
+	/*
+	 * This should really never happen unless
+	 * the code is changed to use memory that is
+	 * not mappable in the sg. Seeing there doesn't
+	 * seem to be any error path out of here,
+	 * we can only WARN.
+	 */
+	WARN(1, "Non-mappable memory used in sg!");
 }
 
 static sense_reason_t
@@ -1359,8 +1386,8 @@ sbc_dif_v1_verify(struct se_cmd *cmd, struct t10_pi_tuple *sdt,
 	return 0;
 }
 
-void sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read,
-		       struct scatterlist *sg, int sg_off)
+int sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read,
+		      struct scatterlist *sg, int sg_off)
 {
 	struct se_device *dev = cmd->se_dev;
 	struct scatterlist *psg;
@@ -1369,18 +1396,24 @@ void sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read,
 	unsigned int offset = sg_off;
 
 	if (!sg)
-		return;
+		return 0;
 
 	left = sectors * dev->prot_length;
 
 	for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) {
 		unsigned int psg_len, copied = 0;
 
-		paddr = kmap_atomic(sg_page(psg)) + psg->offset;
+		paddr = sg_map(psg, SG_KMAP_ATOMIC);
+		if (IS_ERR(paddr))
+			return TCM_OUT_OF_RESOURCES;
+
 		psg_len = min(left, psg->length);
 		while (psg_len) {
 			len = min(psg_len, sg->length - offset);
-			addr = kmap_atomic(sg_page(sg)) + sg->offset + offset;
+			addr = sg_map_offset(sg, offset, SG_KMAP_ATOMIC);
+
+			if (IS_ERR(paddr))
+				return TCM_OUT_OF_RESOURCES;
 
 			if (read)
 				memcpy(paddr + copied, addr, len);
@@ -1392,15 +1425,17 @@ void sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read,
 			copied += len;
 			psg_len -= len;
 
-			kunmap_atomic(addr - sg->offset - offset);
+			sg_unmap_offset(sg, addr, offset, SG_KMAP_ATOMIC);
 
 			if (offset >= sg->length) {
 				sg = sg_next(sg);
 				offset = 0;
 			}
 		}
-		kunmap_atomic(paddr - psg->offset);
+		sg_unmap(psg, paddr, SG_KMAP_ATOMIC);
 	}
+
+	return 0;
 }
 EXPORT_SYMBOL(sbc_dif_copy_prot);
 
@@ -1419,8 +1454,15 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
 	unsigned int block_size = dev->dev_attrib.block_size;
 
 	for (; psg && sector < start + sectors; psg = sg_next(psg)) {
-		paddr = kmap_atomic(sg_page(psg)) + psg->offset;
-		daddr = kmap_atomic(sg_page(dsg)) + dsg->offset;
+		paddr = sg_map(psg, SG_KMAP_ATOMIC);
+		if (IS_ERR(paddr))
+			goto sg_map_err;
+
+		daddr = sg_map(dsg, SG_KMAP_ATOMIC);
+		if (IS_ERR(daddr)) {
+			sg_unmap(psg, paddr, SG_KMAP_ATOMIC);
+			goto sg_map_err;
+		}
 
 		for (i = psg_off; i < psg->length &&
 				sector < start + sectors;
@@ -1430,13 +1472,13 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
 
 			if (dsg_off >= dsg->length) {
 				dsg_off -= dsg->length;
-				kunmap_atomic(daddr - dsg->offset);
+				sg_unmap(dsg, daddr, SG_KMAP_ATOMIC);
 				dsg = sg_next(dsg);
 				if (!dsg) {
-					kunmap_atomic(paddr - psg->offset);
+					sg_unmap(psg, paddr, SG_KMAP_ATOMIC);
 					return 0;
 				}
-				daddr = kmap_atomic(sg_page(dsg)) + dsg->offset;
+				daddr = sg_map(dsg, SG_KMAP_ATOMIC);
 			}
 
 			sdt = paddr + i;
@@ -1454,13 +1496,13 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
 			avail = min(block_size, dsg->length - dsg_off);
 			crc = crc_t10dif(daddr + dsg_off, avail);
 			if (avail < block_size) {
-				kunmap_atomic(daddr - dsg->offset);
+				sg_unmap(dsg, daddr, SG_KMAP_ATOMIC);
 				dsg = sg_next(dsg);
 				if (!dsg) {
-					kunmap_atomic(paddr - psg->offset);
+					sg_unmap(psg, paddr, SG_KMAP_ATOMIC);
 					return 0;
 				}
-				daddr = kmap_atomic(sg_page(dsg)) + dsg->offset;
+				daddr = sg_map(dsg, SG_KMAP_ATOMIC);
 				dsg_off = block_size - avail;
 				crc = crc_t10dif_update(crc, daddr, dsg_off);
 			} else {
@@ -1469,8 +1511,8 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
 
 			rc = sbc_dif_v1_verify(cmd, sdt, crc, sector, ei_lba);
 			if (rc) {
-				kunmap_atomic(daddr - dsg->offset);
-				kunmap_atomic(paddr - psg->offset);
+				sg_unmap(dsg, daddr, SG_KMAP_ATOMIC);
+				sg_unmap(psg, paddr, SG_KMAP_ATOMIC);
 				cmd->bad_sector = sector;
 				return rc;
 			}
@@ -1480,10 +1522,16 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
 		}
 
 		psg_off = 0;
-		kunmap_atomic(daddr - dsg->offset);
-		kunmap_atomic(paddr - psg->offset);
+		sg_unmap(dsg, daddr, SG_KMAP_ATOMIC);
+		sg_unmap(psg, paddr, SG_KMAP_ATOMIC);
 	}
 
 	return 0;
+
+sg_map_err:
+	if (!IS_ERR_OR_NULL(paddr))
+		sg_unmap(psg, paddr, SG_KMAP_ATOMIC);
+
+	return TCM_OUT_OF_RESOURCES;
 }
 EXPORT_SYMBOL(sbc_dif_verify);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index b1a3cdb..6899ef9 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1504,11 +1504,11 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess
 			unsigned char *buf = NULL;
 
 			if (sgl)
-				buf = kmap(sg_page(sgl)) + sgl->offset;
+				buf = sg_map(sgl, SG_KMAP);
 
-			if (buf) {
+			if (buf && !IS_ERR(buf)) {
 				memset(buf, 0, sgl->length);
-				kunmap(sg_page(sgl));
+				sg_unmap(sgl, buf, SG_KMAP);
 			}
 		}
 
@@ -2276,8 +2276,14 @@ void *transport_kmap_data_sg(struct se_cmd *cmd)
 		return NULL;
 
 	BUG_ON(!sg);
-	if (cmd->t_data_nents == 1)
-		return kmap(sg_page(sg)) + sg->offset;
+	if (cmd->t_data_nents == 1) {
+		cmd->t_data_vmap = sg_map(sg, SG_KMAP);
+		if (IS_ERR(cmd->t_data_vmap)) {
+			cmd->t_data_vmap = NULL;
+			return NULL;
+		}
+		return cmd->t_data_vmap;
+	}
 
 	/* >1 page. use vmap */
 	pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL);
@@ -2303,7 +2309,7 @@ void transport_kunmap_data_sg(struct se_cmd *cmd)
 	if (!cmd->t_data_nents) {
 		return;
 	} else if (cmd->t_data_nents == 1) {
-		kunmap(sg_page(cmd->t_data_sg));
+		sg_unmap(cmd->t_data_sg, cmd->t_data_vmap, SG_KMAP);
 		return;
 	}
 
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index c6874c3..319fef5 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -260,7 +260,7 @@ static inline size_t iov_tail(struct tcmu_dev *udev, struct iovec *iov)
 	return (size_t)iov->iov_base + iov->iov_len;
 }
 
-static void alloc_and_scatter_data_area(struct tcmu_dev *udev,
+static int alloc_and_scatter_data_area(struct tcmu_dev *udev,
 	struct scatterlist *data_sg, unsigned int data_nents,
 	struct iovec **iov, int *iov_cnt, bool copy_data)
 {
@@ -272,7 +272,10 @@ static void alloc_and_scatter_data_area(struct tcmu_dev *udev,
 
 	for_each_sg(data_sg, sg, data_nents, i) {
 		int sg_remaining = sg->length;
-		from = kmap_atomic(sg_page(sg)) + sg->offset;
+		from = sg_map(sg, SG_KMAP_ATOMIC);
+		if (IS_ERR(from))
+			return PTR_ERR(from);
+
 		while (sg_remaining > 0) {
 			if (block_remaining == 0) {
 				block = find_first_zero_bit(udev->data_bitmap,
@@ -301,8 +304,10 @@ static void alloc_and_scatter_data_area(struct tcmu_dev *udev,
 			sg_remaining -= copy_bytes;
 			block_remaining -= copy_bytes;
 		}
-		kunmap_atomic(from - sg->offset);
+		sg_unmap(sg, from, SG_KMAP_ATOMIC);
 	}
+
+	return 0;
 }
 
 static void free_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd)
@@ -311,7 +316,7 @@ static void free_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd)
 		   DATA_BLOCK_BITS);
 }
 
-static void gather_data_area(struct tcmu_dev *udev, unsigned long *cmd_bitmap,
+static int gather_data_area(struct tcmu_dev *udev, unsigned long *cmd_bitmap,
 		struct scatterlist *data_sg, unsigned int data_nents)
 {
 	int i, block;
@@ -322,7 +327,10 @@ static void gather_data_area(struct tcmu_dev *udev, unsigned long *cmd_bitmap,
 
 	for_each_sg(data_sg, sg, data_nents, i) {
 		int sg_remaining = sg->length;
-		to = kmap_atomic(sg_page(sg)) + sg->offset;
+		to = sg_map(sg, SG_KMAP_ATOMIC);
+		if (IS_ERR(to))
+			return PTR_ERR(to);
+
 		while (sg_remaining > 0) {
 			if (block_remaining == 0) {
 				block = find_first_bit(cmd_bitmap,
@@ -342,8 +350,10 @@ static void gather_data_area(struct tcmu_dev *udev, unsigned long *cmd_bitmap,
 			sg_remaining -= copy_bytes;
 			block_remaining -= copy_bytes;
 		}
-		kunmap_atomic(to - sg->offset);
+		sg_unmap(sg, to, SG_KMAP_ATOMIC);
 	}
+
+	return 0;
 }
 
 static inline size_t spc_bitmap_free(unsigned long *bitmap)
@@ -505,15 +515,18 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
 	iov_cnt = 0;
 	copy_to_data_area = (se_cmd->data_direction == DMA_TO_DEVICE
 		|| se_cmd->se_cmd_flags & SCF_BIDI);
-	alloc_and_scatter_data_area(udev, se_cmd->t_data_sg,
-		se_cmd->t_data_nents, &iov, &iov_cnt, copy_to_data_area);
+	if (alloc_and_scatter_data_area(udev, se_cmd->t_data_sg,
+		se_cmd->t_data_nents, &iov, &iov_cnt, copy_to_data_area))
+		return TCM_OUT_OF_RESOURCES;
+
 	entry->req.iov_cnt = iov_cnt;
 	entry->req.iov_dif_cnt = 0;
 
 	/* Handle BIDI commands */
 	iov_cnt = 0;
-	alloc_and_scatter_data_area(udev, se_cmd->t_bidi_data_sg,
-		se_cmd->t_bidi_data_nents, &iov, &iov_cnt, false);
+	if (alloc_and_scatter_data_area(udev, se_cmd->t_bidi_data_sg,
+		se_cmd->t_bidi_data_nents, &iov, &iov_cnt, false))
+		return TCM_OUT_OF_RESOURCES;
 	entry->req.iov_bidi_cnt = iov_cnt;
 
 	/* cmd's data_bitmap is what changed in process */
@@ -596,15 +609,17 @@ static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry *
 
 		/* Get Data-In buffer before clean up */
 		bitmap_copy(bitmap, cmd->data_bitmap, DATA_BLOCK_BITS);
-		gather_data_area(udev, bitmap,
-			se_cmd->t_bidi_data_sg, se_cmd->t_bidi_data_nents);
+		if (gather_data_area(udev, bitmap,
+			se_cmd->t_bidi_data_sg, se_cmd->t_bidi_data_nents))
+			entry->rsp.scsi_status = SAM_STAT_CHECK_CONDITION;
 		free_data_area(udev, cmd);
 	} else if (se_cmd->data_direction == DMA_FROM_DEVICE) {
 		DECLARE_BITMAP(bitmap, DATA_BLOCK_BITS);
 
 		bitmap_copy(bitmap, cmd->data_bitmap, DATA_BLOCK_BITS);
-		gather_data_area(udev, bitmap,
-			se_cmd->t_data_sg, se_cmd->t_data_nents);
+		if (gather_data_area(udev, bitmap,
+			se_cmd->t_data_sg, se_cmd->t_data_nents))
+			entry->rsp.scsi_status = SAM_STAT_CHECK_CONDITION;
 		free_data_area(udev, cmd);
 	} else if (se_cmd->data_direction == DMA_TO_DEVICE) {
 		free_data_area(udev, cmd);
diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h
index 1b0f447..c39ecd9 100644
--- a/include/target/target_core_backend.h
+++ b/include/target/target_core_backend.h
@@ -82,8 +82,8 @@ sector_t	sbc_get_write_same_sectors(struct se_cmd *cmd);
 void	sbc_dif_generate(struct se_cmd *);
 sense_reason_t	sbc_dif_verify(struct se_cmd *, sector_t, unsigned int,
 				     unsigned int, struct scatterlist *, int);
-void sbc_dif_copy_prot(struct se_cmd *, unsigned int, bool,
-		       struct scatterlist *, int);
+int sbc_dif_copy_prot(struct se_cmd *, unsigned int, bool,
+		      struct scatterlist *, int);
 void	transport_set_vpd_proto_id(struct t10_vpd *, unsigned char *);
 int	transport_set_vpd_assoc(struct t10_vpd *, unsigned char *);
 int	transport_set_vpd_ident_type(struct t10_vpd *, unsigned char *);
-- 
2.1.4

[toc] | [prev] | [next] | [standalone]


#1623391 — [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper function

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-14 00:20 +0200
Subject[PATCH 16/22] xen-blkfront: Make use of the new sg_map helper function
Message-ID<tvVfQ-Tr-17@gated-at.bofh.it>
In reply to#1623387
Straightforward conversion to the new helper, except due to
the lack of error path, we have to warn if unmapable memory
is ever present in the sgl.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/block/xen-blkfront.c | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 5067a0a..7dcf41d 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -807,8 +807,19 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
 		BUG_ON(sg->offset + sg->length > PAGE_SIZE);
 
 		if (setup.need_copy) {
-			setup.bvec_off = sg->offset;
-			setup.bvec_data = kmap_atomic(sg_page(sg));
+			setup.bvec_off = 0;
+			setup.bvec_data = sg_map(sg, SG_KMAP_ATOMIC);
+			if (IS_ERR(setup.bvec_data)) {
+				/*
+				 * This should really never happen unless
+				 * the code is changed to use memory that is
+				 * not mappable in the sg. Seeing there is a
+				 * questionable error path out of here,
+				 * we WARN.
+				 */
+				WARN(1, "Non-mappable memory used in sg!");
+				return 1;
+			}
 		}
 
 		gnttab_foreach_grant_in_range(sg_page(sg),
@@ -818,7 +829,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
 					      &setup);
 
 		if (setup.need_copy)
-			kunmap_atomic(setup.bvec_data);
+			sg_unmap(sg, setup.bvec_data, SG_KMAP_ATOMIC);
 	}
 	if (setup.segments)
 		kunmap_atomic(setup.segments);
@@ -1468,8 +1479,18 @@ static bool blkif_completion(unsigned long *id,
 		for_each_sg(s->sg, sg, num_sg, i) {
 			BUG_ON(sg->offset + sg->length > PAGE_SIZE);
 
-			data.bvec_offset = sg->offset;
-			data.bvec_data = kmap_atomic(sg_page(sg));
+			data.bvec_offset = 0;
+			data.bvec_data = sg_map(sg, SG_KMAP_ATOMIC);
+			if (IS_ERR(data.bvec_data)) {
+				/*
+				 * This should really never happen unless
+				 * the code is changed to use memory that is
+				 * not mappable in the sg. Seeing there is no
+				 * clear error path, we WARN.
+				 */
+				WARN(1, "Non-mappable memory used in sg!");
+				return 1;
+			}
 
 			gnttab_foreach_grant_in_range(sg_page(sg),
 						      sg->offset,
@@ -1477,7 +1498,7 @@ static bool blkif_completion(unsigned long *id,
 						      blkif_copy_from_grant,
 						      &data);
 
-			kunmap_atomic(data.bvec_data);
+			sg_unmap(sg, data.bvec_data, SG_KMAP_ATOMIC);
 		}
 	}
 	/* Add the persistent grant into the list of free grants */
-- 
2.1.4

[toc] | [prev] | [next] | [standalone]


#1625353 — RE: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper function

FromDavid Laight <David.Laight@ACULAB.COM>
Date2017-04-18 16:20 +0200
SubjectRE: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper function
Message-ID<txC94-7aw-11@gated-at.bofh.it>
In reply to#1623391
From: Logan Gunthorpe
> Sent: 13 April 2017 23:05
> Straightforward conversion to the new helper, except due to
> the lack of error path, we have to warn if unmapable memory
> is ever present in the sgl.
> 
> Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
> ---
>  drivers/block/xen-blkfront.c | 33 +++++++++++++++++++++++++++------
>  1 file changed, 27 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
> index 5067a0a..7dcf41d 100644
> --- a/drivers/block/xen-blkfront.c
> +++ b/drivers/block/xen-blkfront.c
> @@ -807,8 +807,19 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
>  		BUG_ON(sg->offset + sg->length > PAGE_SIZE);
> 
>  		if (setup.need_copy) {
> -			setup.bvec_off = sg->offset;
> -			setup.bvec_data = kmap_atomic(sg_page(sg));
> +			setup.bvec_off = 0;
> +			setup.bvec_data = sg_map(sg, SG_KMAP_ATOMIC);
> +			if (IS_ERR(setup.bvec_data)) {
> +				/*
> +				 * This should really never happen unless
> +				 * the code is changed to use memory that is
> +				 * not mappable in the sg. Seeing there is a
> +				 * questionable error path out of here,
> +				 * we WARN.
> +				 */
> +				WARN(1, "Non-mappable memory used in sg!");
> +				return 1;
> +			}
...

Perhaps add a flag to mark failure as 'unexpected' and trace (and panic?)
inside sg_map().

	David

[toc] | [prev] | [next] | [standalone]


#1625368 — Re: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper function

FromKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date2017-04-18 16:40 +0200
SubjectRe: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper function
Message-ID<txCsp-7gY-11@gated-at.bofh.it>
In reply to#1625353
On Tue, Apr 18, 2017 at 02:13:59PM +0000, David Laight wrote:
> From: Logan Gunthorpe
> > Sent: 13 April 2017 23:05
> > Straightforward conversion to the new helper, except due to
> > the lack of error path, we have to warn if unmapable memory
> > is ever present in the sgl.

Interesting that you didn't CC any of the maintainers. Could you 
do that in the future please?

> > 
> > Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
> > ---
> >  drivers/block/xen-blkfront.c | 33 +++++++++++++++++++++++++++------
> >  1 file changed, 27 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
> > index 5067a0a..7dcf41d 100644
> > --- a/drivers/block/xen-blkfront.c
> > +++ b/drivers/block/xen-blkfront.c
> > @@ -807,8 +807,19 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
> >  		BUG_ON(sg->offset + sg->length > PAGE_SIZE);
> > 
> >  		if (setup.need_copy) {
> > -			setup.bvec_off = sg->offset;
> > -			setup.bvec_data = kmap_atomic(sg_page(sg));
> > +			setup.bvec_off = 0;
> > +			setup.bvec_data = sg_map(sg, SG_KMAP_ATOMIC);
> > +			if (IS_ERR(setup.bvec_data)) {
> > +				/*
> > +				 * This should really never happen unless
> > +				 * the code is changed to use memory that is
> > +				 * not mappable in the sg. Seeing there is a
> > +				 * questionable error path out of here,
> > +				 * we WARN.
> > +				 */
> > +				WARN(1, "Non-mappable memory used in sg!");
> > +				return 1;
> > +			}
> ...
> 
> Perhaps add a flag to mark failure as 'unexpected' and trace (and panic?)
> inside sg_map().
> 
> 	David
> 
> 
> _______________________________________________
> Linux-nvdimm mailing list
> Linux-nvdimm@lists.01.org
> https://lists.01.org/mailman/listinfo/linux-nvdimm

[toc] | [prev] | [next] | [standalone]


#1625412 — Re: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper function

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-18 17:50 +0200
SubjectRe: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper function
Message-ID<txDya-7Sz-21@gated-at.bofh.it>
In reply to#1625368

On 18/04/17 08:27 AM, Konrad Rzeszutek Wilk wrote:
> Interesting that you didn't CC any of the maintainers. Could you 
> do that in the future please?

Please read the cover letter. The distribution list for the patchset
would have been way too large to cc every maintainer (even as limited as
it was, I had mailing lists yelling at me). My plan was to get buy in
for the first patch, get it merged and resend the rest independently to
their respective maintainers. Of course, though, I'd be open to other
suggestions.

>>>
>>> Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
>>> ---
>>>  drivers/block/xen-blkfront.c | 33 +++++++++++++++++++++++++++------
>>>  1 file changed, 27 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
>>> index 5067a0a..7dcf41d 100644
>>> --- a/drivers/block/xen-blkfront.c
>>> +++ b/drivers/block/xen-blkfront.c
>>> @@ -807,8 +807,19 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
>>>  		BUG_ON(sg->offset + sg->length > PAGE_SIZE);
>>>
>>>  		if (setup.need_copy) {
>>> -			setup.bvec_off = sg->offset;
>>> -			setup.bvec_data = kmap_atomic(sg_page(sg));
>>> +			setup.bvec_off = 0;
>>> +			setup.bvec_data = sg_map(sg, SG_KMAP_ATOMIC);
>>> +			if (IS_ERR(setup.bvec_data)) {
>>> +				/*
>>> +				 * This should really never happen unless
>>> +				 * the code is changed to use memory that is
>>> +				 * not mappable in the sg. Seeing there is a
>>> +				 * questionable error path out of here,
>>> +				 * we WARN.
>>> +				 */
>>> +				WARN(1, "Non-mappable memory used in sg!");
>>> +				return 1;
>>> +			}
>> ...
>>
>> Perhaps add a flag to mark failure as 'unexpected' and trace (and panic?)
>> inside sg_map().

Thanks, that's a good suggestion. I'll make the change for v2.

Logan

[toc] | [prev] | [next] | [standalone]


#1625416 — Re: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper function

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-18 18:00 +0200
SubjectRe: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper function
Message-ID<txDHP-7VF-5@gated-at.bofh.it>
In reply to#1625412

On 18/04/17 09:50 AM, Konrad Rzeszutek Wilk wrote:
> I am not sure if you know, but you can add on each patch the respective
> maintainer via 'CC'. That way you can have certain maintainers CCed only
> on the subsystems they cover. You put it after (or before) your SoB and
> git send-email happilly picks it up.

Yes, but I've seen some maintainers complain when they receive a patch
with no context (ie. cover letter and first patch). So I chose to do it
this way. I expect in this situation, no matter what you do, someone is
going to complain about the approach chosen.

Thanks anyway for the tip.

Logan

[toc] | [prev] | [next] | [standalone]


#1625417 — Re: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper function

FromKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date2017-04-18 18:00 +0200
SubjectRe: [PATCH 16/22] xen-blkfront: Make use of the new sg_map helper function
Message-ID<txDHP-7VF-7@gated-at.bofh.it>
In reply to#1625412
On Tue, Apr 18, 2017 at 09:42:20AM -0600, Logan Gunthorpe wrote:
> 
> 
> On 18/04/17 08:27 AM, Konrad Rzeszutek Wilk wrote:
> > Interesting that you didn't CC any of the maintainers. Could you 
> > do that in the future please?
> 
> Please read the cover letter. The distribution list for the patchset
> would have been way too large to cc every maintainer (even as limited as
> it was, I had mailing lists yelling at me). My plan was to get buy in

I am not sure if you know, but you can add on each patch the respective
maintainer via 'CC'. That way you can have certain maintainers CCed only
on the subsystems they cover. You put it after (or before) your SoB and
git send-email happilly picks it up.

It does mean that for every patch you have to run something like this:

$ more add_cc 
#!/bin/bash

git diff HEAD^.. > /tmp/a
echo "---"
scripts/get_maintainer.pl --no-l /tmp/a | while read file
do
    echo "Cc: $file"
done

Or such.


> for the first patch, get it merged and resend the rest independently to
> their respective maintainers. Of course, though, I'd be open to other
> suggestions.
> 
> >>>
> >>> Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
> >>> ---
> >>>  drivers/block/xen-blkfront.c | 33 +++++++++++++++++++++++++++------
> >>>  1 file changed, 27 insertions(+), 6 deletions(-)
> >>>
> >>> diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
> >>> index 5067a0a..7dcf41d 100644
> >>> --- a/drivers/block/xen-blkfront.c
> >>> +++ b/drivers/block/xen-blkfront.c
> >>> @@ -807,8 +807,19 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri
> >>>  		BUG_ON(sg->offset + sg->length > PAGE_SIZE);
> >>>
> >>>  		if (setup.need_copy) {
> >>> -			setup.bvec_off = sg->offset;
> >>> -			setup.bvec_data = kmap_atomic(sg_page(sg));
> >>> +			setup.bvec_off = 0;
> >>> +			setup.bvec_data = sg_map(sg, SG_KMAP_ATOMIC);
> >>> +			if (IS_ERR(setup.bvec_data)) {
> >>> +				/*
> >>> +				 * This should really never happen unless
> >>> +				 * the code is changed to use memory that is
> >>> +				 * not mappable in the sg. Seeing there is a
> >>> +				 * questionable error path out of here,
> >>> +				 * we WARN.
> >>> +				 */
> >>> +				WARN(1, "Non-mappable memory used in sg!");
> >>> +				return 1;
> >>> +			}
> >> ...
> >>
> >> Perhaps add a flag to mark failure as 'unexpected' and trace (and panic?)
> >> inside sg_map().
> 
> Thanks, that's a good suggestion. I'll make the change for v2.
> 
> Logan

[toc] | [prev] | [next] | [standalone]


#1623392 — [PATCH 10/22] staging: unisys: visorbus: Make use of the new sg_map helper function

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-14 00:20 +0200
Subject[PATCH 10/22] staging: unisys: visorbus: Make use of the new sg_map helper function
Message-ID<tvVfQ-Tr-19@gated-at.bofh.it>
In reply to#1623387
Straightforward conversion to the new function.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/staging/unisys/visorhba/visorhba_main.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c
index 0ce92c8..2d8c8bc 100644
--- a/drivers/staging/unisys/visorhba/visorhba_main.c
+++ b/drivers/staging/unisys/visorhba/visorhba_main.c
@@ -842,7 +842,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
 	struct scatterlist *sg;
 	unsigned int i;
 	char *this_page;
-	char *this_page_orig;
 	int bufind = 0;
 	struct visordisk_info *vdisk;
 	struct visorhba_devdata *devdata;
@@ -869,11 +868,14 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
 
 		sg = scsi_sglist(scsicmd);
 		for (i = 0; i < scsi_sg_count(scsicmd); i++) {
-			this_page_orig = kmap_atomic(sg_page(sg + i));
-			this_page = (void *)((unsigned long)this_page_orig |
-					     sg[i].offset);
+			this_page = sg_map(sg + i, SG_KMAP_ATOMIC);
+			if (IS_ERR(this_page)) {
+				scsicmd->result = DID_ERROR << 16;
+				return;
+			}
+
 			memcpy(this_page, buf + bufind, sg[i].length);
-			kunmap_atomic(this_page_orig);
+			sg_unmap(sg + i, this_page, SG_KMAP_ATOMIC);
 		}
 	} else {
 		devdata = (struct visorhba_devdata *)scsidev->host->hostdata;
-- 
2.1.4

[toc] | [prev] | [next] | [standalone]


#1623753 — RE: [PATCH 10/22] staging: unisys: visorbus: Make use of the new sg_map helper function

From"Kershner, David A" <David.Kershner@unisys.com>
Date2017-04-14 18:10 +0200
SubjectRE: [PATCH 10/22] staging: unisys: visorbus: Make use of the new sg_map helper function
Message-ID<twbXk-3bL-21@gated-at.bofh.it>
In reply to#1623392
> -----Original Message-----
> From: Logan Gunthorpe [mailto:logang@deltatee.com]
...
> Subject: [PATCH 10/22] staging: unisys: visorbus: Make use of the new
> sg_map helper function
> 
> Straightforward conversion to the new function.
> 
> Signed-off-by: Logan Gunthorpe <logang@deltatee.com>

Can you add Acked-by for this patch? 

Acked-by: David Kershner <david.kershner@unisys.com>

Tested on s-Par and no problems. 

Thanks,
David Kershner

> ---
>  drivers/staging/unisys/visorhba/visorhba_main.c | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c
> b/drivers/staging/unisys/visorhba/visorhba_main.c
> index 0ce92c8..2d8c8bc 100644
> --- a/drivers/staging/unisys/visorhba/visorhba_main.c
> +++ b/drivers/staging/unisys/visorhba/visorhba_main.c
> @@ -842,7 +842,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct
> scsi_cmnd *scsicmd)
>  	struct scatterlist *sg;
>  	unsigned int i;
>  	char *this_page;
> -	char *this_page_orig;
>  	int bufind = 0;
>  	struct visordisk_info *vdisk;
>  	struct visorhba_devdata *devdata;
> @@ -869,11 +868,14 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp,
> struct scsi_cmnd *scsicmd)
> 
>  		sg = scsi_sglist(scsicmd);
>  		for (i = 0; i < scsi_sg_count(scsicmd); i++) {
> -			this_page_orig = kmap_atomic(sg_page(sg + i));
> -			this_page = (void *)((unsigned long)this_page_orig |
> -					     sg[i].offset);
> +			this_page = sg_map(sg + i, SG_KMAP_ATOMIC);
> +			if (IS_ERR(this_page)) {
> +				scsicmd->result = DID_ERROR << 16;
> +				return;
> +			}
> +
>  			memcpy(this_page, buf + bufind, sg[i].length);
> -			kunmap_atomic(this_page_orig);
> +			sg_unmap(sg + i, this_page, SG_KMAP_ATOMIC);
>  		}
>  	} else {
>  		devdata = (struct visorhba_devdata *)scsidev->host-
> >hostdata;
> --
> 2.1.4

[toc] | [prev] | [next] | [standalone]


#1623758 — Re: [PATCH 10/22] staging: unisys: visorbus: Make use of the new sg_map helper function

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-14 18:20 +0200
SubjectRe: [PATCH 10/22] staging: unisys: visorbus: Make use of the new sg_map helper function
Message-ID<twc70-3f1-15@gated-at.bofh.it>
In reply to#1623753
Great, thanks!

Logan

On 14/04/17 10:07 AM, Kershner, David A wrote:
> Can you add Acked-by for this patch? 
> 
> Acked-by: David Kershner <david.kershner@unisys.com>
> 
> Tested on s-Par and no problems. 
> 
> Thanks,
> David Kershner
> 
>> ---
>>  drivers/staging/unisys/visorhba/visorhba_main.c | 12 +++++++-----
>>  1 file changed, 7 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c
>> b/drivers/staging/unisys/visorhba/visorhba_main.c
>> index 0ce92c8..2d8c8bc 100644
>> --- a/drivers/staging/unisys/visorhba/visorhba_main.c
>> +++ b/drivers/staging/unisys/visorhba/visorhba_main.c
>> @@ -842,7 +842,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct
>> scsi_cmnd *scsicmd)
>>  	struct scatterlist *sg;
>>  	unsigned int i;
>>  	char *this_page;
>> -	char *this_page_orig;
>>  	int bufind = 0;
>>  	struct visordisk_info *vdisk;
>>  	struct visorhba_devdata *devdata;
>> @@ -869,11 +868,14 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp,
>> struct scsi_cmnd *scsicmd)
>>
>>  		sg = scsi_sglist(scsicmd);
>>  		for (i = 0; i < scsi_sg_count(scsicmd); i++) {
>> -			this_page_orig = kmap_atomic(sg_page(sg + i));
>> -			this_page = (void *)((unsigned long)this_page_orig |
>> -					     sg[i].offset);
>> +			this_page = sg_map(sg + i, SG_KMAP_ATOMIC);
>> +			if (IS_ERR(this_page)) {
>> +				scsicmd->result = DID_ERROR << 16;
>> +				return;
>> +			}
>> +
>>  			memcpy(this_page, buf + bufind, sg[i].length);
>> -			kunmap_atomic(this_page_orig);
>> +			sg_unmap(sg + i, this_page, SG_KMAP_ATOMIC);
>>  		}
>>  	} else {
>>  		devdata = (struct visorhba_devdata *)scsidev->host-
>>> hostdata;
>> --
>> 2.1.4
> 

[toc] | [prev] | [next] | [standalone]


#1623393 — [PATCH 07/22] crypto: shash, caam: Make use of the new sg_map helper function

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-14 00:20 +0200
Subject[PATCH 07/22] crypto: shash, caam: Make use of the new sg_map helper function
Message-ID<tvVfQ-Tr-21@gated-at.bofh.it>
In reply to#1623387
Very straightforward conversion to the new function in two crypto
drivers.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 crypto/shash.c                | 9 ++++++---
 drivers/crypto/caam/caamalg.c | 8 +++-----
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/crypto/shash.c b/crypto/shash.c
index 5e31c8d..2b7de94 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -283,10 +283,13 @@ int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc)
 	if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {
 		void *data;
 
-		data = kmap_atomic(sg_page(sg));
-		err = crypto_shash_digest(desc, data + offset, nbytes,
+		data = sg_map(sg, SG_KMAP_ATOMIC);
+		if (IS_ERR(data))
+			return PTR_ERR(data);
+
+		err = crypto_shash_digest(desc, data, nbytes,
 					  req->result);
-		kunmap_atomic(data);
+		sg_unmap(sg, data, SG_KMAP_ATOMIC);
 		crypto_yield(desc->flags);
 	} else
 		err = crypto_shash_init(desc) ?:
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 9bc80eb..76b97de 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -89,7 +89,6 @@ static void dbg_dump_sg(const char *level, const char *prefix_str,
 			struct scatterlist *sg, size_t tlen, bool ascii)
 {
 	struct scatterlist *it;
-	void *it_page;
 	size_t len;
 	void *buf;
 
@@ -98,19 +97,18 @@ static void dbg_dump_sg(const char *level, const char *prefix_str,
 		 * make sure the scatterlist's page
 		 * has a valid virtual memory mapping
 		 */
-		it_page = kmap_atomic(sg_page(it));
-		if (unlikely(!it_page)) {
+		buf = sg_map(it, SG_KMAP_ATOMIC);
+		if (IS_ERR(buf)) {
 			printk(KERN_ERR "dbg_dump_sg: kmap failed\n");
 			return;
 		}
 
-		buf = it_page + it->offset;
 		len = min_t(size_t, tlen, it->length);
 		print_hex_dump(level, prefix_str, prefix_type, rowsize,
 			       groupsize, buf, len, ascii);
 		tlen -= len;
 
-		kunmap_atomic(it_page);
+		sg_unmap(it, buf, SG_KMAP_ATOMIC);
 	}
 }
 #endif
-- 
2.1.4

[toc] | [prev] | [next] | [standalone]


#1623394 — [PATCH 12/22] scsi: ipr, pmcraid, isci: Make use of the new sg_map helper in 4 call sites

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-14 00:20 +0200
Subject[PATCH 12/22] scsi: ipr, pmcraid, isci: Make use of the new sg_map helper in 4 call sites
Message-ID<tvVfQ-Tr-25@gated-at.bofh.it>
In reply to#1623387
Very straightforward conversion of three scsi drivers.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/scsi/ipr.c          | 27 ++++++++++++++-------------
 drivers/scsi/isci/request.c | 42 +++++++++++++++++++++++++-----------------
 drivers/scsi/pmcraid.c      | 19 ++++++++++++-------
 3 files changed, 51 insertions(+), 37 deletions(-)

diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b29afaf..f98f251 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3853,7 +3853,7 @@ static void ipr_free_ucode_buffer(struct ipr_sglist *sglist)
 static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
 				 u8 *buffer, u32 len)
 {
-	int bsize_elem, i, result = 0;
+	int bsize_elem, i;
 	struct scatterlist *scatterlist;
 	void *kaddr;
 
@@ -3863,32 +3863,33 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
 	scatterlist = sglist->scatterlist;
 
 	for (i = 0; i < (len / bsize_elem); i++, buffer += bsize_elem) {
-		struct page *page = sg_page(&scatterlist[i]);
+		kaddr = sg_map(&scatterlist[i], SG_KMAP);
+		if (IS_ERR(kaddr)) {
+			ipr_trace;
+			return PTR_ERR(kaddr);
+		}
 
-		kaddr = kmap(page);
 		memcpy(kaddr, buffer, bsize_elem);
-		kunmap(page);
+		sg_unmap(&scatterlist[i], kaddr, SG_KMAP);
 
 		scatterlist[i].length = bsize_elem;
-
-		if (result != 0) {
-			ipr_trace;
-			return result;
-		}
 	}
 
 	if (len % bsize_elem) {
-		struct page *page = sg_page(&scatterlist[i]);
+		kaddr = sg_map(&scatterlist[i], SG_KMAP);
+		if (IS_ERR(kaddr)) {
+			ipr_trace;
+			return PTR_ERR(kaddr);
+		}
 
-		kaddr = kmap(page);
 		memcpy(kaddr, buffer, len % bsize_elem);
-		kunmap(page);
+		sg_unmap(&scatterlist[i], kaddr, SG_KMAP);
 
 		scatterlist[i].length = len % bsize_elem;
 	}
 
 	sglist->buffer_len = len;
-	return result;
+	return 0;
 }
 
 /**
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index 47f66e9..66d6596 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -1424,12 +1424,14 @@ sci_stp_request_pio_data_in_copy_data_buffer(struct isci_stp_request *stp_req,
 		sg = task->scatter;
 
 		while (total_len > 0) {
-			struct page *page = sg_page(sg);
-
 			copy_len = min_t(int, total_len, sg_dma_len(sg));
-			kaddr = kmap_atomic(page);
-			memcpy(kaddr + sg->offset, src_addr, copy_len);
-			kunmap_atomic(kaddr);
+			kaddr = sg_map(sg, SG_KMAP_ATOMIC);
+			if (IS_ERR(kaddr))
+				return SCI_FAILURE;
+
+			memcpy(kaddr, src_addr, copy_len);
+			sg_unmap(sg, kaddr, SG_KMAP_ATOMIC);
+
 			total_len -= copy_len;
 			src_addr += copy_len;
 			sg = sg_next(sg);
@@ -1771,14 +1773,16 @@ sci_io_request_frame_handler(struct isci_request *ireq,
 	case SCI_REQ_SMP_WAIT_RESP: {
 		struct sas_task *task = isci_request_access_task(ireq);
 		struct scatterlist *sg = &task->smp_task.smp_resp;
-		void *frame_header, *kaddr;
+		void *frame_header;
 		u8 *rsp;
 
 		sci_unsolicited_frame_control_get_header(&ihost->uf_control,
 							 frame_index,
 							 &frame_header);
-		kaddr = kmap_atomic(sg_page(sg));
-		rsp = kaddr + sg->offset;
+		rsp = sg_map(sg, SG_KMAP_ATOMIC);
+		if (IS_ERR(rsp))
+			return SCI_FAILURE;
+
 		sci_swab32_cpy(rsp, frame_header, 1);
 
 		if (rsp[0] == SMP_RESPONSE) {
@@ -1814,7 +1818,7 @@ sci_io_request_frame_handler(struct isci_request *ireq,
 			ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
 			sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
 		}
-		kunmap_atomic(kaddr);
+		sg_unmap(sg, rsp, SG_KMAP_ATOMIC);
 
 		sci_controller_release_frame(ihost, frame_index);
 
@@ -2919,15 +2923,18 @@ static void isci_request_io_request_complete(struct isci_host *ihost,
 	case SAS_PROTOCOL_SMP: {
 		struct scatterlist *sg = &task->smp_task.smp_req;
 		struct smp_req *smp_req;
-		void *kaddr;
 
 		dma_unmap_sg(&ihost->pdev->dev, sg, 1, DMA_TO_DEVICE);
 
 		/* need to swab it back in case the command buffer is re-used */
-		kaddr = kmap_atomic(sg_page(sg));
-		smp_req = kaddr + sg->offset;
+		smp_req = sg_map(sg, SG_KMAP_ATOMIC);
+		if (IS_ERR(smp_req)) {
+			status = SAS_ABORTED_TASK;
+			break;
+		}
+
 		sci_swab32_cpy(smp_req, smp_req, sg->length / sizeof(u32));
-		kunmap_atomic(kaddr);
+		sg_unmap(sg, smp_req, SG_KMAP_ATOMIC);
 		break;
 	}
 	default:
@@ -3190,12 +3197,13 @@ sci_io_request_construct_smp(struct device *dev,
 	struct scu_task_context *task_context;
 	struct isci_port *iport;
 	struct smp_req *smp_req;
-	void *kaddr;
 	u8 req_len;
 	u32 cmd;
 
-	kaddr = kmap_atomic(sg_page(sg));
-	smp_req = kaddr + sg->offset;
+	smp_req = sg_map(sg, SG_KMAP_ATOMIC);
+	if (IS_ERR(smp_req))
+		return SCI_FAILURE;
+
 	/*
 	 * Look at the SMP requests' header fields; for certain SAS 1.x SMP
 	 * functions under SAS 2.0, a zero request length really indicates
@@ -3220,7 +3228,7 @@ sci_io_request_construct_smp(struct device *dev,
 	req_len = smp_req->req_len;
 	sci_swab32_cpy(smp_req, smp_req, sg->length / sizeof(u32));
 	cmd = *(u32 *) smp_req;
-	kunmap_atomic(kaddr);
+	sg_unmap(sg, smp_req, SG_KMAP_ATOMIC);
 
 	if (!dma_map_sg(dev, sg, 1, DMA_TO_DEVICE))
 		return SCI_FAILURE;
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 49e70a3..af1903e 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -3342,9 +3342,12 @@ static int pmcraid_copy_sglist(
 	scatterlist = sglist->scatterlist;
 
 	for (i = 0; i < (len / bsize_elem); i++, buffer += bsize_elem) {
-		struct page *page = sg_page(&scatterlist[i]);
+		kaddr = sg_map(&scatterlist[i], SG_KMAP);
+		if (IS_ERR(kaddr)) {
+			pmcraid_err("failed to copy user data into sg list\n");
+			return PTR_ERR(kaddr);
+		}
 
-		kaddr = kmap(page);
 		if (direction == DMA_TO_DEVICE)
 			rc = __copy_from_user(kaddr,
 					      (void *)buffer,
@@ -3352,7 +3355,7 @@ static int pmcraid_copy_sglist(
 		else
 			rc = __copy_to_user((void *)buffer, kaddr, bsize_elem);
 
-		kunmap(page);
+		sg_unmap(&scatterlist[i], kaddr, SG_KMAP);
 
 		if (rc) {
 			pmcraid_err("failed to copy user data into sg list\n");
@@ -3363,9 +3366,11 @@ static int pmcraid_copy_sglist(
 	}
 
 	if (len % bsize_elem) {
-		struct page *page = sg_page(&scatterlist[i]);
-
-		kaddr = kmap(page);
+		kaddr = sg_map(&scatterlist[i], SG_KMAP);
+		if (IS_ERR(kaddr)) {
+			pmcraid_err("failed to copy user data into sg list\n");
+			return PTR_ERR(kaddr);
+		}
 
 		if (direction == DMA_TO_DEVICE)
 			rc = __copy_from_user(kaddr,
@@ -3376,7 +3381,7 @@ static int pmcraid_copy_sglist(
 					    kaddr,
 					    len % bsize_elem);
 
-		kunmap(page);
+		sg_unmap(&scatterlist[i], kaddr, SG_KMAP);
 
 		scatterlist[i].length = len % bsize_elem;
 	}
-- 
2.1.4

[toc] | [prev] | [next] | [standalone]


#1623395 — [PATCH 15/22] scsi: libfc, csiostor: Change to sg_copy_buffer in two drivers

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-14 00:20 +0200
Subject[PATCH 15/22] scsi: libfc, csiostor: Change to sg_copy_buffer in two drivers
Message-ID<tvVfQ-Tr-29@gated-at.bofh.it>
In reply to#1623387
These two drivers appear to duplicate the functionality of
sg_copy_buffer. So we clean them up to use the common code.

This helps us remove a couple of instances that would otherwise be
slightly tricky sg_map usages.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/scsi/csiostor/csio_scsi.c | 54 +++------------------------------------
 drivers/scsi/libfc/fc_libfc.c     | 49 ++++++++---------------------------
 2 files changed, 14 insertions(+), 89 deletions(-)

diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c
index a1ff75f..bd9d062 100644
--- a/drivers/scsi/csiostor/csio_scsi.c
+++ b/drivers/scsi/csiostor/csio_scsi.c
@@ -1489,60 +1489,14 @@ static inline uint32_t
 csio_scsi_copy_to_sgl(struct csio_hw *hw, struct csio_ioreq *req)
 {
 	struct scsi_cmnd *scmnd  = (struct scsi_cmnd *)csio_scsi_cmnd(req);
-	struct scatterlist *sg;
-	uint32_t bytes_left;
-	uint32_t bytes_copy;
-	uint32_t buf_off = 0;
-	uint32_t start_off = 0;
-	uint32_t sg_off = 0;
-	void *sg_addr;
-	void *buf_addr;
 	struct csio_dma_buf *dma_buf;
+	size_t copied;
 
-	bytes_left = scsi_bufflen(scmnd);
-	sg = scsi_sglist(scmnd);
 	dma_buf = (struct csio_dma_buf *)csio_list_next(&req->gen_list);
+	copied = sg_copy_from_buffer(scsi_sglist(scmnd), scsi_sg_count(scmnd),
+				     dma_buf->vaddr, scsi_bufflen(scmnd));
 
-	/* Copy data from driver buffer to SGs of SCSI CMD */
-	while (bytes_left > 0 && sg && dma_buf) {
-		if (buf_off >= dma_buf->len) {
-			buf_off = 0;
-			dma_buf = (struct csio_dma_buf *)
-					csio_list_next(dma_buf);
-			continue;
-		}
-
-		if (start_off >= sg->length) {
-			start_off -= sg->length;
-			sg = sg_next(sg);
-			continue;
-		}
-
-		buf_addr = dma_buf->vaddr + buf_off;
-		sg_off = sg->offset + start_off;
-		bytes_copy = min((dma_buf->len - buf_off),
-				sg->length - start_off);
-		bytes_copy = min((uint32_t)(PAGE_SIZE - (sg_off & ~PAGE_MASK)),
-				 bytes_copy);
-
-		sg_addr = kmap_atomic(sg_page(sg) + (sg_off >> PAGE_SHIFT));
-		if (!sg_addr) {
-			csio_err(hw, "failed to kmap sg:%p of ioreq:%p\n",
-				sg, req);
-			break;
-		}
-
-		csio_dbg(hw, "copy_to_sgl:sg_addr %p sg_off %d buf %p len %d\n",
-				sg_addr, sg_off, buf_addr, bytes_copy);
-		memcpy(sg_addr + (sg_off & ~PAGE_MASK), buf_addr, bytes_copy);
-		kunmap_atomic(sg_addr);
-
-		start_off +=  bytes_copy;
-		buf_off += bytes_copy;
-		bytes_left -= bytes_copy;
-	}
-
-	if (bytes_left > 0)
+	if (copied != scsi_bufflen(scmnd))
 		return DID_ERROR;
 	else
 		return DID_OK;
diff --git a/drivers/scsi/libfc/fc_libfc.c b/drivers/scsi/libfc/fc_libfc.c
index d623d08..ce0805a 100644
--- a/drivers/scsi/libfc/fc_libfc.c
+++ b/drivers/scsi/libfc/fc_libfc.c
@@ -113,45 +113,16 @@ u32 fc_copy_buffer_to_sglist(void *buf, size_t len,
 			     u32 *nents, size_t *offset,
 			     u32 *crc)
 {
-	size_t remaining = len;
-	u32 copy_len = 0;
-
-	while (remaining > 0 && sg) {
-		size_t off, sg_bytes;
-		void *page_addr;
-
-		if (*offset >= sg->length) {
-			/*
-			 * Check for end and drop resources
-			 * from the last iteration.
-			 */
-			if (!(*nents))
-				break;
-			--(*nents);
-			*offset -= sg->length;
-			sg = sg_next(sg);
-			continue;
-		}
-		sg_bytes = min(remaining, sg->length - *offset);
-
-		/*
-		 * The scatterlist item may be bigger than PAGE_SIZE,
-		 * but we are limited to mapping PAGE_SIZE at a time.
-		 */
-		off = *offset + sg->offset;
-		sg_bytes = min(sg_bytes,
-			       (size_t)(PAGE_SIZE - (off & ~PAGE_MASK)));
-		page_addr = kmap_atomic(sg_page(sg) + (off >> PAGE_SHIFT));
-		if (crc)
-			*crc = crc32(*crc, buf, sg_bytes);
-		memcpy((char *)page_addr + (off & ~PAGE_MASK), buf, sg_bytes);
-		kunmap_atomic(page_addr);
-		buf += sg_bytes;
-		*offset += sg_bytes;
-		remaining -= sg_bytes;
-		copy_len += sg_bytes;
-	}
-	return copy_len;
+	size_t copied;
+
+	copied = sg_pcopy_from_buffer(sg, sg_nents(sg),
+				      buf, len, *offset);
+
+	*offset += copied;
+	if (crc)
+		*crc = crc32(*crc, buf, copied);
+
+	return copied;
 }
 
 /**
-- 
2.1.4

[toc] | [prev] | [next] | [standalone]


#1623396 — [PATCH 17/22] mmc: sdhci: Make use of the new sg_map helper function

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-14 00:20 +0200
Subject[PATCH 17/22] mmc: sdhci: Make use of the new sg_map helper function
Message-ID<tvVfQ-Tr-31@gated-at.bofh.it>
In reply to#1623387
Straightforward conversion, except due to the lack of error path we
have to WARN if the memory in the SGL is not mappable.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/mmc/host/sdhci.c | 35 ++++++++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 63bc33a..af0c107 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -497,15 +497,34 @@ static int sdhci_pre_dma_transfer(struct sdhci_host *host,
 	return sg_count;
 }
 
+/*
+ * Note this function may return PTR_ERR and must be checked.
+ */
 static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
 {
+	void *ret;
+
 	local_irq_save(*flags);
-	return kmap_atomic(sg_page(sg)) + sg->offset;
+
+	ret = sg_map(sg, SG_KMAP_ATOMIC);
+	if (IS_ERR(ret)) {
+		/*
+		 * This should really never happen unless the code is changed
+		 * to use memory that is not mappable in the sg. Seeing there
+		 * doesn't seem to be any error path out of here, we can only
+		 * WARN.
+		 */
+		WARN(1, "Non-mappable memory used in sg!");
+		local_irq_restore(*flags);
+	}
+
+	return ret;
 }
 
-static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags)
+static void sdhci_kunmap_atomic(struct scatterlist *sg, void *buffer,
+				unsigned long *flags)
 {
-	kunmap_atomic(buffer);
+	sg_unmap(sg, buffer, SG_KMAP_ATOMIC);
 	local_irq_restore(*flags);
 }
 
@@ -568,8 +587,11 @@ static void sdhci_adma_table_pre(struct sdhci_host *host,
 		if (offset) {
 			if (data->flags & MMC_DATA_WRITE) {
 				buffer = sdhci_kmap_atomic(sg, &flags);
+				if (IS_ERR(buffer))
+					return;
+
 				memcpy(align, buffer, offset);
-				sdhci_kunmap_atomic(buffer, &flags);
+				sdhci_kunmap_atomic(sg, buffer, &flags);
 			}
 
 			/* tran, valid */
@@ -646,8 +668,11 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
 					       (sg_dma_address(sg) & SDHCI_ADMA2_MASK);
 
 					buffer = sdhci_kmap_atomic(sg, &flags);
+					if (IS_ERR(buffer))
+						return;
+
 					memcpy(buffer, align, size);
-					sdhci_kunmap_atomic(buffer, &flags);
+					sdhci_kunmap_atomic(sg, buffer, &flags);
 
 					align += SDHCI_ADMA2_ALIGN;
 				}
-- 
2.1.4

[toc] | [prev] | [next] | [standalone]


#1623397 — [PATCH 22/22] memstick: Make use of the new sg_map helper function

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-14 00:20 +0200
Subject[PATCH 22/22] memstick: Make use of the new sg_map helper function
Message-ID<tvVfR-Tr-35@gated-at.bofh.it>
In reply to#1623387
Straightforward conversion, but we have to WARN if unmappable
memory finds its way into the sgl.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/memstick/host/jmb38x_ms.c | 23 ++++++++++++++++++-----
 drivers/memstick/host/tifm_ms.c   | 22 +++++++++++++++++-----
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index 48db922..256cf41 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -303,7 +303,6 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host)
 	unsigned int off;
 	unsigned int t_size, p_cnt;
 	unsigned char *buf;
-	struct page *pg;
 	unsigned long flags = 0;
 
 	if (host->req->long_data) {
@@ -318,14 +317,26 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host)
 		unsigned int uninitialized_var(p_off);
 
 		if (host->req->long_data) {
-			pg = nth_page(sg_page(&host->req->sg),
-				      off >> PAGE_SHIFT);
 			p_off = offset_in_page(off);
 			p_cnt = PAGE_SIZE - p_off;
 			p_cnt = min(p_cnt, length);
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pg) + p_off;
+			buf = sg_map_offset(&host->req->sg,
+					     off - host->req->sg.offset,
+					     SG_KMAP_ATOMIC);
+			if (IS_ERR(buf)) {
+				/*
+				 * This should really never happen unless
+				 * the code is changed to use memory that is
+				 * not mappable in the sg. Seeing there doesn't
+				 * seem to be any error path out of here,
+				 * we can only WARN.
+				 */
+				WARN(1, "Non-mappable memory used in sg!");
+				break;
+			}
+
 		} else {
 			buf = host->req->data + host->block_pos;
 			p_cnt = host->req->data_len - host->block_pos;
@@ -341,7 +352,9 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host)
 				 : jmb38x_ms_read_reg_data(host, buf, p_cnt);
 
 		if (host->req->long_data) {
-			kunmap_atomic(buf - p_off);
+			sg_unmap_offset(&host->req->sg, buf,
+					 off - host->req->sg.offset,
+					 SG_KMAP_ATOMIC);
 			local_irq_restore(flags);
 		}
 
diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c
index 7bafa72..c0bc40e 100644
--- a/drivers/memstick/host/tifm_ms.c
+++ b/drivers/memstick/host/tifm_ms.c
@@ -186,7 +186,6 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms *host)
 	unsigned int off;
 	unsigned int t_size, p_cnt;
 	unsigned char *buf;
-	struct page *pg;
 	unsigned long flags = 0;
 
 	if (host->req->long_data) {
@@ -203,14 +202,25 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms *host)
 		unsigned int uninitialized_var(p_off);
 
 		if (host->req->long_data) {
-			pg = nth_page(sg_page(&host->req->sg),
-				      off >> PAGE_SHIFT);
 			p_off = offset_in_page(off);
 			p_cnt = PAGE_SIZE - p_off;
 			p_cnt = min(p_cnt, length);
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pg) + p_off;
+			buf = sg_map_offset(&host->req->sg,
+					     off - host->req->sg.offset,
+					     SG_KMAP_ATOMIC);
+			if (IS_ERR(buf)) {
+				/*
+				 * This should really never happen unless
+				 * the code is changed to use memory that is
+				 * not mappable in the sg. Seeing there doesn't
+				 * seem to be any error path out of here,
+				 * we can only WARN.
+				 */
+				WARN(1, "Non-mappable memory used in sg!");
+				break;
+			}
 		} else {
 			buf = host->req->data + host->block_pos;
 			p_cnt = host->req->data_len - host->block_pos;
@@ -221,7 +231,9 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms *host)
 			 : tifm_ms_read_data(host, buf, p_cnt);
 
 		if (host->req->long_data) {
-			kunmap_atomic(buf - p_off);
+			sg_unmap_offset(&host->req->sg, buf,
+					 off - host->req->sg.offset,
+					 SG_KMAP_ATOMIC);
 			local_irq_restore(flags);
 		}
 
-- 
2.1.4

[toc] | [prev] | [next] | [standalone]


#1623398 — [PATCH 19/22] mmc: tmio: Make use of the new sg_map helper function

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-14 00:20 +0200
Subject[PATCH 19/22] mmc: tmio: Make use of the new sg_map helper function
Message-ID<tvVfQ-Tr-33@gated-at.bofh.it>
In reply to#1623387
Straightforward conversion to sg_map helper. A couple paths will
WARN if the memory does not end up being mappable.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/mmc/host/tmio_mmc.h     | 12 ++++++++++--
 drivers/mmc/host/tmio_mmc_dma.c |  5 +++++
 drivers/mmc/host/tmio_mmc_pio.c | 24 ++++++++++++++++++++++++
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 2b349d4..ba68c9fed 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -198,17 +198,25 @@ void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
 void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
 irqreturn_t tmio_mmc_irq(int irq, void *devid);
 
+/* Note: this function may return PTR_ERR and must be checked! */
 static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg,
 					 unsigned long *flags)
 {
+	void *ret;
+
 	local_irq_save(*flags);
-	return kmap_atomic(sg_page(sg)) + sg->offset;
+	ret = sg_map(sg, SG_KMAP_ATOMIC);
+
+	if (IS_ERR(ret))
+		local_irq_restore(*flags);
+
+	return ret;
 }
 
 static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg,
 					  unsigned long *flags, void *virt)
 {
-	kunmap_atomic(virt - sg->offset);
+	sg_unmap(sg, virt, SG_KMAP_ATOMIC);
 	local_irq_restore(*flags);
 }
 
diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c
index fa8a936..07531f7 100644
--- a/drivers/mmc/host/tmio_mmc_dma.c
+++ b/drivers/mmc/host/tmio_mmc_dma.c
@@ -149,6 +149,11 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
 	if (!aligned) {
 		unsigned long flags;
 		void *sg_vaddr = tmio_mmc_kmap_atomic(sg, &flags);
+		if (IS_ERR(sg_vaddr)) {
+			ret = PTR_ERR(sg_vaddr);
+			goto pio;
+		}
+
 		sg_init_one(&host->bounce_sg, host->bounce_buf, sg->length);
 		memcpy(host->bounce_buf, sg_vaddr, host->bounce_sg.length);
 		tmio_mmc_kunmap_atomic(sg, &flags, sg_vaddr);
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 6b789a7..d6fdbf6 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -479,6 +479,18 @@ static void tmio_mmc_pio_irq(struct tmio_mmc_host *host)
 	}
 
 	sg_virt = tmio_mmc_kmap_atomic(host->sg_ptr, &flags);
+	if (IS_ERR(sg_virt)) {
+		/*
+		 * This should really never happen unless
+		 * the code is changed to use memory that is
+		 * not mappable in the sg. Seeing there doesn't
+		 * seem to be any error path out of here,
+		 * we can only WARN.
+		 */
+		WARN(1, "Non-mappable memory used in sg!");
+		return;
+	}
+
 	buf = (unsigned short *)(sg_virt + host->sg_off);
 
 	count = host->sg_ptr->length - host->sg_off;
@@ -506,6 +518,18 @@ static void tmio_mmc_check_bounce_buffer(struct tmio_mmc_host *host)
 	if (host->sg_ptr == &host->bounce_sg) {
 		unsigned long flags;
 		void *sg_vaddr = tmio_mmc_kmap_atomic(host->sg_orig, &flags);
+		if (IS_ERR(sg_vaddr)) {
+			/*
+			 * This should really never happen unless
+			 * the code is changed to use memory that is
+			 * not mappable in the sg. Seeing there doesn't
+			 * seem to be any error path out of here,
+			 * we can only WARN.
+			 */
+			WARN(1, "Non-mappable memory used in sg!");
+			return;
+		}
+
 		memcpy(sg_vaddr, host->bounce_buf, host->bounce_sg.length);
 		tmio_mmc_kunmap_atomic(host->sg_orig, &flags, sg_vaddr);
 	}
-- 
2.1.4

[toc] | [prev] | [next] | [standalone]


#1623399 — [PATCH 02/22] nvmet: Make use of the new sg_map helper function

FromLogan Gunthorpe <logang@deltatee.com>
Date2017-04-14 00:20 +0200
Subject[PATCH 02/22] nvmet: Make use of the new sg_map helper function
Message-ID<tvVfR-Tr-37@gated-at.bofh.it>
In reply to#1623387
This is a straight forward conversion in two places. Should kmap fail,
the code will return an INVALD_DATA error in the completion.

Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
---
 drivers/nvme/target/fabrics-cmd.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/nvme/target/fabrics-cmd.c b/drivers/nvme/target/fabrics-cmd.c
index 8bd022af..f62a634 100644
--- a/drivers/nvme/target/fabrics-cmd.c
+++ b/drivers/nvme/target/fabrics-cmd.c
@@ -122,7 +122,11 @@ static void nvmet_execute_admin_connect(struct nvmet_req *req)
 	struct nvmet_ctrl *ctrl = NULL;
 	u16 status = 0;
 
-	d = kmap(sg_page(req->sg)) + req->sg->offset;
+	d = sg_map(req->sg, SG_KMAP);
+	if (IS_ERR(d)) {
+		status = NVME_SC_SGL_INVALID_DATA;
+		goto out;
+	}
 
 	/* zero out initial completion result, assign values as needed */
 	req->rsp->result.u32 = 0;
@@ -158,7 +162,7 @@ static void nvmet_execute_admin_connect(struct nvmet_req *req)
 	req->rsp->result.u16 = cpu_to_le16(ctrl->cntlid);
 
 out:
-	kunmap(sg_page(req->sg));
+	sg_unmap(req->sg, d, SG_KMAP);
 	nvmet_req_complete(req, status);
 }
 
@@ -170,7 +174,11 @@ static void nvmet_execute_io_connect(struct nvmet_req *req)
 	u16 qid = le16_to_cpu(c->qid);
 	u16 status = 0;
 
-	d = kmap(sg_page(req->sg)) + req->sg->offset;
+	d = sg_map(req->sg, SG_KMAP);
+	if (IS_ERR(d)) {
+		status = NVME_SC_SGL_INVALID_DATA;
+		goto out;
+	}
 
 	/* zero out initial completion result, assign values as needed */
 	req->rsp->result.u32 = 0;
@@ -205,7 +213,7 @@ static void nvmet_execute_io_connect(struct nvmet_req *req)
 	pr_info("adding queue %d to ctrl %d.\n", qid, ctrl->cntlid);
 
 out:
-	kunmap(sg_page(req->sg));
+	sg_unmap(req->sg, d, SG_KMAP);
 	nvmet_req_complete(req, status);
 	return;
 
-- 
2.1.4

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | linux.kernel


csiph-web