From patchwork Thu Feb 21 13:58:00 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 15012 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 9ADDC23F7C for ; Thu, 21 Feb 2013 13:58:25 +0000 (UTC) Received: from mail-vb0-f42.google.com (mail-vb0-f42.google.com [209.85.212.42]) by fiordland.canonical.com (Postfix) with ESMTP id 2CF38A18092 for ; Thu, 21 Feb 2013 13:58:25 +0000 (UTC) Received: by mail-vb0-f42.google.com with SMTP id ff1so2662551vbb.29 for ; Thu, 21 Feb 2013 05:58:24 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:x-extloop1:x-ironport-av:from:to:date:message-id :x-mailer:in-reply-to:references:cc:subject:x-beenthere :x-mailman-version:precedence:list-id:list-unsubscribe:list-archive :list-post:list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:sender:errors-to:x-gm-message-state; bh=SyxOqIlVHN3kihWotWNBSER3aXom2v77y2FXuxQ0vIU=; b=hAha5WdpOlLUmmHEeLsxQKTNgp96MVE+fK0FKPJVFqPysvi3pOUfmZMvZ0eqwjuaE7 J/sZ8fFNtdPpSx5H2bvvgyEq7mHUMFygXt9zIdx+nlg4KEpFkP8u7HqGKHK/kA/50YcH NUblw/LAkndrjKqwbtF1ouniqPzcCzsr3/r0mbwltkz9BSLD2KGzPHCQ1B2Z2kcd2vlQ FZEr/o1C+Ksc71U2hJWvVh8nPaNE//iSFam+tn+vCRNArnvzCRjEaiceg1PCTwlUlf2o h1fPQNRv5lVB8tzJIe54WxFfjbVF42YhCs+kguhomxKRn6+/8NF7xTesMvyQ7HLW2e+t c0og== X-Received: by 10.58.205.179 with SMTP id lh19mr10012394vec.7.1361455104551; Thu, 21 Feb 2013 05:58:24 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.58.145.101 with SMTP id st5csp18253veb; Thu, 21 Feb 2013 05:58:23 -0800 (PST) X-Received: by 10.204.147.23 with SMTP id j23mr10620533bkv.76.1361455102098; Thu, 21 Feb 2013 05:58:22 -0800 (PST) Received: from mombin.canonical.com (mombin.canonical.com. [91.189.95.16]) by mx.google.com with ESMTP id gc18si1561131bkc.171.2013.02.21.05.58.16; Thu, 21 Feb 2013 05:58:22 -0800 (PST) Received-SPF: neutral (google.com: 91.189.95.16 is neither permitted nor denied by best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org) client-ip=91.189.95.16; Authentication-Results: mx.google.com; spf=neutral (google.com: 91.189.95.16 is neither permitted nor denied by best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org) smtp.mail=linaro-mm-sig-bounces@lists.linaro.org Received: from localhost ([127.0.0.1] helo=mombin.canonical.com) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1U8Wf4-0000s7-V0; Thu, 21 Feb 2013 13:58:11 +0000 Received: from mga11.intel.com ([192.55.52.93]) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1U8Wf2-0000s2-GB for linaro-mm-sig@lists.linaro.org; Thu, 21 Feb 2013 13:58:09 +0000 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 21 Feb 2013 05:58:04 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.84,709,1355126400"; d="scan'208";a="294153449" Received: from intelbox.fi.intel.com (HELO localhost) ([10.237.72.52]) by fmsmga002.fm.intel.com with ESMTP; 21 Feb 2013 05:58:01 -0800 From: Imre Deak To: linux-kernel@vger.kernel.org Date: Thu, 21 Feb 2013 15:58:00 +0200 Message-Id: <1361455080-23667-1-git-send-email-imre.deak@intel.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1360768224-18163-2-git-send-email-imre.deak@intel.com> References: <1360768224-18163-2-git-send-email-imre.deak@intel.com> Cc: James Hogan , Maxim Levitsky , linaro-mm-sig@lists.linaro.org, Tejun Heo , Andrew Morton , Chris Ball Subject: [Linaro-mm-sig] [PATCH v4] lib/scatterlist: use page iterator in the mapping iterator X-BeenThere: linaro-mm-sig@lists.linaro.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Unified memory management interest group." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linaro-mm-sig-bounces@lists.linaro.org Errors-To: linaro-mm-sig-bounces@lists.linaro.org X-Gm-Message-State: ALoCoQlls2sH77O+YSFPoBqAHQfHDNqv8BWZdmMCWW1aS8Q8Bgo4rnQhScBPUfGmeRC23F5PECGh For better code reuse use the newly added page iterator to iterate through the pages. The offset, length within the page is still calculated by the mapping iterator as well as the actual mapping. Idea from Tejun Heo. v1-v3: - original version v4: - The dw_mmc driver used sg_mapping_iter::__sg, which was marked as internal and moved by this patch to the new sg_page_iter struct. This caused a compile time breakage for the driver. Fix this by making sg_mapping_iter::piter a public interface and making the driver use sg_mapping_iter::piter.sg instead of sg_mapping_iter::__sg. Thanks to James Hogan for pointing this out. Signed-off-by: Imre Deak Cc: Maxim Levitsky Cc: Tejun Heo Cc: Daniel Vetter Signed-off-by: Andrew Morton --- drivers/mmc/host/dw_mmc.c | 4 ++-- include/linux/scatterlist.h | 6 +++--- lib/scatterlist.c | 46 ++++++++++++++++++++----------------------- 3 files changed, 26 insertions(+), 30 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 323c502..6b89fde 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1445,7 +1445,7 @@ static void dw_mci_read_data_pio(struct dw_mci *host) if (!sg_miter_next(sg_miter)) goto done; - host->sg = sg_miter->__sg; + host->sg = sg_miter->piter.sg; buf = sg_miter->addr; remain = sg_miter->length; offset = 0; @@ -1500,7 +1500,7 @@ static void dw_mci_write_data_pio(struct dw_mci *host) if (!sg_miter_next(sg_miter)) goto done; - host->sg = sg_miter->__sg; + host->sg = sg_miter->piter.sg; buf = sg_miter->addr; remain = sg_miter->length; offset = 0; diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index 788a853..2d8bdae 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -293,11 +293,11 @@ struct sg_mapping_iter { void *addr; /* pointer to the mapped area */ size_t length; /* length of the mapped area */ size_t consumed; /* number of consumed bytes */ + struct sg_page_iter piter; /* page iterator */ /* these are internal states, keep away */ - struct scatterlist *__sg; /* current entry */ - unsigned int __nents; /* nr of remaining entries */ - unsigned int __offset; /* offset within sg */ + unsigned int __offset; /* offset within page */ + unsigned int __remaining; /* remaining bytes on page */ unsigned int __flags; }; diff --git a/lib/scatterlist.c b/lib/scatterlist.c index a1d1564..2645acf 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -449,9 +449,7 @@ void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl, { memset(miter, 0, sizeof(struct sg_mapping_iter)); - miter->__sg = sgl; - miter->__nents = nents; - miter->__offset = 0; + __sg_page_iter_start(&miter->piter, sgl, nents, 0); WARN_ON(!(flags & (SG_MITER_TO_SG | SG_MITER_FROM_SG))); miter->__flags = flags; } @@ -476,36 +474,33 @@ EXPORT_SYMBOL(sg_miter_start); */ bool sg_miter_next(struct sg_mapping_iter *miter) { - unsigned int off, len; - - /* check for end and drop resources from the last iteration */ - if (!miter->__nents) - return false; - sg_miter_stop(miter); - /* get to the next sg if necessary. __offset is adjusted by stop */ - while (miter->__offset == miter->__sg->length) { - if (--miter->__nents) { - miter->__sg = sg_next(miter->__sg); - miter->__offset = 0; - } else + /* + * Get to the next page if necessary. + * __remaining, __offset is adjusted by sg_miter_stop + */ + if (!miter->__remaining) { + struct scatterlist *sg; + unsigned long pgoffset; + + if (!__sg_page_iter_next(&miter->piter)) return false; - } - /* map the next page */ - off = miter->__sg->offset + miter->__offset; - len = miter->__sg->length - miter->__offset; + sg = miter->piter.sg; + pgoffset = miter->piter.sg_pgoffset; - miter->page = nth_page(sg_page(miter->__sg), off >> PAGE_SHIFT); - off &= ~PAGE_MASK; - miter->length = min_t(unsigned int, len, PAGE_SIZE - off); - miter->consumed = miter->length; + miter->__offset = pgoffset ? 0 : sg->offset; + miter->__remaining = sg->offset + sg->length - + (pgoffset << PAGE_SHIFT) - miter->__offset; + } + miter->page = miter->piter.page; + miter->consumed = miter->length = miter->__remaining; if (miter->__flags & SG_MITER_ATOMIC) - miter->addr = kmap_atomic(miter->page) + off; + miter->addr = kmap_atomic(miter->page) + miter->__offset; else - miter->addr = kmap(miter->page) + off; + miter->addr = kmap(miter->page) + miter->__offset; return true; } @@ -532,6 +527,7 @@ void sg_miter_stop(struct sg_mapping_iter *miter) /* drop resources from the last iteration */ if (miter->addr) { miter->__offset += miter->consumed; + miter->__remaining -= miter->consumed; if (miter->__flags & SG_MITER_TO_SG) flush_kernel_dcache_page(miter->page);