Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934654AbdC3WNZ (ORCPT ); Thu, 30 Mar 2017 18:13:25 -0400 Received: from ale.deltatee.com ([207.54.116.67]:44303 "EHLO ale.deltatee.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750903AbdC3WNX (ORCPT ); Thu, 30 Mar 2017 18:13:23 -0400 From: Logan Gunthorpe To: Christoph Hellwig , Sagi Grimberg , "James E.J. Bottomley" , "Martin K. Petersen" , Jens Axboe , Steve Wise , Stephen Bates , Max Gurtovoy , Dan Williams , Keith Busch , Jason Gunthorpe Cc: linux-pci@vger.kernel.org, linux-scsi@vger.kernel.org, linux-nvme@lists.infradead.org, linux-rdma@vger.kernel.org, linux-nvdimm@ml01.01.org, linux-kernel@vger.kernel.org, Logan Gunthorpe Date: Thu, 30 Mar 2017 16:12:36 -0600 Message-Id: <1490911959-5146-6-git-send-email-logang@deltatee.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1490911959-5146-1-git-send-email-logang@deltatee.com> References: <1490911959-5146-1-git-send-email-logang@deltatee.com> X-SA-Exim-Connect-IP: 172.16.1.31 X-SA-Exim-Rcpt-To: hch@lst.de, sagi@grimberg.me, jejb@linux.vnet.ibm.com, martin.petersen@oracle.com, axboe@kernel.dk, swise@opengridcomputing.com, sbates@raithlin.com, maxg@mellanox.com, dan.j.williams@intel.com, keith.busch@intel.com, jgunthorpe@obsidianresearch.com, linux-nvme@lists.infradead.org, linux-nvdimm@lists.01.org, linux-pci@vger.kernel.org, linux-scsi@vger.kernel.org, linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org, logang@deltatee.com X-SA-Exim-Mail-From: gunthorp@deltatee.com Subject: [RFC 5/8] scatterlist: Modify SG copy functions to support io memory. X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on ale.deltatee.com) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6399 Lines: 181 Now that we are using p2pmem SG buffers we occasionally have to copy to and from this memory. For this, we add an iomem flag to sg_copy_buffer for copying with iomemcpy. We also add the sg_iocopy_ variants to use this more easily. Signed-off-by: Logan Gunthorpe Signed-off-by: Stephen Bates Signed-off-by: Steve Wise --- drivers/scsi/scsi_debug.c | 7 ++--- include/linux/scatterlist.h | 7 ++++- lib/scatterlist.c | 64 ++++++++++++++++++++++++++++++++++++++------- 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 17249c3..70c0d9f 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1309,7 +1309,7 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) int lu_id_num, port_group_id, target_dev_id, len; char lu_id_str[6]; int host_no = devip->sdbg_host->shost->host_no; - + port_group_id = (((host_no + 1) & 0x7f) << 8) + (devip->channel & 0x7f); if (sdebug_vpd_use_hostno == 0) @@ -2381,14 +2381,15 @@ static int do_device_access(struct scsi_cmnd *scmd, u64 lba, u32 num, ret = sg_copy_buffer(sdb->table.sgl, sdb->table.nents, fake_storep + (block * sdebug_sector_size), - (num - rest) * sdebug_sector_size, 0, do_write); + (num - rest) * sdebug_sector_size, 0, do_write, false); if (ret != (num - rest) * sdebug_sector_size) return ret; if (rest) { ret += sg_copy_buffer(sdb->table.sgl, sdb->table.nents, fake_storep, rest * sdebug_sector_size, - (num - rest) * sdebug_sector_size, do_write); + (num - rest) * sdebug_sector_size, do_write, + false); } return ret; diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index cb3c8fe..030b92b 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -267,7 +267,7 @@ int sg_alloc_table_from_pages(struct sg_table *sgt, gfp_t gfp_mask); size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, void *buf, - size_t buflen, off_t skip, bool to_buffer); + size_t buflen, off_t skip, bool to_buffer, bool iomem); size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents, const void *buf, size_t buflen); @@ -279,6 +279,11 @@ size_t sg_pcopy_from_buffer(struct scatterlist *sgl, unsigned int nents, size_t sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents, void *buf, size_t buflen, off_t skip); +size_t sg_iocopy_from_buffer(struct scatterlist *sgl, unsigned int nents, + const void *buf, size_t buflen); +size_t sg_iocopy_to_buffer(struct scatterlist *sgl, unsigned int nents, + void *buf, size_t buflen); + /* * Maximum number of entries that will be allocated in one piece, if * a list larger than this is required then chaining will be utilized. diff --git a/lib/scatterlist.c b/lib/scatterlist.c index c6cf822..22abd94 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -647,7 +647,7 @@ EXPORT_SYMBOL(sg_miter_stop); * **/ size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, void *buf, - size_t buflen, off_t skip, bool to_buffer) + size_t buflen, off_t skip, bool to_buffer, bool iomem) { unsigned int offset = 0; struct sg_mapping_iter miter; @@ -668,10 +668,17 @@ size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, void *buf, len = min(miter.length, buflen - offset); - if (to_buffer) - memcpy(buf + offset, miter.addr, len); - else - memcpy(miter.addr, buf + offset, len); + if (iomem) { + if (to_buffer) + memcpy_fromio(buf + offset, miter.addr, len); + else + memcpy_toio(miter.addr, buf + offset, len); + } else { + if (to_buffer) + memcpy(buf + offset, miter.addr, len); + else + memcpy(miter.addr, buf + offset, len); + } offset += len; } @@ -695,7 +702,8 @@ EXPORT_SYMBOL(sg_copy_buffer); size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents, const void *buf, size_t buflen) { - return sg_copy_buffer(sgl, nents, (void *)buf, buflen, 0, false); + return sg_copy_buffer(sgl, nents, (void *)buf, buflen, 0, false, + false); } EXPORT_SYMBOL(sg_copy_from_buffer); @@ -712,7 +720,7 @@ EXPORT_SYMBOL(sg_copy_from_buffer); size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents, void *buf, size_t buflen) { - return sg_copy_buffer(sgl, nents, buf, buflen, 0, true); + return sg_copy_buffer(sgl, nents, buf, buflen, 0, true, false); } EXPORT_SYMBOL(sg_copy_to_buffer); @@ -730,7 +738,8 @@ EXPORT_SYMBOL(sg_copy_to_buffer); size_t sg_pcopy_from_buffer(struct scatterlist *sgl, unsigned int nents, const void *buf, size_t buflen, off_t skip) { - return sg_copy_buffer(sgl, nents, (void *)buf, buflen, skip, false); + return sg_copy_buffer(sgl, nents, (void *)buf, buflen, skip, false, + false); } EXPORT_SYMBOL(sg_pcopy_from_buffer); @@ -748,6 +757,43 @@ EXPORT_SYMBOL(sg_pcopy_from_buffer); size_t sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents, void *buf, size_t buflen, off_t skip) { - return sg_copy_buffer(sgl, nents, buf, buflen, skip, true); + return sg_copy_buffer(sgl, nents, buf, buflen, skip, true, false); } EXPORT_SYMBOL(sg_pcopy_to_buffer); + +/** + * sg_iocopy_from_buffer - Copy from a linear buffer to an SG list containing + * IO memory. + * @sgl: The SG list + * @nents: Number of SG entries + * @buf: Where to copy from + * @buflen: The number of bytes to copy + * + * Returns the number of copied bytes. + * + **/ +size_t sg_iocopy_from_buffer(struct scatterlist *sgl, unsigned int nents, + const void *buf, size_t buflen) +{ + return sg_copy_buffer(sgl, nents, (void *)buf, buflen, 0, false, + true); +} +EXPORT_SYMBOL(sg_iocopy_from_buffer); + +/** + * sg_iocopy_to_buffer - Copy from an SG list containing IO memory + * to a linear buffer + * @sgl: The SG list + * @nents: Number of SG entries + * @buf: Where to copy to + * @buflen: The number of bytes to copy + * + * Returns the number of copied bytes. + * + **/ +size_t sg_iocopy_to_buffer(struct scatterlist *sgl, unsigned int nents, + void *buf, size_t buflen) +{ + return sg_copy_buffer(sgl, nents, buf, buflen, 0, true, true); +} +EXPORT_SYMBOL(sg_iocopy_to_buffer); -- 2.1.4