From patchwork Mon Apr 11 21:32:37 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 8805861 Return-Path: X-Original-To: patchwork-linux-rdma@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 69986C0553 for ; Mon, 11 Apr 2016 21:33:31 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 65404201F2 for ; Mon, 11 Apr 2016 21:33:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3C891200B4 for ; Mon, 11 Apr 2016 21:33:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755184AbcDKVd2 (ORCPT ); Mon, 11 Apr 2016 17:33:28 -0400 Received: from casper.infradead.org ([85.118.1.10]:32909 "EHLO casper.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755112AbcDKVd1 (ORCPT ); Mon, 11 Apr 2016 17:33:27 -0400 Received: from [67.51.76.21] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.85_2 #1 (Red Hat Linux)) id 1apjSW-000855-3Q; Mon, 11 Apr 2016 21:33:24 +0000 From: Christoph Hellwig To: dledford@redhat.com Cc: bart.vanassche@sandisk.com, swise@opengridcomputing.com, sagi@grimberg.me, linux-rdma@vger.kernel.org, target-devel@vger.kernel.org Subject: [PATCH 09/12] target: enhance and export target_alloc_sgl/target_free_sgl Date: Mon, 11 Apr 2016 14:32:37 -0700 Message-Id: <1460410360-13104-10-git-send-email-hch@lst.de> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1460410360-13104-1-git-send-email-hch@lst.de> References: <1460410360-13104-1-git-send-email-hch@lst.de> X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The SRP target driver will need to allocate and chain it's own SGLs soon. For this export target_alloc_sgl, and add a new argument to it so that it can allocate an additional chain entry that doesn't point to a page. Also export transport_free_sgl after renaming it to target_free_sgl to free these SGLs again. Signed-off-by: Christoph Hellwig Reviewed-by: Bart Van Assche --- drivers/target/target_core_transport.c | 32 ++++++++++++++++++-------------- drivers/target/target_core_xcopy.c | 2 +- include/target/target_core_backend.h | 1 - include/target/target_core_fabric.h | 4 ++++ 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index ab2bf12..590384a 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2195,7 +2195,7 @@ queue_full: transport_handle_queue_full(cmd, cmd->se_dev); } -static inline void transport_free_sgl(struct scatterlist *sgl, int nents) +void target_free_sgl(struct scatterlist *sgl, int nents) { struct scatterlist *sg; int count; @@ -2205,6 +2205,7 @@ static inline void transport_free_sgl(struct scatterlist *sgl, int nents) kfree(sgl); } +EXPORT_SYMBOL(target_free_sgl); static inline void transport_reset_sgl_orig(struct se_cmd *cmd) { @@ -2225,7 +2226,7 @@ static inline void transport_reset_sgl_orig(struct se_cmd *cmd) static inline void transport_free_pages(struct se_cmd *cmd) { if (!(cmd->se_cmd_flags & SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC)) { - transport_free_sgl(cmd->t_prot_sg, cmd->t_prot_nents); + target_free_sgl(cmd->t_prot_sg, cmd->t_prot_nents); cmd->t_prot_sg = NULL; cmd->t_prot_nents = 0; } @@ -2236,7 +2237,7 @@ static inline void transport_free_pages(struct se_cmd *cmd) * SG_TO_MEM_NOALLOC to function with COMPARE_AND_WRITE */ if (cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE) { - transport_free_sgl(cmd->t_bidi_data_sg, + target_free_sgl(cmd->t_bidi_data_sg, cmd->t_bidi_data_nents); cmd->t_bidi_data_sg = NULL; cmd->t_bidi_data_nents = 0; @@ -2246,11 +2247,11 @@ static inline void transport_free_pages(struct se_cmd *cmd) } transport_reset_sgl_orig(cmd); - transport_free_sgl(cmd->t_data_sg, cmd->t_data_nents); + target_free_sgl(cmd->t_data_sg, cmd->t_data_nents); cmd->t_data_sg = NULL; cmd->t_data_nents = 0; - transport_free_sgl(cmd->t_bidi_data_sg, cmd->t_bidi_data_nents); + target_free_sgl(cmd->t_bidi_data_sg, cmd->t_bidi_data_nents); cmd->t_bidi_data_sg = NULL; cmd->t_bidi_data_nents = 0; } @@ -2324,20 +2325,22 @@ EXPORT_SYMBOL(transport_kunmap_data_sg); int target_alloc_sgl(struct scatterlist **sgl, unsigned int *nents, u32 length, - bool zero_page) + bool zero_page, bool chainable) { struct scatterlist *sg; struct page *page; gfp_t zero_flag = (zero_page) ? __GFP_ZERO : 0; - unsigned int nent; + unsigned int nalloc, nent; int i = 0; - nent = DIV_ROUND_UP(length, PAGE_SIZE); - sg = kmalloc(sizeof(struct scatterlist) * nent, GFP_KERNEL); + nalloc = nent = DIV_ROUND_UP(length, PAGE_SIZE); + if (chainable) + nalloc++; + sg = kmalloc_array(nalloc, sizeof(struct scatterlist), GFP_KERNEL); if (!sg) return -ENOMEM; - sg_init_table(sg, nent); + sg_init_table(sg, nalloc); while (length) { u32 page_len = min_t(u32, length, PAGE_SIZE); @@ -2361,6 +2364,7 @@ out: kfree(sg); return -ENOMEM; } +EXPORT_SYMBOL(target_alloc_sgl); /* * Allocate any required resources to execute the command. For writes we @@ -2376,7 +2380,7 @@ transport_generic_new_cmd(struct se_cmd *cmd) if (cmd->prot_op != TARGET_PROT_NORMAL && !(cmd->se_cmd_flags & SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC)) { ret = target_alloc_sgl(&cmd->t_prot_sg, &cmd->t_prot_nents, - cmd->prot_length, true); + cmd->prot_length, true, false); if (ret < 0) return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; } @@ -2401,13 +2405,13 @@ transport_generic_new_cmd(struct se_cmd *cmd) ret = target_alloc_sgl(&cmd->t_bidi_data_sg, &cmd->t_bidi_data_nents, - bidi_length, zero_flag); + bidi_length, zero_flag, false); if (ret < 0) return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; } ret = target_alloc_sgl(&cmd->t_data_sg, &cmd->t_data_nents, - cmd->data_length, zero_flag); + cmd->data_length, zero_flag, false); if (ret < 0) return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; } else if ((cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE) && @@ -2421,7 +2425,7 @@ transport_generic_new_cmd(struct se_cmd *cmd) ret = target_alloc_sgl(&cmd->t_bidi_data_sg, &cmd->t_bidi_data_nents, - caw_length, zero_flag); + caw_length, zero_flag, false); if (ret < 0) return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; } diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c index 47fe94e..75cd854 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c @@ -563,7 +563,7 @@ static int target_xcopy_setup_pt_cmd( if (alloc_mem) { rc = target_alloc_sgl(&cmd->t_data_sg, &cmd->t_data_nents, - cmd->data_length, false); + cmd->data_length, false, false); if (rc < 0) { ret = rc; goto out; diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index 28ee5c2..d8ab510 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h @@ -85,7 +85,6 @@ extern struct configfs_attribute *passthrough_attrib_attrs[]; void *transport_kmap_data_sg(struct se_cmd *); void transport_kunmap_data_sg(struct se_cmd *); /* core helpers also used by xcopy during internal command setup */ -int target_alloc_sgl(struct scatterlist **, unsigned int *, u32, bool); sense_reason_t transport_generic_map_mem_to_cmd(struct se_cmd *, struct scatterlist *, u32, struct scatterlist *, u32); diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 8ff6d40..78d88f0 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -185,6 +185,10 @@ int core_tpg_set_initiator_node_tag(struct se_portal_group *, int core_tpg_register(struct se_wwn *, struct se_portal_group *, int); int core_tpg_deregister(struct se_portal_group *); +int target_alloc_sgl(struct scatterlist **sgl, unsigned int *nents, + u32 length, bool zero_page, bool chainable); +void target_free_sgl(struct scatterlist *sgl, int nents); + /* * The LIO target core uses DMA_TO_DEVICE to mean that data is going * to the target (eg handling a WRITE) and DMA_FROM_DEVICE to mean