Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp501720pxb; Tue, 3 Nov 2020 05:25:18 -0800 (PST) X-Google-Smtp-Source: ABdhPJzTaYV076V954/pgRng+fEwxbU5nPmj7QQZL0w0r8XB7dquwn4SO6nc8GbK58jjM7vcpvpF X-Received: by 2002:a50:d5dd:: with SMTP id g29mr5384268edj.344.1604409917969; Tue, 03 Nov 2020 05:25:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1604409917; cv=none; d=google.com; s=arc-20160816; b=f8q5feht9iT4wPOK5rGxaoAAtzMW/JPWv3XmBBjvh54QrvYawK/j9a/B8PQMxy+nD6 eeB6yrIwoRHnfs+z3ayoPDT4q9fIIDzdoy2mYiAdcKd5raIJm0+ztigv+RqNV+8ZoT9c YWLTYiU2dXPyR7KxndFMGdgftFayH2fqkDxIS3GUzF3f/7uac1fNaNua2E8JuozvHm/h 0E7WHe+cQhlAF5w++PGq7pi03UHLoc8ZxidUvQdONsxSm6VFQcGplKDnl4guiq3+15Sy PQLGT7xoADN68ZCOY19PxEvabIo9oB9pYjs8baZBMD1fifrtcUz3ULRWg8zvNJ39sCa1 h9TQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:content-language :in-reply-to:mime-version:user-agent:date:message-id:from:references :cc:to:subject:dkim-signature; bh=Y51Nz46vqk7FKl0bA40zhWT3Uvjs83z5KYe+jNaFjB4=; b=vkFyLzMLh2w7v/DnDcrNDzZ4iEEZMUuXNORxCsIQvVnGJULIBcghCJXAN0d/m6szWI UExEE82YW23cow6fR9hXqANyvt98ZoV9FfmS7qv8vFFMYDYstuUIzRi+3Pg25KiMNGbL 1P8jWNY3zatRccq7VzTKJp1ynzRsLx1l+ZXVa3fwfSIo9L8LTKcq+N4tZ0z1V4WoRiVh 9BZwcsU00p6xLTPgWsSbHrBTZ3Ja2ivflA+drCVQibpeQJCKTn8zwIWcIBCr2ZuMMJNq Djyf9Ogi8kV0MPo/JPQ+r9Ba7Shgk+AYoZfCNOQ2xpFiAFo+NChgNG1aNEx4cwiPJeNj /4kQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=FSNu+p+Q; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d6si8940227edo.498.2020.11.03.05.24.54; Tue, 03 Nov 2020 05:25:17 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=FSNu+p+Q; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729211AbgKCNWf (ORCPT + 99 others); Tue, 3 Nov 2020 08:22:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36776 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729205AbgKCNWe (ORCPT ); Tue, 3 Nov 2020 08:22:34 -0500 Received: from mail-ej1-x644.google.com (mail-ej1-x644.google.com [IPv6:2a00:1450:4864:20::644]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6F0C3C0613D1; Tue, 3 Nov 2020 05:22:34 -0800 (PST) Received: by mail-ej1-x644.google.com with SMTP id oq3so22208030ejb.7; Tue, 03 Nov 2020 05:22:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=Y51Nz46vqk7FKl0bA40zhWT3Uvjs83z5KYe+jNaFjB4=; b=FSNu+p+Q3mEiAZKZ77h8iLZLJtVMQHcmI4UUo3IgyiX2sVL4bb5OEpYuRly/wH5wIM zlSO13IinpDsmnBHhQ2ZSF5fPZ8ZZYk1P95ELPBgYTHhRgoGjMvmLgyVhA8GNDqbVo7O oAib7Cf0efZZsgvdLX0/Ojw0KzBU+VxVKzXltTPOkgypInCpRxJ262SLw4vEKkmM1q/B bOj0JhjdaPtoCxmILYFgJzMGgr6Lxlwft/1locGzFuNbomL1ZaJiLiNB6UztP1gHNZ6I KkClh4MZNoKm1B69bSm20tRB9AzO6v4ydz2ENz7xHrAofmlP5HUk2MFgZE4MkSz9kXfg rzeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=Y51Nz46vqk7FKl0bA40zhWT3Uvjs83z5KYe+jNaFjB4=; b=Vao8dSJaFn4GUZGwKU9canJ/b181bgpHADRCFicjYmr07C198k1agid269lMdXJrzy vQVJliA360RsT/hEXEz65SSaNIXrxjV6f0eOttGjTZxb6p49TVZGX8kpgRFLAyfBy6Mq KtuGGbkKxzQsHpyLFEQYlL3Id+ZyL6WHFIH6Pi+BgCuI1XY3ZomAs9ZBjzh3dfQqVOwR KpIiOo/StP5jqmAmzw7/6ULKas6ubBEhVDCNvqlEpD9aanwAl7BuUDtHPJBc62x/oFjk 4AXlqbHYtCYtb47xpYYz+ugu729Dmhkofq1NOS4I7sLmUszS3qxHdCryIZqXFwQeerKj AJ6w== X-Gm-Message-State: AOAM532IZgrFcOPDSub2zCr8KM2SvstXfcF9tI8tl+l9by5jff4CCKr1 dqknpcRBK2c1tvTNyJIMmwI= X-Received: by 2002:a17:906:854b:: with SMTP id h11mr11646527ejy.273.1604409753205; Tue, 03 Nov 2020 05:22:33 -0800 (PST) Received: from [192.168.178.40] ([188.192.138.212]) by smtp.gmail.com with ESMTPSA id p8sm6091833ejn.5.2020.11.03.05.22.32 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 03 Nov 2020 05:22:32 -0800 (PST) Subject: Re: [PATCH v3 2/4] scatterlist: add sgl_copy_sgl() function To: Douglas Gilbert , linux-scsi@vger.kernel.org, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org Cc: martin.petersen@oracle.com, axboe@kernel.dk, bvanassche@acm.org References: <20201019191928.77845-1-dgilbert@interlog.com> <20201019191928.77845-3-dgilbert@interlog.com> From: Bodo Stroesser Message-ID: Date: Tue, 3 Nov 2020 14:22:31 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: <20201019191928.77845-3-dgilbert@interlog.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Am 19.10.20 um 21:19 schrieb Douglas Gilbert: > Both the SCSI and NVMe subsystems receive user data from the block > layer in scatterlist_s (aka scatter gather lists (sgl) which are > often arrays). If drivers in those subsystems represent storage > (e.g. a ramdisk) or cache "hot" user data then they may also > choose to use scatterlist_s. Currently there are no sgl to sgl > operations in the kernel. Start with a sgl to sgl copy. Stops > when the first of the number of requested bytes to copy, or the > source sgl, or the destination sgl is exhausted. So the > destination sgl will _not_ grow. > > Signed-off-by: Douglas Gilbert > --- > include/linux/scatterlist.h | 4 ++ > lib/scatterlist.c | 75 +++++++++++++++++++++++++++++++++++++ > 2 files changed, 79 insertions(+) > > diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h > index 80178afc2a4a..6649414c0749 100644 > --- a/include/linux/scatterlist.h > +++ b/include/linux/scatterlist.h > @@ -321,6 +321,10 @@ size_t sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents, > size_t sg_zero_buffer(struct scatterlist *sgl, unsigned int nents, > size_t buflen, off_t skip); > > +size_t sgl_copy_sgl(struct scatterlist *d_sgl, unsigned int d_nents, off_t d_skip, > + struct scatterlist *s_sgl, unsigned int s_nents, off_t s_skip, > + size_t n_bytes); > + > /* > * 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 d5770e7f1030..1f9e093ad7da 100644 > --- a/lib/scatterlist.c > +++ b/lib/scatterlist.c > @@ -974,3 +974,78 @@ size_t sg_zero_buffer(struct scatterlist *sgl, unsigned int nents, > return offset; > } > EXPORT_SYMBOL(sg_zero_buffer); > + > +/** > + * sgl_copy_sgl - Copy over a destination sgl from a source sgl > + * @d_sgl: Destination sgl > + * @d_nents: Number of SG entries in destination sgl > + * @d_skip: Number of bytes to skip in destination before starting > + * @s_sgl: Source sgl > + * @s_nents: Number of SG entries in source sgl > + * @s_skip: Number of bytes to skip in source before starting > + * @n_bytes: The (maximum) number of bytes to copy > + * > + * Returns: > + * The number of copied bytes. > + * > + * Notes: > + * Destination arguments appear before the source arguments, as with memcpy(). > + * > + * Stops copying if either d_sgl, s_sgl or n_bytes is exhausted. > + * > + * Since memcpy() is used, overlapping copies (where d_sgl and s_sgl belong > + * to the same sgl and the copy regions overlap) are not supported. > + * > + * Large copies are broken into copy segments whose sizes may vary. Those > + * copy segment sizes are chosen by the min3() statement in the code below. > + * Since SG_MITER_ATOMIC is used for both sides, each copy segment is started > + * with kmap_atomic() [in sg_miter_next()] and completed with kunmap_atomic() > + * [in sg_miter_stop()]. This means pre-emption is inhibited for relatively > + * short periods even in very large copies. > + * > + * If d_skip is large, potentially spanning multiple d_nents then some > + * integer arithmetic to adjust d_sgl may improve performance. For example > + * if d_sgl is built using sgl_alloc_order(chainable=false) then the sgl > + * will be an array with equally sized segments facilitating that > + * arithmetic. The suggestion applies to s_skip, s_sgl and s_nents as well. > + * > + **/ > +size_t sgl_copy_sgl(struct scatterlist *d_sgl, unsigned int d_nents, off_t d_skip, > + struct scatterlist *s_sgl, unsigned int s_nents, off_t s_skip, > + size_t n_bytes) > +{ > + size_t len; > + size_t offset = 0; > + struct sg_mapping_iter d_iter, s_iter; > + > + if (n_bytes == 0) > + return 0; > + sg_miter_start(&s_iter, s_sgl, s_nents, SG_MITER_ATOMIC | SG_MITER_FROM_SG); > + sg_miter_start(&d_iter, d_sgl, d_nents, SG_MITER_ATOMIC | SG_MITER_TO_SG); > + if (!sg_miter_skip(&s_iter, s_skip)) > + goto fini; > + if (!sg_miter_skip(&d_iter, d_skip)) > + goto fini; > + > + while (offset < n_bytes) { > + if (!sg_miter_next(&s_iter)) > + break; > + if (!sg_miter_next(&d_iter)) > + break; > + len = min3(d_iter.length, s_iter.length, n_bytes - offset); > + > + memcpy(d_iter.addr, s_iter.addr, len); > + offset += len; > + /* LIFO order (stop d_iter before s_iter) needed with SG_MITER_ATOMIC */ > + d_iter.consumed = len; > + sg_miter_stop(&d_iter); > + s_iter.consumed = len; > + sg_miter_stop(&s_iter); > + } > +fini: > + sg_miter_stop(&d_iter); > + sg_miter_stop(&s_iter); > + return offset; > +} > +EXPORT_SYMBOL(sgl_copy_sgl); > + > Reviewed-by: Bodo Stroesser