From patchwork Mon Feb 11 16:32:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 14735 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 CA5EA23E33 for ; Mon, 11 Feb 2013 16:32:47 +0000 (UTC) Received: from mail-ve0-f181.google.com (mail-ve0-f181.google.com [209.85.128.181]) by fiordland.canonical.com (Postfix) with ESMTP id 6317DA18952 for ; Mon, 11 Feb 2013 16:32:47 +0000 (UTC) Received: by mail-ve0-f181.google.com with SMTP id d10so5208673vea.26 for ; Mon, 11 Feb 2013 08:32:46 -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=1Q1oDnn46tjJXIuO4tvjHQLKc1rTX7i0/my65yAnN6w=; b=TzVzgXTh3+zwr8Yuc81DpEGHIuttMbzmgf0s+Blu3OhyE+r89rOYM8PYoANntGK2Ez 1YLLsDc95H3zILSYW1MG7ywcoRWQlxU97EVFuRpt792ld8mryx7DZ7WaEZmYDoABHr/Q j0H3D7w5AWY2kR/e0M5tY2E/r6ujHb8DMYtepdWOHhL+LY0IOShJPGfJmee1y9inMxd1 SFqJaDaEmvXl2NUcjg3At/5HHKGI8xpZoTZpqNm/ES59010EBx6w6ng4VdHvPNgHlsOP 9VeQhKdkobDoJSwVvQjJD7sVzp9bmzmfkeJKFl3bdU7VTRi/5cmzqc7g1lPuzyNLyp5p uYnA== X-Received: by 10.220.151.141 with SMTP id c13mr19913303vcw.64.1360600366874; Mon, 11 Feb 2013 08:32:46 -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.252.8 with SMTP id zo8csp106024vec; Mon, 11 Feb 2013 08:32:46 -0800 (PST) X-Received: by 10.205.122.80 with SMTP id gf16mr4296871bkc.130.1360600365070; Mon, 11 Feb 2013 08:32:45 -0800 (PST) Received: from mombin.canonical.com (mombin.canonical.com. [91.189.95.16]) by mx.google.com with ESMTP id gy7si29158129bkc.254.2013.02.11.08.32.30; Mon, 11 Feb 2013 08:32:45 -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 1U4wIt-0003yc-1i; Mon, 11 Feb 2013 16:32:27 +0000 Received: from mga03.intel.com ([143.182.124.21]) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1U4wIq-0003yW-Tr for linaro-mm-sig@lists.linaro.org; Mon, 11 Feb 2013 16:32:25 +0000 Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga101.ch.intel.com with ESMTP; 11 Feb 2013 08:32:23 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.84,643,1355126400"; d="scan'208";a="255486351" Received: from ideak-desk.fi.intel.com (HELO localhost) ([10.237.72.52]) by azsmga001.ch.intel.com with ESMTP; 11 Feb 2013 08:32:17 -0800 From: Imre Deak To: linux-kernel@vger.kernel.org Date: Mon, 11 Feb 2013 18:32:16 +0200 Message-Id: <1360600336-24798-1-git-send-email-imre.deak@intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1353590706-1366-5-git-send-email-imre.deak@intel.com> References: <1353590706-1366-5-git-send-email-imre.deak@intel.com> Cc: Tejun Heo , Andrew Morton , linaro-mm-sig@lists.linaro.org, Maxim Levitsky Subject: [Linaro-mm-sig] [PATCH] lib/scatterlist: add simple page 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: ALoCoQk5VIhGwSVTabEcwn7Mkkx/2taoGIHIruWkMDZJkS70RKfe3vkQ1o1oOjWBZ4EVpxHqpSO5 Add an iterator to walk through a scatter list a page at a time starting at a specific page offset. As opposed to the mapping iterator this is meant to be small, performing well even in simple loops like collecting all pages on the scatterlist into an array or setting up an iommu table based on the pages' DMA address. Signed-off-by: Imre Deak --- include/linux/scatterlist.h | 48 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) [ Resending with proper email addresses. ] diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index 4bd6c06..d22851c 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -231,6 +231,54 @@ size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents, */ #define SG_MAX_SINGLE_ALLOC (PAGE_SIZE / sizeof(struct scatterlist)) +struct sg_page_iter { + struct scatterlist *sg; + int sg_pgoffset; + struct page *page; +}; + +static inline int +sg_page_cnt(struct scatterlist *sg) +{ + BUG_ON(sg->offset || sg->length & ~PAGE_MASK); + + return sg->length >> PAGE_SHIFT; +} + +static inline void +sg_page_iter_next(struct sg_page_iter *iter) +{ + while (iter->sg && iter->sg_pgoffset >= sg_page_cnt(iter->sg)) { + iter->sg_pgoffset -= sg_page_cnt(iter->sg); + iter->sg = sg_next(iter->sg); + } + + if (iter->sg) { + iter->page = nth_page(sg_page(iter->sg), iter->sg_pgoffset); + iter->sg_pgoffset++; + } +} + +static inline void +sg_page_iter_start(struct sg_page_iter *iter, struct scatterlist *sglist, + unsigned long pgoffset) +{ + iter->sg = sglist; + iter->sg_pgoffset = pgoffset; + iter->page = NULL; + + sg_page_iter_next(iter); +} + +/* + * Simple sg page iterator, starting off at the given page offset. Each entry + * on the sglist must start at offset 0 and can contain only full pages. + * iter->page will point to the current page, iter->sg_pgoffset to the page + * offset within the sg holding that page. + */ +#define for_each_sg_page(sglist, iter, pgoffset) \ + for (sg_page_iter_start((iter), (sglist), (pgoffset)); \ + (iter)->sg; sg_page_iter_next(iter)) /* * Mapping sg iterator