From patchwork Thu Feb 7 14:36:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilias Apalodimas X-Patchwork-Id: 157760 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp729789jaa; Thu, 7 Feb 2019 06:36:52 -0800 (PST) X-Google-Smtp-Source: AHgI3Iasj2XM9mrIN6cTgQCgIjae7RD9Gc+x+XzPSLobeBfKiFHCwCgn28LmWB16dgreinOiv2oO X-Received: by 2002:a65:5bc4:: with SMTP id o4mr15242399pgr.426.1549550212447; Thu, 07 Feb 2019 06:36:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549550212; cv=none; d=google.com; s=arc-20160816; b=O2X0YZuIv0HRCpmxDkh94TPWsCAjyUcf5OZ+L1mETOXHDnVlCVklbomigy33+v23vE pfTLKDWMdN9fMZVhWd+O9kPjRYzxdBDS66KBH4s6h6zMUnz0wBfEvSjP9NBWjLG7oANz I5wV1OuH9wI7iJq49MtlB62REixhH9AJ9wP0WAKZddT5/Jh44e9czy3e4Z6cwsFypxN/ 8nztvKO8iLSYmqmc8IzhSnllkCIwQ7Exyr65rhKqSoLUDPkNeWqBp7moJyK9ThdNDouj lPNdBhn+XbIUUWySD0+hi02T4fg0wXHqQexqSzu2AjPj7/zIzl0jKPTkY7dtLKRqj75x FC9A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature; bh=USWTqNNaTFMecCWSHWRIq82FHnD40j+lsfqrz/0WGpY=; b=YjRcSxTWivAf1yx6qXOCjoixPK4KeSjOwVAWiZTiCj8DcdxTGmyLdlX4YiTnggXSqD QOyPOFD5k4WwWjT9JfbT9UOY9S3ex0N0G4aC1Q/Bj2kJXKey0BaKhAohlHh01NMHpeF1 u7ba65qym9gJNz3GfjwqCEmJGHtLA0YSSDXarBDD9wKokN8Kpx93UJoNEI7XRc0NGyxc gIRb/Zs7ZESPjkZxo2L9aSZv6Nxi012xZjIp/ecBiGKlnYmVdifCuvpKbAhgPqMgIIrX TUYb1Nn9f3smB+JGqotRPaPvR3SaEzVrp7TCy9nvaSS9wZlS5vZEY7pfEpYuL0E8T4fM E0Vg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=PTv9EPT2; spf=pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g20si8853757pgh.241.2019.02.07.06.36.52; Thu, 07 Feb 2019 06:36:52 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=PTv9EPT2; spf=pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726985AbfBGOgv (ORCPT + 10 others); Thu, 7 Feb 2019 09:36:51 -0500 Received: from mail-wm1-f65.google.com ([209.85.128.65]:37863 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726795AbfBGOgu (ORCPT ); Thu, 7 Feb 2019 09:36:50 -0500 Received: by mail-wm1-f65.google.com with SMTP id g67so89822wmd.2 for ; Thu, 07 Feb 2019 06:36:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=USWTqNNaTFMecCWSHWRIq82FHnD40j+lsfqrz/0WGpY=; b=PTv9EPT29LlNcqMeVoydVc4XWa4we0Cg3MnxIMD40V7yonzExbA+u//uju3oeCi8Z8 45CeJ5A60zb0Bse46U6ZxxptxcB7HhiTZ+2KCUXGf/JkM7pKSYE9WRNwVXbMs7Nu1qrj 3ZJLW0Ld28J8UTxB30xcSMpmSb+IWc86i+oqE3bcGupfRIhwIQUbT+HBe7q8wGTQwHfS 3IxLxCC8gOArTX6Barc3KQ8RyMhJDXjj4xF5UXM9L3aH2Zxw2bxcLOMc8l9K0FQFvNQj 2eTSHEobwlmj7OjpvywKsTvDEQMw4pi3vjBSi2XHwYf1MIkDFZpEUia5KDngtNyvbB9u s/gQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=USWTqNNaTFMecCWSHWRIq82FHnD40j+lsfqrz/0WGpY=; b=ZlXW5iMvkMJqXA3dexMhDipNLhlqCiQ+q3L75MAztFqWkp5rhJhLHgS0rIB1KiB7QK WwqkpYwzmy/DRFhiAGfmeRn4ycLRjQnZ3b0avwO4gFMhN2Po/aHRd79coqDM25ItIBuM 50d13AibraJhn2WDzBYKFFGpH4scDXu6ZDFlUuAwOKG9jgok/H/JvUgwdlgGLPSooXbf rE726kpmQlaP9e7bZfmHgXfzmA0Azkt0MofQPw+UfHmNsvpRi1pb5WSGzmBCLqvKdRiN 7EPYgWYkCgqbL96hiY8HsvWVKn2JAI+GTaCvwInGAassKsmVx+8OPSFitX4MKuMYz4L1 n/7Q== X-Gm-Message-State: AHQUAuZAnSORLv//p+UyTH8c09gQSd2HjhKBbVU0KbrUbDLvjJIZFIOV 2vi5zkEPkdh56wwA94X0HbV9MA== X-Received: by 2002:a1c:26c1:: with SMTP id m184mr7370762wmm.25.1549550208059; Thu, 07 Feb 2019 06:36:48 -0800 (PST) Received: from apalos.lan (ppp-94-65-225-153.home.otenet.gr. [94.65.225.153]) by smtp.gmail.com with ESMTPSA id m6sm17332938wrv.24.2019.02.07.06.36.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 07 Feb 2019 06:36:47 -0800 (PST) From: Ilias Apalodimas To: brouer@redhat.com, tariqt@mellanox.com, toke@redhat.com Cc: davem@davemloft.net, netdev@vger.kernel.org, mgorman@techsingularity.net, linux-mm@kvack.org, Ilias Apalodimas Subject: [RFC, PATCH] net: page_pool: Don't use page->private to store dma_addr_t Date: Thu, 7 Feb 2019 16:36:36 +0200 Message-Id: <1549550196-25581-1-git-send-email-ilias.apalodimas@linaro.org> X-Mailer: git-send-email 2.7.4 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org As pointed out in https://www.mail-archive.com/netdev@vger.kernel.org/msg257926.html the current page_pool implementation stores dma_addr_t in page->private. This won't work on 32-bit platforms with 64-bit DMA addresses since the page->private is an unsigned long and the dma_addr_t a u64. Since no driver is yet using the DMA mapping capabilities of the API let's try and fix this by shadowing struct_page and use 'struct list_head lru' to store and retrieve DMA addresses from network drivers. As long as the addresses returned from dma_map_page() are aligned the first bit, used by the compound pages code should not be set. Signed-off-by: Ilias Apalodimas Signed-off-by: Jesper Dangaard Brouer --- include/net/page_pool.h | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ net/core/page_pool.c | 18 ++++++++++++---- 2 files changed, 69 insertions(+), 4 deletions(-) -- 2.7.4 diff --git a/include/net/page_pool.h b/include/net/page_pool.h index 694d055..618f2e5 100644 --- a/include/net/page_pool.h +++ b/include/net/page_pool.h @@ -98,6 +98,52 @@ struct page_pool { struct ptr_ring ring; }; +/* Until we can update struct-page, have a shadow struct-page, that + * include our use-case + * Used to store retrieve dma addresses from network drivers. + * Never access this directly, use helper functions provided + * page_pool_get_dma_addr() + */ +struct page_shadow { + unsigned long flags; /* Atomic flags, some possibly + * updated asynchronously + */ + /* + * Five words (20/40 bytes) are available in this union. + * WARNING: bit 0 of the first word is used for PageTail(). That + * means the other users of this union MUST NOT use the bit to + * avoid collision and false-positive PageTail(). + */ + union { + struct { /* Page cache and anonymous pages */ + /** + * @lru: Pageout list, eg. active_list protected by + * zone_lru_lock. Sometimes used as a generic list + * by the page owner. + */ + struct list_head lru; + /* See page-flags.h for PAGE_MAPPING_FLAGS */ + struct address_space *mapping; + pgoff_t index; /* Our offset within mapping. */ + /** + * @private: Mapping-private opaque data. + * Usually used for buffer_heads if PagePrivate. + * Used for swp_entry_t if PageSwapCache. + * Indicates order in the buddy system if PageBuddy. + */ + unsigned long private; + }; + struct { /* page_pool used by netstack */ + /** + * @dma_addr: Page_pool need to store DMA-addr, and + * cannot use @private, as DMA-mappings can be 64bit + * even on 32-bit Architectures. + */ + dma_addr_t dma_addr; /* Shares area with @lru */ + }; + }; +}; + struct page *page_pool_alloc_pages(struct page_pool *pool, gfp_t gfp); static inline struct page *page_pool_dev_alloc_pages(struct page_pool *pool) @@ -141,4 +187,13 @@ static inline bool is_page_pool_compiled_in(void) #endif } +static inline dma_addr_t page_pool_get_dma_addr(struct page *page) +{ + struct page_shadow *_page; + + _page = (struct page_shadow *)page; + + return _page->dma_addr; +} + #endif /* _NET_PAGE_POOL_H */ diff --git a/net/core/page_pool.c b/net/core/page_pool.c index 43a932c..1a956a6 100644 --- a/net/core/page_pool.c +++ b/net/core/page_pool.c @@ -111,6 +111,7 @@ noinline static struct page *__page_pool_alloc_pages_slow(struct page_pool *pool, gfp_t _gfp) { + struct page_shadow *_page; struct page *page; gfp_t gfp = _gfp; dma_addr_t dma; @@ -136,7 +137,7 @@ static struct page *__page_pool_alloc_pages_slow(struct page_pool *pool, if (!(pool->p.flags & PP_FLAG_DMA_MAP)) goto skip_dma_map; - /* Setup DMA mapping: use page->private for DMA-addr + /* Setup DMA mapping: use struct-page area for storing DMA-addr * This mapping is kept for lifetime of page, until leaving pool. */ dma = dma_map_page(pool->p.dev, page, 0, @@ -146,7 +147,8 @@ static struct page *__page_pool_alloc_pages_slow(struct page_pool *pool, put_page(page); return NULL; } - set_page_private(page, dma); /* page->private = dma; */ + _page = (struct page_shadow *)page; + _page->dma_addr = dma; skip_dma_map: /* When page just alloc'ed is should/must have refcnt 1. */ @@ -175,13 +177,21 @@ EXPORT_SYMBOL(page_pool_alloc_pages); static void __page_pool_clean_page(struct page_pool *pool, struct page *page) { + struct page_shadow *_page = (struct page_shadow *)page; + dma_addr_t dma; + if (!(pool->p.flags & PP_FLAG_DMA_MAP)) return; + dma = _page->dma_addr; + /* DMA unmap */ - dma_unmap_page(pool->p.dev, page_private(page), + dma_unmap_page(pool->p.dev, dma, PAGE_SIZE << pool->p.order, pool->p.dma_dir); - set_page_private(page, 0); + _page->dma_addr = 0; + /* 1. Make sure we don't need to list-init page->lru. + * 2. What does it mean: bit 0 of LRU first word is used for PageTail() + */ } /* Return a page to the page allocator, cleaning up our state */