iommu.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] dma-mapping: Relax warnings for per-device areas
@ 2018-07-03 13:08 Robin Murphy
       [not found] ` <1f8262d206c6886072d04cc93454f6e3f812bd20.1530623284.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
  0 siblings, 1 reply; 15+ messages in thread
From: Robin Murphy @ 2018-07-03 13:08 UTC (permalink / raw)
  To: hch-jcswGhMUV9g, m.szyprowski-Sze3O3UU22JBDgjK7y7TUQ
  Cc: JuergenUrban-Mmb7MZpHnFY,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	noring-zgYzP9v7iJcdnm+yROfE0A

The reasons why dma_free_attrs() should not be called from IRQ context
are not necessarily obvious and somewhat buried in the development
history, so let's start by documenting the warning itself to help anyone
who does happen to hit it and wonder what the deal is.

However, this check turns out to be slightly over-restrictive for the
way that per-device memory has been spliced into the general API, since
for that case we know that dma_declare_coherent_memory() has created an
appropriate CPU mapping for the entire area and nothing dynamic should
be happening. Given that the usage model for per-device memory is often
more akin to streaming DMA than 'real' coherent DMA (e.g. allocating and
freeing space to copy short-lived packets in and out), it is also
somewhat more reasonable for those operations to happen in IRQ handlers
for such devices.

A somewhat similar line of reasoning also applies at the other end for
the mask check in dma_alloc_attrs() too - indeed, a device which cannot
access anything other than its own local memory probably *shouldn't*
have a valid mask for the general coherent DMA API.

Therefore, let's move the per-device area hooks up ahead of the assorted
checks, so that they get a chance to resolve the request before we get
as far as definite "you're doing it wrong" territory.

Reported-by: Fredrik Noring <noring-zgYzP9v7iJcdnm+yROfE0A@public.gmane.org>
Signed-off-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org>
---
 include/linux/dma-mapping.h | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index f9cc309507d9..ffeca3ab59c0 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -512,12 +512,12 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size,
 	const struct dma_map_ops *ops = get_dma_ops(dev);
 	void *cpu_addr;
 
-	BUG_ON(!ops);
-	WARN_ON_ONCE(dev && !dev->coherent_dma_mask);
-
 	if (dma_alloc_from_dev_coherent(dev, size, dma_handle, &cpu_addr))
 		return cpu_addr;
 
+	BUG_ON(!ops);
+	WARN_ON_ONCE(dev && !dev->coherent_dma_mask);
+
 	/* let the implementation decide on the zone to allocate from: */
 	flag &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
 
@@ -537,12 +537,19 @@ static inline void dma_free_attrs(struct device *dev, size_t size,
 {
 	const struct dma_map_ops *ops = get_dma_ops(dev);
 
-	BUG_ON(!ops);
-	WARN_ON(irqs_disabled());
-
 	if (dma_release_from_dev_coherent(dev, get_order(size), cpu_addr))
 		return;
 
+	BUG_ON(!ops);
+	/*
+	 * On non-coherent platforms which implement DMA-coherent buffers via
+	 * non-cacheable remaps, ops->free() may call vunmap(). Thus arriving
+	 * here in IRQ context is a) at risk of a BUG_ON() or trying to sleep
+	 * on some machines, and b) an indication that the driver is probably
+	 * misusing the coherent API anyway.
+	 */
+	WARN_ON(irqs_disabled());
+
 	if (!ops->free || !cpu_addr)
 		return;
 
-- 
2.17.1.dirty

^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2018-07-19 13:16 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-07-03 13:08 [PATCH] dma-mapping: Relax warnings for per-device areas Robin Murphy
     [not found] ` <1f8262d206c6886072d04cc93454f6e3f812bd20.1530623284.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
2018-07-03 16:47   ` Fredrik Noring
2018-07-05 19:36   ` Christoph Hellwig
     [not found]     ` <20180705193613.GA28905-jcswGhMUV9g@public.gmane.org>
2018-07-06 11:57       ` Robin Murphy
     [not found]         ` <5811ebe5-b2bd-efc1-bf54-a8f05432c4f8-5wv7dgnIgG8@public.gmane.org>
2018-07-06 14:19           ` Fredrik Noring
     [not found]             ` <20180706141926.GA2313-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2018-07-06 16:46               ` Robin Murphy
     [not found]                 ` <bd63815c-260e-078f-4184-561c8e54e636-5wv7dgnIgG8@public.gmane.org>
2018-07-06 20:54                   ` Fredrik Noring
2018-07-06 23:35                     ` Aw: " "Jürgen Urban"
2018-07-07  6:32                       ` Fredrik Noring
2018-07-08 20:47                         ` Aw: " "Jürgen Urban"
2018-07-15 12:28       ` Fredrik Noring
2018-07-17 14:57         ` Christoph Hellwig
2018-07-17 16:33           ` Fredrik Noring
2018-07-18 21:55             ` Geoff Levand
2018-07-19 13:16               ` Christoph Hellwig

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).