From patchwork Mon Feb 11 18:50:04 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 14754 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 638DB4C1772 for ; Mon, 11 Feb 2013 18:50:27 +0000 (UTC) Received: from mail-vc0-f169.google.com (mail-vc0-f169.google.com [209.85.220.169]) by fiordland.canonical.com (Postfix) with ESMTP id ED8BEA180F2 for ; Mon, 11 Feb 2013 18:50:26 +0000 (UTC) Received: by mail-vc0-f169.google.com with SMTP id n10so4104490vcn.0 for ; Mon, 11 Feb 2013 10:50:26 -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=wFRdN/uUXphgRzALNSKfzaR1Lm7JoKKyTkOiqcKBurM=; b=EeXs8DSi5XG26J6kzBHKf6MLIM/JewRUospXyvLkK3AgzNQtcNJIFkMnrmdRW1RQUq 0eU6tFmt2t1BrAp1ct70sxAo0M18qV+2pFJPYKMrzMAy/hHeVe64QwcezIEFhC6KEqh2 NO0viksVHT4ze25yXUYYR5UIDuI8wkx9tIIcVrrXtdzzxERwNt/EGhQmnPkbpMi7d4YJ pYAvygJkocWDYINzlfmUzbp+/XZjRrIxf5hpqIvV0EflRCSV5sFtHf5BWr4FCTxy/Ko7 /qHwji5vQr++bxaEsCNfC5ferIINELG1x+A6zsdk7bWRDyN5b0v3vkNe1XRYJ+RoE9fJ Vt+g== X-Received: by 10.52.75.65 with SMTP id a1mr3621071vdw.79.1360608626464; Mon, 11 Feb 2013 10:50:26 -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 zo8csp112716vec; Mon, 11 Feb 2013 10:50:25 -0800 (PST) X-Received: by 10.204.147.144 with SMTP id l16mr4392792bkv.96.1360608624747; Mon, 11 Feb 2013 10:50:24 -0800 (PST) Received: from mombin.canonical.com (mombin.canonical.com. [91.189.95.16]) by mx.google.com with ESMTP id fm11si29462946bkc.53.2013.02.11.10.50.19; Mon, 11 Feb 2013 10:50:24 -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 1U4ySG-0001Nj-I3; Mon, 11 Feb 2013 18:50:16 +0000 Received: from mga14.intel.com ([143.182.124.37]) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1U4ySE-0001Ne-JT for linaro-mm-sig@lists.linaro.org; Mon, 11 Feb 2013 18:50:15 +0000 Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga102.ch.intel.com with ESMTP; 11 Feb 2013 10:50:07 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.84,644,1355126400"; d="scan'208";a="255545792" Received: from ideak-desk.fi.intel.com (HELO localhost) ([10.237.72.52]) by azsmga001.ch.intel.com with ESMTP; 11 Feb 2013 10:50:05 -0800 From: Imre Deak To: linux-kernel@vger.kernel.org Date: Mon, 11 Feb 2013 20:50:04 +0200 Message-Id: <1360608604-3520-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 v2] 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: ALoCoQlW6qeNLvl+oP2VMpOTn3GmYB69JS83K6qe2Q1K9+1h01kWJLjxfKe4ZVng8O6q2UrT/lR8 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. v2: - In each iteration sg_pgoffset pointed incorrectly at the next page not the current one. Signed-off-by: Imre Deak --- include/linux/scatterlist.h | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index 4bd6c06..72578b5 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -231,6 +231,56 @@ 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 struct page * +sg_page_iter_get_page(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); + } + + return iter->sg ? nth_page(sg_page(iter->sg), iter->sg_pgoffset) : NULL; +} + +static inline void +sg_page_iter_next(struct sg_page_iter *iter) +{ + iter->sg_pgoffset++; + iter->page = sg_page_iter_get_page(iter); +} + +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 = sg_page_iter_get_page(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)->page; sg_page_iter_next(iter)) /* * Mapping sg iterator