From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
To: hch@lst.de, Robin Murphy <robin.murphy@arm.com>,
David Rientjes <rientjes@google.com>,
iommu@lists.linux-foundation.org,
Marek Szyprowski <m.szyprowski@samsung.com>
Cc: linux-rpi-kernel@lists.infradead.org, jeremy.linton@arm.com,
Nicolas Saenz Julienne <nsaenzjulienne@suse.de>,
linux-kernel@vger.kernel.org
Subject: [PATCH 4/4] dma-pool: Make sure atomic pool suits device
Date: Thu, 9 Jul 2020 18:19:04 +0200 [thread overview]
Message-ID: <20200709161903.26229-5-nsaenzjulienne@suse.de> (raw)
In-Reply-To: <20200709161903.26229-1-nsaenzjulienne@suse.de>
When allocating DMA memory from a pool, the core can only guess which
atomic pool will fit a device's constraints. If it doesn't, get a safer
atomic pool and try again.
Fixes: c84dc6e68a1d ("dma-pool: add additional coherent pools to map to gfp mask")
Reported-by: Jeremy Linton <jeremy.linton@arm.com>
Suggested-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
kernel/dma/pool.c | 53 +++++++++++++++++++++++++++++++++--------------
1 file changed, 37 insertions(+), 16 deletions(-)
diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c
index 3d518de07617..d48d9acb585f 100644
--- a/kernel/dma/pool.c
+++ b/kernel/dma/pool.c
@@ -240,35 +240,56 @@ static inline struct gen_pool *dma_guess_pool(struct device *dev,
void *dma_alloc_from_pool(struct device *dev, size_t size,
struct page **ret_page, gfp_t flags)
{
- struct gen_pool *pool = dma_guess_pool(dev, NULL);
- unsigned long val;
+ struct gen_pool *pool = NULL;
+ unsigned long val = 0;
void *ptr = NULL;
-
- if (!pool) {
- WARN(1, "%pGg atomic pool not initialised!\n", &flags);
- return NULL;
+ phys_addr_t phys;
+
+ while (1) {
+ pool = dma_guess_pool(dev, pool);
+ if (!pool) {
+ WARN(1, "Failed to get suitable pool for %s\n",
+ dev_name(dev));
+ break;
+ }
+
+ val = gen_pool_alloc(pool, size);
+ if (!val)
+ continue;
+
+ phys = gen_pool_virt_to_phys(pool, val);
+ if (dma_coherent_ok(dev, phys, size))
+ break;
+
+ gen_pool_free(pool, val, size);
+ val = 0;
}
- val = gen_pool_alloc(pool, size);
- if (val) {
- phys_addr_t phys = gen_pool_virt_to_phys(pool, val);
+ if (val) {
*ret_page = pfn_to_page(__phys_to_pfn(phys));
ptr = (void *)val;
memset(ptr, 0, size);
+
+ if (gen_pool_avail(pool) < atomic_pool_size)
+ schedule_work(&atomic_pool_work);
}
- if (gen_pool_avail(pool) < atomic_pool_size)
- schedule_work(&atomic_pool_work);
return ptr;
}
bool dma_free_from_pool(struct device *dev, void *start, size_t size)
{
- struct gen_pool *pool = dma_guess_pool(dev, NULL);
+ struct gen_pool *pool = NULL;
+
+ while (1) {
+ pool = dma_guess_pool(dev, pool);
+ if (!pool)
+ return false;
- if (!pool || !gen_pool_has_addr(pool, (unsigned long)start, size))
- return false;
- gen_pool_free(pool, (unsigned long)start, size);
- return true;
+ if (gen_pool_has_addr(pool, (unsigned long)start, size)) {
+ gen_pool_free(pool, (unsigned long)start, size);
+ return true;
+ }
+ }
}
--
2.27.0
next prev parent reply other threads:[~2020-07-09 16:19 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-09 16:19 [PATCH 0/4] dma-pool: Fix atomic pool selection Nicolas Saenz Julienne
2020-07-09 16:19 ` [PATCH 1/4] dma-direct: Provide function to check physical memory area validity Nicolas Saenz Julienne
2020-07-09 16:19 ` [PATCH 2/4] dma-pool: Get rid of dma_in_atomic_pool() Nicolas Saenz Julienne
2020-07-09 21:51 ` David Rientjes
2020-07-10 6:50 ` Christoph Hellwig
2020-07-09 16:19 ` [PATCH 3/4] dma-pool: Introduce dma_guess_pool() Nicolas Saenz Julienne
2020-07-14 11:22 ` Christoph Hellwig
2020-07-14 11:40 ` Nicolas Saenz Julienne
2020-07-09 16:19 ` Nicolas Saenz Julienne [this message]
2020-07-10 18:52 ` [PATCH 0/4] dma-pool: Fix atomic pool selection Jeremy Linton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200709161903.26229-5-nsaenzjulienne@suse.de \
--to=nsaenzjulienne@suse.de \
--cc=hch@lst.de \
--cc=iommu@lists.linux-foundation.org \
--cc=jeremy.linton@arm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rpi-kernel@lists.infradead.org \
--cc=m.szyprowski@samsung.com \
--cc=rientjes@google.com \
--cc=robin.murphy@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).