* Re: [PATCH 31/33] dma-direct: reject too small dma masks
From: Robin Murphy @ 2018-01-10 11:49 UTC (permalink / raw)
To: Christoph Hellwig, iommu
Cc: linux-mips, linux-ia64, linux-sh, sparclinux, Guan Xuetao,
linux-arch, linux-s390, linux-c6x-dev, linux-hexagon, x86,
Konrad Rzeszutek Wilk, linux-snps-arc, linux-m68k, patches,
linux-metag, linux-arm-kernel, Michal Simek, linux-parisc,
linux-cris-kernel, linux-kernel, linux-alpha, linuxppc-dev
In-Reply-To: <20180110080027.13879-32-hch@lst.de>
On 10/01/18 08:00, Christoph Hellwig wrote:
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> include/linux/dma-direct.h | 1 +
> lib/dma-direct.c | 19 +++++++++++++++++++
> 2 files changed, 20 insertions(+)
>
> diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
> index 4788bf0bf683..bcdb1a3e4b1f 100644
> --- a/include/linux/dma-direct.h
> +++ b/include/linux/dma-direct.h
> @@ -42,5 +42,6 @@ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
> gfp_t gfp, unsigned long attrs);
> void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
> dma_addr_t dma_addr, unsigned long attrs);
> +int dma_direct_supported(struct device *dev, u64 mask);
>
> #endif /* _LINUX_DMA_DIRECT_H */
> diff --git a/lib/dma-direct.c b/lib/dma-direct.c
> index 784a68dfdbe3..40b1f92f2214 100644
> --- a/lib/dma-direct.c
> +++ b/lib/dma-direct.c
> @@ -122,6 +122,24 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
> return nents;
> }
>
> +int dma_direct_supported(struct device *dev, u64 mask)
> +{
> +#ifdef CONFIG_ZONE_DMA
> + if (mask < DMA_BIT_MASK(ARCH_ZONE_DMA_BITS))
> + return 0;
> +#else
> + /*
> + * Because 32-bit DMA masks are so common we expect every architecture
> + * to be able to satisfy them - either by not supporting more physical
> + * memory, or by providing a ZONE_DMA32. If neither is the case, the
> + * architecture needs to use an IOMMU instead of the direct mapping.
> + */
> + if (mask < DMA_BIT_MASK(32))
> + return 0;
Do you think it's worth the effort to be a little more accommodating
here? i.e.:
return dma_max_pfn(dev) >= max_pfn;
We seem to have a fair few 28-31 bit masks for older hardware which
probably associates with host systems packing equivalently small amounts
of RAM.
Otherwise though,
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Robin.
> +#endif
> + return 1;
> +}
> +
> static int dma_direct_mapping_error(struct device *dev, dma_addr_t dma_addr)
> {
> return dma_addr == DIRECT_MAPPING_ERROR;
> @@ -132,6 +150,7 @@ const struct dma_map_ops dma_direct_ops = {
> .free = dma_direct_free,
> .map_page = dma_direct_map_page,
> .map_sg = dma_direct_map_sg,
> + .dma_supported = dma_direct_supported,
> .mapping_error = dma_direct_mapping_error,
> };
> EXPORT_SYMBOL(dma_direct_ops);
>
^ permalink raw reply
* Re: [PATCH 10/33] arm64: don't override dma_max_pfn
From: Robin Murphy @ 2018-01-10 11:08 UTC (permalink / raw)
To: Christoph Hellwig, iommu
Cc: linux-mips, linux-ia64, linux-sh, sparclinux, Guan Xuetao,
linux-arch, linux-s390, linux-c6x-dev, linux-hexagon, x86,
Konrad Rzeszutek Wilk, linux-snps-arc, linux-m68k, patches,
linux-metag, linux-arm-kernel, Michal Simek, linux-parisc,
linux-cris-kernel, linux-kernel, linux-alpha, linuxppc-dev
In-Reply-To: <20180110080027.13879-11-hch@lst.de>
On 10/01/18 08:00, Christoph Hellwig wrote:
> The generic version now takes dma_pfn_offset into account, so there is no
> more need for an architecture override.
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> arch/arm64/include/asm/dma-mapping.h | 9 ---------
> 1 file changed, 9 deletions(-)
>
> diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
> index 0df756b24863..eada887a93bf 100644
> --- a/arch/arm64/include/asm/dma-mapping.h
> +++ b/arch/arm64/include/asm/dma-mapping.h
> @@ -76,14 +76,5 @@ static inline void dma_mark_clean(void *addr, size_t size)
> {
> }
>
> -/* Override for dma_max_pfn() */
> -static inline unsigned long dma_max_pfn(struct device *dev)
> -{
> - dma_addr_t dma_max = (dma_addr_t)*dev->dma_mask;
> -
> - return (ulong)dma_to_phys(dev, dma_max) >> PAGE_SHIFT;
> -}
> -#define dma_max_pfn(dev) dma_max_pfn(dev)
> -
> #endif /* __KERNEL__ */
> #endif /* __ASM_DMA_MAPPING_H */
>
^ permalink raw reply
* Re: [PATCH 09/33] dma-mapping: take dma_pfn_offset into account in dma_max_pfn
From: Robin Murphy @ 2018-01-10 11:07 UTC (permalink / raw)
To: Christoph Hellwig, iommu
Cc: linux-mips, linux-ia64, linux-sh, sparclinux, Guan Xuetao,
linux-arch, linux-s390, linux-c6x-dev, linux-hexagon, x86,
Konrad Rzeszutek Wilk, linux-snps-arc, linux-m68k, patches,
linux-metag, linux-arm-kernel, Michal Simek, linux-parisc,
linux-cris-kernel, linux-kernel, linux-alpha, linuxppc-dev
In-Reply-To: <20180110080027.13879-10-hch@lst.de>
On 10/01/18 08:00, Christoph Hellwig wrote:
> This makes sure the generic version can be used with architectures /
> devices that have a DMA offset in the direct mapping.
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> include/linux/dma-mapping.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index 81ed9b2d84dc..d84951865be7 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -692,7 +692,7 @@ static inline int dma_set_seg_boundary(struct device *dev, unsigned long mask)
> #ifndef dma_max_pfn
> static inline unsigned long dma_max_pfn(struct device *dev)
> {
> - return *dev->dma_mask >> PAGE_SHIFT;
> + return (*dev->dma_mask >> PAGE_SHIFT) + dev->dma_pfn_offset;
> }
> #endif
>
>
^ permalink raw reply
* [PATCH] powerpc : Fix sleeping-in-atomic section warning triggered by /proc/cpuinfo
From: Shriya @ 2018-01-10 9:52 UTC (permalink / raw)
To: linuxppc-dev
Cc: aneesh.kumar, ego, svaidy, akshay.adiga, shilpa.bhat, npiggin,
Shriya
Commit cd77b5ce208c ("Fix the frequency read by /proc/cpuinfo")
to fix /proc/cpuinfo on POWERNV triggered a sleeping-in-atomic section
warning. This was because the place where we cpufreq_get (which takes
an rwsem) from show_cpuinfo is in a preempt_disabled. However, the
preempt_disable() in show_cpuinfo is for protection against
CPU-Hotplug, since we don't want to report the information of offline
CPUs in /proc/cpuinfo.
Fix this by replacing preempt_disable()/preempt_enable() in
show_cpuinfo() by get_online_cpus()/put_online_cpus() giving a proper
protection against CPU-Hotplug.
---
arch/powerpc/kernel/setup-common.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 2075322..f772442 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -244,9 +244,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
/* We only show online cpus: disable preempt (overzealous, I
* knew) to prevent cpu going down. */
- preempt_disable();
+ get_online_cpus();
if (!cpu_online(cpu_id)) {
- preempt_enable();
+ put_online_cpus();
return 0;
}
@@ -359,7 +359,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "\n");
#endif
- preempt_enable();
+ put_online_cpus();
/* If this is the last cpu, print the summary */
if (cpumask_next(cpu_id, cpu_online_mask) >= nr_cpu_ids)
--
1.9.1
^ permalink raw reply related
* Re: [v3 PATCH 0/3] powernv-cpufreq: Multiple pstate related fixes.
From: Viresh Kumar @ 2018-01-10 9:43 UTC (permalink / raw)
To: Gautham R. Shenoy
Cc: Shilpasri G Bhat, rjw, huntbag, akshay.adiga, Michael Ellerman,
Vaidyanathan Srinivasan, Balbir Singh, linux-pm, linux-kernel,
linuxppc-dev
In-Reply-To: <1513148261-21097-1-git-send-email-ego@linux.vnet.ibm.com>
On 13-12-17, 12:27, Gautham R. Shenoy wrote:
> From: "Gautham R. Shenoy" <ego@linux.vnet.ibm.com>
>
> This is a third version of the patch to fix pstate related issues in
> the powernv-cpufreq driver.
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
--
viresh
^ permalink raw reply
* Re: [PATCH 29/33] dma-direct: retry allocations using GFP_DMA for small masks
From: Vladimir Murzin @ 2018-01-10 9:32 UTC (permalink / raw)
To: Christoph Hellwig, iommu
Cc: linux-mips, linux-ia64, linux-sh, sparclinux, Guan Xuetao,
linux-arch, linux-s390, linux-c6x-dev, linux-hexagon, x86,
Konrad Rzeszutek Wilk, linux-snps-arc, linux-m68k, patches,
linux-metag, linux-arm-kernel, Michal Simek, linux-parisc,
linux-cris-kernel, linux-kernel, linux-alpha, linuxppc-dev
In-Reply-To: <20180110080027.13879-30-hch@lst.de>
On 10/01/18 08:00, Christoph Hellwig wrote:
> If an attempt to allocate memory succeeded, but isn't inside the
> supported DMA mask, retry the allocation with GFP_DMA set as a
> last resort.
>
> Based on the x86 code, but an off by one error in what is now
> dma_coherent_ok has been fixed vs the x86 code.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> lib/dma-direct.c | 25 ++++++++++++++++++++++++-
> 1 file changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/lib/dma-direct.c b/lib/dma-direct.c
> index 8f76032ebc3c..4e43c2bb7f5f 100644
> --- a/lib/dma-direct.c
> +++ b/lib/dma-direct.c
> @@ -35,6 +35,11 @@ check_addr(struct device *dev, dma_addr_t dma_addr, size_t size,
> return true;
> }
>
> +static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)
> +{
> + return phys_to_dma(dev, phys) + size - 1 <= dev->coherent_dma_mask;
> +}
> +
> static void *dma_direct_alloc(struct device *dev, size_t size,
> dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
> {
> @@ -48,11 +53,29 @@ static void *dma_direct_alloc(struct device *dev, size_t size,
> if (dev->coherent_dma_mask <= DMA_BIT_MASK(32) && !(gfp & GFP_DMA))
> gfp |= GFP_DMA32;
>
> +again:
> /* CMA can be used only in the context which permits sleeping */
> - if (gfpflags_allow_blocking(gfp))
> + if (gfpflags_allow_blocking(gfp)) {
> page = dma_alloc_from_contiguous(dev, count, page_order, gfp);
> + if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
> + dma_release_from_contiguous(dev, page, count);
> + page = NULL;
> + }
> + }
> if (!page)
> page = alloc_pages_node(dev_to_node(dev), gfp, page_order);
> +
> + if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
> + __free_pages(page, page_order);
> + page = NULL;
> +
> + if (dev->coherent_dma_mask < DMA_BIT_MASK(32) &&
> + !(gfp & GFP_DMA)) {
> + gfp = (gfp & ~GFP_DMA32) | GFP_DMA;
> + goto again;
> + }
> + }
> +
> if (!page)
> return NULL;
>
>
Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com>
Cheers
Vladimir
^ permalink raw reply
* Re: [PATCH 11/33] dma-mapping: move swiotlb arch helpers to a new header
From: Vladimir Murzin @ 2018-01-10 9:31 UTC (permalink / raw)
To: Christoph Hellwig, iommu
Cc: linux-mips, linux-ia64, linux-sh, sparclinux, Guan Xuetao,
linux-arch, linux-s390, linux-c6x-dev, linux-hexagon, x86,
Konrad Rzeszutek Wilk, linux-snps-arc, linux-m68k, patches,
linux-metag, linux-arm-kernel, Michal Simek, linux-parisc,
linux-cris-kernel, linux-kernel, linux-alpha, linuxppc-dev
In-Reply-To: <20180110080027.13879-12-hch@lst.de>
On 10/01/18 08:00, Christoph Hellwig wrote:
> index 9110988b92a1..f00833acb626 100644
> --- a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
> +++ b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
> @@ -61,6 +61,14 @@ static inline void plat_post_dma_flush(struct device *dev)
> {
> }
>
> +static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
> +{
> + if (!dev->dma_mask)
> + return false;
> +
> + return addr + size <= *dev->dma_mask;
> +}
> +
I know it is copy&paste, but it seems it has off by one error and it should be
return addr + size - 1 <= *dev->dma_mask;
> dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
> phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
>
snip...
> diff --git a/arch/mips/include/asm/mach-loongson64/dma-coherence.h b/arch/mips/include/asm/mach-loongson64/dma-coherence.h
> index 1602a9e9e8c2..5cfda8f893e9 100644
> --- a/arch/mips/include/asm/mach-loongson64/dma-coherence.h
> +++ b/arch/mips/include/asm/mach-loongson64/dma-coherence.h
> @@ -17,6 +17,14 @@
>
> struct device;
>
> +static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
> +{
> + if (!dev->dma_mask)
> + return false;
> +
> + return addr + size <= *dev->dma_mask;
ditto
Cheers
Vladimir
^ permalink raw reply
* Re: [v3 PATCH 2/3] powernv-cpufreq: Fix pstate_to_idx() to handle non-continguous pstates
From: Gautham R Shenoy @ 2018-01-10 8:55 UTC (permalink / raw)
To: Balbir Singh
Cc: Rafael J. Wysocki, Gautham R Shenoy, Shilpasri G Bhat,
Viresh Kumar, Abhishek, Akshay Adiga, Michael Ellerman,
Vaidyanathan Srinivasan, linux-pm, linux-kernel@vger.kernel.org,
open list:LINUX FOR POWERPC (32-BIT AND 64-BIT)
In-Reply-To: <CAKTCnznuf1jwWZEqi+og8LyayfzMwGYRUXhK4+zfbSYDfexyRA@mail.gmail.com>
Hi Rafael,
On Wed, Jan 03, 2018 at 11:47:58PM +1100, Balbir Singh wrote:
> On Wed, Jan 3, 2018 at 11:07 PM, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > On Monday, December 18, 2017 9:38:20 AM CET Gautham R Shenoy wrote:
> >> Hi Balbir,
> >>
> >> On Sun, Dec 17, 2017 at 02:15:25PM +1100, Balbir Singh wrote:
> >> > On Wed, Dec 13, 2017 at 5:57 PM, Gautham R. Shenoy
> >> > <ego@linux.vnet.ibm.com> wrote:
> >> > > From: "Gautham R. Shenoy" <ego@linux.vnet.ibm.com>
> >> > >
> >> > > The code in powernv-cpufreq, makes the following two assumptions which
> >> > > are not guaranteed by the device-tree bindings:
> >> > >
> >> > > 1) Pstate ids are continguous: This is used in pstate_to_idx() to
> >> > > obtain the reverse map from a pstate to it's corresponding
> >> > > entry into the cpufreq frequency table.
> >> > >
> >> > > 2) Every Pstate should always lie between the max and the min
> >> > > pstates that are explicitly reported in the device tree: This
> >> > > is used to determine whether a pstate reported by the PMSR is
> >> > > out of bounds.
> >> > >
> >> > > Both these assumptions are unwarranted and can change on future
> >> > > platforms.
> >> >
> >> > While this is a good thing, I wonder if it is worth the complexity. Pstates
> >> > are contiguous because they define transitions in incremental value
> >> > of change in frequency and I can't see how this can be broken in the
> >> > future?
> >>
> >> In the future, we can have the OPAL firmware give us a smaller set of
> >> pstates instead of expose every one of them. As it stands today, for
> >> most of the workloads, we will need at best 20-30 pstates and not
> >> beyond that.
> >
> > I'm not sure about the status here.
> >
> > Is this good to go as is or is it going to be updated?
> >
>
> I have no major objections, except some of the added complexity, but
> Gautham makes a point that this is refactoring for the future
I have tested this across POWER8 and POWER9. The additional complexity
introduced by the second patch is required for the future when we are
going to reduce the number of pstates.
>
> Balbir Singh.
>
--
Thanks and Regards
gautham.
^ permalink raw reply
* Re: consolidate swiotlb dma_map implementations
From: Christian König @ 2018-01-10 8:23 UTC (permalink / raw)
To: Christoph Hellwig, iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
linux-arm-kernel, linux-ia64, linux-mips, linuxppc-dev, x86,
linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
Acked-by: Christian König <christian.koenig@amd.com> for the whole series.
Regards,
Christian.
Am 10.01.2018 um 09:09 schrieb Christoph Hellwig:
> A lot of architectures have essentially identical dma_map_ops
> implementations to use swiotlb. This series adds new generic
> swiotlb_alloc/free helpers that take the attrs argument exposed
> in dma_map_ops, and which do an enhanced direct allocation
> modelled after x86 and reused from the dma-direct code, and
> then switches most architectures over to it. The only exceptions
> are mips, which requires additional cache flushing which will
> need a new abstraction, and x86 itself which will be handled in
> a later series with other x86 dma mapping changes.
>
> To support the generic code a few architectures that currently
> use ZONE_DMA/GFP_DMA for <= 32-bit allocations are switched to
> implement ZONE_DMA32 instead.
>
> This series is based on the previously sent series to consolidate
> the direct dma mapping implementation. A git tree with this
> series as well as the prerequisites is available here:
>
> git://git.infradead.org/users/hch/misc.git swiotlb
>
> Gitweb:
>
> http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/swiotlb
^ permalink raw reply
* [PATCH 22/22] arm64: use swiotlb_alloc and swiotlb_free
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
The generic swiotlb_alloc and swiotlb_free routines already take care
of CMA allocations and adding GFP_DMA32 where needed, so use them
instead of the arm specific helpers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm64/Kconfig | 1 +
arch/arm64/mm/dma-mapping.c | 46 +++------------------------------------------
2 files changed, 4 insertions(+), 43 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6b6985f15d02..53205c02b18a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -59,6 +59,7 @@ config ARM64
select COMMON_CLK
select CPU_PM if (SUSPEND || CPU_IDLE)
select DCACHE_WORD_ACCESS
+ select DMA_DIRECT_OPS
select EDAC_SUPPORT
select FRAME_POINTER
select GENERIC_ALLOCATOR
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 0d641875b20e..a96ec0181818 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -91,46 +91,6 @@ static int __free_from_pool(void *start, size_t size)
return 1;
}
-static void *__dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flags,
- unsigned long attrs)
-{
- if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
- dev->coherent_dma_mask <= DMA_BIT_MASK(32))
- flags |= GFP_DMA32;
- if (dev_get_cma_area(dev) && gfpflags_allow_blocking(flags)) {
- struct page *page;
- void *addr;
-
- page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT,
- get_order(size), flags);
- if (!page)
- return NULL;
-
- *dma_handle = phys_to_dma(dev, page_to_phys(page));
- addr = page_address(page);
- memset(addr, 0, size);
- return addr;
- } else {
- return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
- }
-}
-
-static void __dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle,
- unsigned long attrs)
-{
- bool freed;
- phys_addr_t paddr = dma_to_phys(dev, dma_handle);
-
-
- freed = dma_release_from_contiguous(dev,
- phys_to_page(paddr),
- size >> PAGE_SHIFT);
- if (!freed)
- swiotlb_free_coherent(dev, size, vaddr, dma_handle);
-}
-
static void *__dma_alloc(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flags,
unsigned long attrs)
@@ -152,7 +112,7 @@ static void *__dma_alloc(struct device *dev, size_t size,
return addr;
}
- ptr = __dma_alloc_coherent(dev, size, dma_handle, flags, attrs);
+ ptr = swiotlb_alloc(dev, size, dma_handle, flags, attrs);
if (!ptr)
goto no_mem;
@@ -173,7 +133,7 @@ static void *__dma_alloc(struct device *dev, size_t size,
return coherent_ptr;
no_map:
- __dma_free_coherent(dev, size, ptr, *dma_handle, attrs);
+ swiotlb_free(dev, size, ptr, *dma_handle, attrs);
no_mem:
return NULL;
}
@@ -191,7 +151,7 @@ static void __dma_free(struct device *dev, size_t size,
return;
vunmap(vaddr);
}
- __dma_free_coherent(dev, size, swiotlb_addr, dma_handle, attrs);
+ swiotlb_free(dev, size, swiotlb_addr, dma_handle, attrs);
}
static dma_addr_t __swiotlb_map_page(struct device *dev, struct page *page,
--
2.14.2
^ permalink raw reply related
* [PATCH 21/22] arm64: replace ZONE_DMA with ZONE_DMA32
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
arm64 uses ZONE_DMA for allocations below 32-bits. These days we
name the zone for that ZONE_DMA32, which will allow to use the
dma-direct and generic swiotlb code as-is, so rename it.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm64/Kconfig | 2 +-
arch/arm64/mm/dma-mapping.c | 6 +++---
arch/arm64/mm/init.c | 16 ++++++++--------
3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c9a7e9e1414f..6b6985f15d02 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -227,7 +227,7 @@ config GENERIC_CSUM
config GENERIC_CALIBRATE_DELAY
def_bool y
-config ZONE_DMA
+config ZONE_DMA32
def_bool y
config HAVE_GENERIC_GUP
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 6840426bbe77..0d641875b20e 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -95,9 +95,9 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flags,
unsigned long attrs)
{
- if (IS_ENABLED(CONFIG_ZONE_DMA) &&
+ if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
dev->coherent_dma_mask <= DMA_BIT_MASK(32))
- flags |= GFP_DMA;
+ flags |= GFP_DMA32;
if (dev_get_cma_area(dev) && gfpflags_allow_blocking(flags)) {
struct page *page;
void *addr;
@@ -397,7 +397,7 @@ static int __init atomic_pool_init(void)
page = dma_alloc_from_contiguous(NULL, nr_pages,
pool_size_order, GFP_KERNEL);
else
- page = alloc_pages(GFP_DMA, pool_size_order);
+ page = alloc_pages(GFP_DMA32, pool_size_order);
if (page) {
int ret;
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 00e7b900ca41..8f03276443c9 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -217,7 +217,7 @@ static void __init reserve_elfcorehdr(void)
}
#endif /* CONFIG_CRASH_DUMP */
/*
- * Return the maximum physical address for ZONE_DMA (DMA_BIT_MASK(32)). It
+ * Return the maximum physical address for ZONE_DMA32 (DMA_BIT_MASK(32)). It
* currently assumes that for memory starting above 4G, 32-bit devices will
* use a DMA offset.
*/
@@ -233,8 +233,8 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
{
unsigned long max_zone_pfns[MAX_NR_ZONES] = {0};
- if (IS_ENABLED(CONFIG_ZONE_DMA))
- max_zone_pfns[ZONE_DMA] = PFN_DOWN(max_zone_dma_phys());
+ if (IS_ENABLED(CONFIG_ZONE_DMA32))
+ max_zone_pfns[ZONE_DMA32] = PFN_DOWN(max_zone_dma_phys());
max_zone_pfns[ZONE_NORMAL] = max;
free_area_init_nodes(max_zone_pfns);
@@ -251,9 +251,9 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
memset(zone_size, 0, sizeof(zone_size));
/* 4GB maximum for 32-bit only capable devices */
-#ifdef CONFIG_ZONE_DMA
+#ifdef CONFIG_ZONE_DMA32
max_dma = PFN_DOWN(arm64_dma_phys_limit);
- zone_size[ZONE_DMA] = max_dma - min;
+ zone_size[ZONE_DMA32] = max_dma - min;
#endif
zone_size[ZONE_NORMAL] = max - max_dma;
@@ -266,10 +266,10 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
if (start >= max)
continue;
-#ifdef CONFIG_ZONE_DMA
+#ifdef CONFIG_ZONE_DMA32
if (start < max_dma) {
unsigned long dma_end = min(end, max_dma);
- zhole_size[ZONE_DMA] -= dma_end - start;
+ zhole_size[ZONE_DMA32] -= dma_end - start;
}
#endif
if (end > max_dma) {
@@ -467,7 +467,7 @@ void __init arm64_memblock_init(void)
early_init_fdt_scan_reserved_mem();
/* 4GB maximum for 32-bit only capable devices */
- if (IS_ENABLED(CONFIG_ZONE_DMA))
+ if (IS_ENABLED(CONFIG_ZONE_DMA32))
arm64_dma_phys_limit = max_zone_dma_phys();
else
arm64_dma_phys_limit = PHYS_MASK + 1;
--
2.14.2
^ permalink raw reply related
* [PATCH 20/22] mips: use swiotlb_{alloc,free}
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
These already include the GFP_DMA/GFP_DMA32 usage, and will use CMA
memory if enabled, thus avoiding the GFP_NORETRY hack.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/mips/cavium-octeon/Kconfig | 1 +
arch/mips/cavium-octeon/dma-octeon.c | 26 +++-----------------------
arch/mips/loongson64/Kconfig | 1 +
arch/mips/loongson64/common/dma-swiotlb.c | 21 ++-------------------
4 files changed, 7 insertions(+), 42 deletions(-)
diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig
index 204a1670fd9b..b5eee1a57d6c 100644
--- a/arch/mips/cavium-octeon/Kconfig
+++ b/arch/mips/cavium-octeon/Kconfig
@@ -75,6 +75,7 @@ config NEED_SG_DMA_LENGTH
config SWIOTLB
def_bool y
+ select DMA_DIRECT_OPS
select IOMMU_HELPER
select NEED_SG_DMA_LENGTH
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
index 5baf79fce643..c7bb8a407041 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -159,33 +159,13 @@ static void octeon_dma_sync_sg_for_device(struct device *dev,
static void *octeon_dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
{
- void *ret;
-
- if (IS_ENABLED(CONFIG_ZONE_DMA) && dev == NULL)
- gfp |= __GFP_DMA;
- else if (IS_ENABLED(CONFIG_ZONE_DMA) &&
- dev->coherent_dma_mask <= DMA_BIT_MASK(24))
- gfp |= __GFP_DMA;
- else if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
- dev->coherent_dma_mask <= DMA_BIT_MASK(32))
- gfp |= __GFP_DMA32;
-
- /* Don't invoke OOM killer */
- gfp |= __GFP_NORETRY;
-
- ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
+ void *ret = swiotlb_alloc(dev, size, dma_handle, gfp, attrs);
mb();
return ret;
}
-static void octeon_dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle, unsigned long attrs)
-{
- swiotlb_free_coherent(dev, size, vaddr, dma_handle);
-}
-
static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t paddr)
{
return paddr;
@@ -225,7 +205,7 @@ EXPORT_SYMBOL(dma_to_phys);
static struct octeon_dma_map_ops octeon_linear_dma_map_ops = {
.dma_map_ops = {
.alloc = octeon_dma_alloc_coherent,
- .free = octeon_dma_free_coherent,
+ .free = swiotlb_free,
.map_page = octeon_dma_map_page,
.unmap_page = swiotlb_unmap_page,
.map_sg = octeon_dma_map_sg,
@@ -311,7 +291,7 @@ void __init plat_swiotlb_setup(void)
static struct octeon_dma_map_ops _octeon_pci_dma_map_ops = {
.dma_map_ops = {
.alloc = octeon_dma_alloc_coherent,
- .free = octeon_dma_free_coherent,
+ .free = swiotlb_free,
.map_page = octeon_dma_map_page,
.unmap_page = swiotlb_unmap_page,
.map_sg = octeon_dma_map_sg,
diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig
index 0d249fc3cfe9..6f109bb54cdb 100644
--- a/arch/mips/loongson64/Kconfig
+++ b/arch/mips/loongson64/Kconfig
@@ -136,6 +136,7 @@ config SWIOTLB
bool "Soft IOMMU Support for All-Memory DMA"
default y
depends on CPU_LOONGSON3
+ select DMA_DIRECT_OPS
select IOMMU_HELPER
select NEED_SG_DMA_LENGTH
select NEED_DMA_MAP_STATE
diff --git a/arch/mips/loongson64/common/dma-swiotlb.c b/arch/mips/loongson64/common/dma-swiotlb.c
index 15388c24a504..7bbcf89475f3 100644
--- a/arch/mips/loongson64/common/dma-swiotlb.c
+++ b/arch/mips/loongson64/common/dma-swiotlb.c
@@ -13,29 +13,12 @@
static void *loongson_dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
{
- void *ret;
+ void *ret = swiotlb_alloc(dev, size, dma_handle, gfp, attrs);
- if ((IS_ENABLED(CONFIG_ISA) && dev == NULL) ||
- (IS_ENABLED(CONFIG_ZONE_DMA) &&
- dev->coherent_dma_mask < DMA_BIT_MASK(32)))
- gfp |= __GFP_DMA;
- else if (IS_ENABLED(CONFIG_ZONE_DMA32) &&
- dev->coherent_dma_mask < DMA_BIT_MASK(40))
- gfp |= __GFP_DMA32;
-
- gfp |= __GFP_NORETRY;
-
- ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
mb();
return ret;
}
-static void loongson_dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle, unsigned long attrs)
-{
- swiotlb_free_coherent(dev, size, vaddr, dma_handle);
-}
-
static dma_addr_t loongson_dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
enum dma_data_direction dir,
@@ -106,7 +89,7 @@ phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
static const struct dma_map_ops loongson_dma_map_ops = {
.alloc = loongson_dma_alloc_coherent,
- .free = loongson_dma_free_coherent,
+ .free = swiotlb_free,
.map_page = loongson_dma_map_page,
.unmap_page = swiotlb_unmap_page,
.map_sg = loongson_dma_map_sg,
--
2.14.2
^ permalink raw reply related
* [PATCH 19/22] mips/netlogic: remove swiotlb support
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
nlm_swiotlb_dma_ops is unused code, so the whole swiotlb support is dead.
If it gets resurrected at some point it should use the generic
swiotlb_dma_ops instead.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/mips/include/asm/netlogic/common.h | 3 --
arch/mips/netlogic/Kconfig | 5 --
arch/mips/netlogic/common/Makefile | 1 -
arch/mips/netlogic/common/nlm-dma.c | 94 ---------------------------------
4 files changed, 103 deletions(-)
delete mode 100644 arch/mips/netlogic/common/nlm-dma.c
diff --git a/arch/mips/include/asm/netlogic/common.h b/arch/mips/include/asm/netlogic/common.h
index a6e6cbebe046..57616649b4f3 100644
--- a/arch/mips/include/asm/netlogic/common.h
+++ b/arch/mips/include/asm/netlogic/common.h
@@ -87,9 +87,6 @@ unsigned int nlm_get_cpu_frequency(void);
extern const struct plat_smp_ops nlm_smp_ops;
extern char nlm_reset_entry[], nlm_reset_entry_end[];
-/* SWIOTLB */
-extern const struct dma_map_ops nlm_swiotlb_dma_ops;
-
extern unsigned int nlm_threads_per_core;
extern cpumask_t nlm_cpumask;
diff --git a/arch/mips/netlogic/Kconfig b/arch/mips/netlogic/Kconfig
index 8296b13affd2..7fcfc7fe9f14 100644
--- a/arch/mips/netlogic/Kconfig
+++ b/arch/mips/netlogic/Kconfig
@@ -89,9 +89,4 @@ config IOMMU_HELPER
config NEED_SG_DMA_LENGTH
bool
-config SWIOTLB
- def_bool y
- select NEED_SG_DMA_LENGTH
- select IOMMU_HELPER
-
endif
diff --git a/arch/mips/netlogic/common/Makefile b/arch/mips/netlogic/common/Makefile
index 60d00b5d748e..89f6e3f39fed 100644
--- a/arch/mips/netlogic/common/Makefile
+++ b/arch/mips/netlogic/common/Makefile
@@ -1,6 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
obj-y += irq.o time.o
-obj-y += nlm-dma.o
obj-y += reset.o
obj-$(CONFIG_SMP) += smp.o smpboot.o
obj-$(CONFIG_EARLY_PRINTK) += earlycons.o
diff --git a/arch/mips/netlogic/common/nlm-dma.c b/arch/mips/netlogic/common/nlm-dma.c
deleted file mode 100644
index 49c975b6aa28..000000000000
--- a/arch/mips/netlogic/common/nlm-dma.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
-* Copyright (C) 2003-2013 Broadcom Corporation
-* All Rights Reserved
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the Broadcom
- * license below:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include <linux/dma-mapping.h>
-#include <linux/scatterlist.h>
-#include <linux/bootmem.h>
-#include <linux/export.h>
-#include <linux/swiotlb.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-
-#include <asm/bootinfo.h>
-
-static char *nlm_swiotlb;
-
-static void *nlm_dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
-{
-#ifdef CONFIG_ZONE_DMA32
- if (dev->coherent_dma_mask <= DMA_BIT_MASK(32))
- gfp |= __GFP_DMA32;
-#endif
-
- /* Don't invoke OOM killer */
- gfp |= __GFP_NORETRY;
-
- return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
-}
-
-static void nlm_dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle, unsigned long attrs)
-{
- swiotlb_free_coherent(dev, size, vaddr, dma_handle);
-}
-
-const struct dma_map_ops nlm_swiotlb_dma_ops = {
- .alloc = nlm_dma_alloc_coherent,
- .free = nlm_dma_free_coherent,
- .map_page = swiotlb_map_page,
- .unmap_page = swiotlb_unmap_page,
- .map_sg = swiotlb_map_sg_attrs,
- .unmap_sg = swiotlb_unmap_sg_attrs,
- .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
- .sync_single_for_device = swiotlb_sync_single_for_device,
- .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
- .sync_sg_for_device = swiotlb_sync_sg_for_device,
- .mapping_error = swiotlb_dma_mapping_error,
- .dma_supported = swiotlb_dma_supported
-};
-
-void __init plat_swiotlb_setup(void)
-{
- size_t swiotlbsize;
- unsigned long swiotlb_nslabs;
-
- swiotlbsize = 1 << 20; /* 1 MB for now */
- swiotlb_nslabs = swiotlbsize >> IO_TLB_SHIFT;
- swiotlb_nslabs = ALIGN(swiotlb_nslabs, IO_TLB_SEGSIZE);
- swiotlbsize = swiotlb_nslabs << IO_TLB_SHIFT;
-
- nlm_swiotlb = alloc_bootmem_low_pages(swiotlbsize);
- swiotlb_init_with_tbl(nlm_swiotlb, swiotlb_nslabs, 1);
-}
--
2.14.2
^ permalink raw reply related
* [PATCH 18/22] tile: use generic swiotlb_ops
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
These are identical to the tile ops, and would also support CMA
if enabled on tile.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/tile/Kconfig | 1 +
arch/tile/kernel/pci-dma.c | 36 +++---------------------------------
2 files changed, 4 insertions(+), 33 deletions(-)
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 30c586686f29..ef9d403cbbe4 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -261,6 +261,7 @@ config NEED_SG_DMA_LENGTH
config SWIOTLB
bool
default TILEGX
+ select DMA_DIRECT_OPS
select IOMMU_HELPER
select NEED_SG_DMA_LENGTH
select ARCH_HAS_DMA_SET_COHERENT_MASK
diff --git a/arch/tile/kernel/pci-dma.c b/arch/tile/kernel/pci-dma.c
index a267fa740048..6a1efe5543fa 100644
--- a/arch/tile/kernel/pci-dma.c
+++ b/arch/tile/kernel/pci-dma.c
@@ -509,39 +509,9 @@ EXPORT_SYMBOL(gx_pci_dma_map_ops);
/* PCI DMA mapping functions for legacy PCI devices */
#ifdef CONFIG_SWIOTLB
-static void *tile_swiotlb_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp,
- unsigned long attrs)
-{
- gfp |= GFP_DMA32;
- return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
-}
-
-static void tile_swiotlb_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_addr,
- unsigned long attrs)
-{
- swiotlb_free_coherent(dev, size, vaddr, dma_addr);
-}
-
-static const struct dma_map_ops pci_swiotlb_dma_ops = {
- .alloc = tile_swiotlb_alloc_coherent,
- .free = tile_swiotlb_free_coherent,
- .map_page = swiotlb_map_page,
- .unmap_page = swiotlb_unmap_page,
- .map_sg = swiotlb_map_sg_attrs,
- .unmap_sg = swiotlb_unmap_sg_attrs,
- .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
- .sync_single_for_device = swiotlb_sync_single_for_device,
- .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
- .sync_sg_for_device = swiotlb_sync_sg_for_device,
- .dma_supported = swiotlb_dma_supported,
- .mapping_error = swiotlb_dma_mapping_error,
-};
-
static const struct dma_map_ops pci_hybrid_dma_ops = {
- .alloc = tile_swiotlb_alloc_coherent,
- .free = tile_swiotlb_free_coherent,
+ .alloc = swiotlb_alloc,
+ .free = swiotlb_free,
.map_page = tile_pci_dma_map_page,
.unmap_page = tile_pci_dma_unmap_page,
.map_sg = tile_pci_dma_map_sg,
@@ -552,7 +522,7 @@ static const struct dma_map_ops pci_hybrid_dma_ops = {
.sync_sg_for_device = tile_pci_dma_sync_sg_for_device,
};
-const struct dma_map_ops *gx_legacy_pci_dma_map_ops = &pci_swiotlb_dma_ops;
+const struct dma_map_ops *gx_legacy_pci_dma_map_ops = &swiotlb_dma_ops;
const struct dma_map_ops *gx_hybrid_pci_dma_map_ops = &pci_hybrid_dma_ops;
#else
const struct dma_map_ops *gx_legacy_pci_dma_map_ops;
--
2.14.2
^ permalink raw reply related
* [PATCH 17/22] tile: replace ZONE_DMA with ZONE_DMA32
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
tile uses ZONE_DMA for allocations below 32-bits. These days we
name the zone for that ZONE_DMA32, which will allow to use the
dma-direct and generic swiotlb code as-is, so rename it.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/tile/Kconfig | 2 +-
arch/tile/kernel/pci-dma.c | 4 ++--
arch/tile/kernel/setup.c | 8 ++++----
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 02f269cfa538..30c586686f29 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -249,7 +249,7 @@ config HIGHMEM
If unsure, say "true".
-config ZONE_DMA
+config ZONE_DMA32
def_bool y
config IOMMU_HELPER
diff --git a/arch/tile/kernel/pci-dma.c b/arch/tile/kernel/pci-dma.c
index f2abedc8a080..a267fa740048 100644
--- a/arch/tile/kernel/pci-dma.c
+++ b/arch/tile/kernel/pci-dma.c
@@ -54,7 +54,7 @@ static void *tile_dma_alloc_coherent(struct device *dev, size_t size,
* which case we will return NULL. But such devices are uncommon.
*/
if (dma_mask <= DMA_BIT_MASK(32)) {
- gfp |= GFP_DMA;
+ gfp |= GFP_DMA32;
node = 0;
}
@@ -513,7 +513,7 @@ static void *tile_swiotlb_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp,
unsigned long attrs)
{
- gfp |= GFP_DMA;
+ gfp |= GFP_DMA32;
return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
}
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c
index ad83c1e66dbd..eb4e198f6f93 100644
--- a/arch/tile/kernel/setup.c
+++ b/arch/tile/kernel/setup.c
@@ -814,11 +814,11 @@ static void __init zone_sizes_init(void)
#endif
if (start < dma_end) {
- zones_size[ZONE_DMA] = min(zones_size[ZONE_NORMAL],
+ zones_size[ZONE_DMA32] = min(zones_size[ZONE_NORMAL],
dma_end - start);
- zones_size[ZONE_NORMAL] -= zones_size[ZONE_DMA];
+ zones_size[ZONE_NORMAL] -= zones_size[ZONE_DMA32];
} else {
- zones_size[ZONE_DMA] = 0;
+ zones_size[ZONE_DMA32] = 0;
}
/* Take zone metadata from controller 0 if we're isolnode. */
@@ -830,7 +830,7 @@ static void __init zone_sizes_init(void)
PFN_UP(node_percpu[i]));
/* Track the type of memory on each node */
- if (zones_size[ZONE_NORMAL] || zones_size[ZONE_DMA])
+ if (zones_size[ZONE_NORMAL] || zones_size[ZONE_DMA32])
node_set_state(i, N_NORMAL_MEMORY);
#ifdef CONFIG_HIGHMEM
if (end != start)
--
2.14.2
^ permalink raw reply related
* [PATCH 16/22] unicore32: use generic swiotlb_ops
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
These are identical to the unicore32 ops, and would also support CMA
if enabled on unicore32.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/unicore32/include/asm/dma-mapping.h | 9 +-----
arch/unicore32/mm/Kconfig | 1 +
arch/unicore32/mm/Makefile | 2 --
arch/unicore32/mm/dma-swiotlb.c | 48 --------------------------------
4 files changed, 2 insertions(+), 58 deletions(-)
delete mode 100644 arch/unicore32/mm/dma-swiotlb.c
diff --git a/arch/unicore32/include/asm/dma-mapping.h b/arch/unicore32/include/asm/dma-mapping.h
index f2bfec273aa7..790bc2ef4af2 100644
--- a/arch/unicore32/include/asm/dma-mapping.h
+++ b/arch/unicore32/include/asm/dma-mapping.h
@@ -12,18 +12,11 @@
#ifndef __UNICORE_DMA_MAPPING_H__
#define __UNICORE_DMA_MAPPING_H__
-#ifdef __KERNEL__
-
-#include <linux/mm_types.h>
-#include <linux/scatterlist.h>
#include <linux/swiotlb.h>
-extern const struct dma_map_ops swiotlb_dma_map_ops;
-
static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
{
- return &swiotlb_dma_map_ops;
+ return &swiotlb_dma_ops;
}
-#endif /* __KERNEL__ */
#endif
diff --git a/arch/unicore32/mm/Kconfig b/arch/unicore32/mm/Kconfig
index c256460cd363..e9154a59d561 100644
--- a/arch/unicore32/mm/Kconfig
+++ b/arch/unicore32/mm/Kconfig
@@ -42,6 +42,7 @@ config CPU_TLB_SINGLE_ENTRY_DISABLE
config SWIOTLB
def_bool y
+ select DMA_DIRECT_OPS
config IOMMU_HELPER
def_bool SWIOTLB
diff --git a/arch/unicore32/mm/Makefile b/arch/unicore32/mm/Makefile
index 681c0ef5ec9e..8106260583ab 100644
--- a/arch/unicore32/mm/Makefile
+++ b/arch/unicore32/mm/Makefile
@@ -6,8 +6,6 @@
obj-y := extable.o fault.o init.o pgd.o mmu.o
obj-y += flush.o ioremap.o
-obj-$(CONFIG_SWIOTLB) += dma-swiotlb.o
-
obj-$(CONFIG_MODULES) += proc-syms.o
obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
diff --git a/arch/unicore32/mm/dma-swiotlb.c b/arch/unicore32/mm/dma-swiotlb.c
deleted file mode 100644
index 525413d6690e..000000000000
--- a/arch/unicore32/mm/dma-swiotlb.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Contains routines needed to support swiotlb for UniCore32.
- *
- * Copyright (C) 2010 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-#include <linux/pci.h>
-#include <linux/cache.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <linux/swiotlb.h>
-#include <linux/bootmem.h>
-
-#include <asm/dma.h>
-
-static void *unicore_swiotlb_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flags,
- unsigned long attrs)
-{
- return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
-}
-
-static void unicore_swiotlb_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_addr,
- unsigned long attrs)
-{
- swiotlb_free_coherent(dev, size, vaddr, dma_addr);
-}
-
-const struct dma_map_ops swiotlb_dma_map_ops = {
- .alloc = unicore_swiotlb_alloc_coherent,
- .free = unicore_swiotlb_free_coherent,
- .map_sg = swiotlb_map_sg_attrs,
- .unmap_sg = swiotlb_unmap_sg_attrs,
- .dma_supported = swiotlb_dma_supported,
- .map_page = swiotlb_map_page,
- .unmap_page = swiotlb_unmap_page,
- .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
- .sync_single_for_device = swiotlb_sync_single_for_device,
- .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
- .sync_sg_for_device = swiotlb_sync_sg_for_device,
- .mapping_error = swiotlb_dma_mapping_error,
-};
-EXPORT_SYMBOL(swiotlb_dma_map_ops);
--
2.14.2
^ permalink raw reply related
* [PATCH 15/22] ia64: remove an ifdef around the content of pci-dma.c
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
The file is only compiled if CONFIG_INTEL_IOMMU is set to start with.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/ia64/kernel/pci-dma.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c
index 35e0cad33b7d..b5df084c0af4 100644
--- a/arch/ia64/kernel/pci-dma.c
+++ b/arch/ia64/kernel/pci-dma.c
@@ -12,12 +12,7 @@
#include <asm/iommu.h>
#include <asm/machvec.h>
#include <linux/dma-mapping.h>
-
-
-#ifdef CONFIG_INTEL_IOMMU
-
#include <linux/kernel.h>
-
#include <asm/page.h>
dma_addr_t bad_dma_address __read_mostly;
@@ -115,5 +110,3 @@ void __init pci_iommu_alloc(void)
}
#endif /* CONFIG_SWIOTLB */
}
-
-#endif
--
2.14.2
^ permalink raw reply related
* [PATCH 14/22] ia64: clean up swiotlb support
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
Move the few remaining bits of swiotlb glue towards their callers,
and remove the pointless on ia64 swiotlb variable.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/ia64/include/asm/dma-mapping.h | 1 -
arch/ia64/include/asm/swiotlb.h | 18 ------------------
arch/ia64/kernel/dma-mapping.c | 9 +++++++++
arch/ia64/kernel/pci-dma.c | 12 ++++++++++--
arch/ia64/kernel/pci-swiotlb.c | 36 ------------------------------------
drivers/iommu/intel-iommu.c | 2 +-
6 files changed, 20 insertions(+), 58 deletions(-)
delete mode 100644 arch/ia64/include/asm/swiotlb.h
delete mode 100644 arch/ia64/kernel/pci-swiotlb.c
diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h
index eabee56d995c..76e4d6632d68 100644
--- a/arch/ia64/include/asm/dma-mapping.h
+++ b/arch/ia64/include/asm/dma-mapping.h
@@ -8,7 +8,6 @@
*/
#include <asm/machvec.h>
#include <linux/scatterlist.h>
-#include <asm/swiotlb.h>
#include <linux/dma-debug.h>
#define ARCH_HAS_DMA_GET_REQUIRED_MASK
diff --git a/arch/ia64/include/asm/swiotlb.h b/arch/ia64/include/asm/swiotlb.h
deleted file mode 100644
index 841e2c7d0b21..000000000000
--- a/arch/ia64/include/asm/swiotlb.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef ASM_IA64__SWIOTLB_H
-#define ASM_IA64__SWIOTLB_H
-
-#include <linux/dma-mapping.h>
-#include <linux/swiotlb.h>
-
-#ifdef CONFIG_SWIOTLB
-extern int swiotlb;
-extern void pci_swiotlb_init(void);
-#else
-#define swiotlb 0
-static inline void pci_swiotlb_init(void)
-{
-}
-#endif
-
-#endif /* ASM_IA64__SWIOTLB_H */
diff --git a/arch/ia64/kernel/dma-mapping.c b/arch/ia64/kernel/dma-mapping.c
index 7a82c9259609..f2d57e66fd86 100644
--- a/arch/ia64/kernel/dma-mapping.c
+++ b/arch/ia64/kernel/dma-mapping.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/dma-mapping.h>
+#include <linux/swiotlb.h>
#include <linux/export.h>
/* Set this to 1 if there is a HW IOMMU in the system */
@@ -23,3 +24,11 @@ const struct dma_map_ops *dma_get_ops(struct device *dev)
return dma_ops;
}
EXPORT_SYMBOL(dma_get_ops);
+
+#ifdef CONFIG_SWIOTLB
+void __init swiotlb_dma_init(void)
+{
+ dma_ops = &swiotlb_dma_ops;
+ swiotlb_init(1);
+}
+#endif
diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c
index 3ba87c22dfbc..35e0cad33b7d 100644
--- a/arch/ia64/kernel/pci-dma.c
+++ b/arch/ia64/kernel/pci-dma.c
@@ -104,8 +104,16 @@ void __init pci_iommu_alloc(void)
detect_intel_iommu();
#ifdef CONFIG_SWIOTLB
- pci_swiotlb_init();
-#endif
+ if (!iommu_detected) {
+#ifdef CONFIG_IA64_GENERIC
+ printk(KERN_INFO "PCI-DMA: Re-initialize machine vector.\n");
+ machvec_init("dig");
+ swiotlb_dma_init();
+#else
+ panic("Unable to find Intel IOMMU");
+#endif /* CONFIG_IA64_GENERIC */
+ }
+#endif /* CONFIG_SWIOTLB */
}
#endif
diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c
deleted file mode 100644
index 0f8d5fbd86bd..000000000000
--- a/arch/ia64/kernel/pci-swiotlb.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Glue code to lib/swiotlb.c */
-
-#include <linux/pci.h>
-#include <linux/gfp.h>
-#include <linux/cache.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <linux/swiotlb.h>
-#include <asm/dma.h>
-#include <asm/iommu.h>
-#include <asm/machvec.h>
-
-int swiotlb __read_mostly;
-EXPORT_SYMBOL(swiotlb);
-
-void __init swiotlb_dma_init(void)
-{
- dma_ops = &swiotlb_dma_ops;
- swiotlb_init(1);
-}
-
-void __init pci_swiotlb_init(void)
-{
- if (!iommu_detected) {
-#ifdef CONFIG_IA64_GENERIC
- swiotlb = 1;
- printk(KERN_INFO "PCI-DMA: Re-initialize machine vector.\n");
- machvec_init("dig");
- swiotlb_init(1);
- dma_ops = &swiotlb_dma_ops;
-#else
- panic("Unable to find Intel IOMMU");
-#endif
- }
-}
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 4a2de34895ec..a1373cf34326 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -4808,7 +4808,7 @@ int __init intel_iommu_init(void)
up_write(&dmar_global_lock);
pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
-#ifdef CONFIG_SWIOTLB
+#if defined(CONFIG_X86) && defined(CONFIG_SWIOTLB)
swiotlb = 0;
#endif
dma_ops = &intel_dma_ops;
--
2.14.2
^ permalink raw reply related
* [PATCH 13/22] ia64: use generic swiotlb_ops
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
These are identical to the ia64 ops, and would also support CMA
if enabled on ia64.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/ia64/Kconfig | 5 +++++
arch/ia64/hp/common/hwsw_iommu.c | 4 ++--
arch/ia64/hp/common/sba_iommu.c | 6 +++---
arch/ia64/kernel/pci-swiotlb.c | 38 +++-----------------------------------
4 files changed, 13 insertions(+), 40 deletions(-)
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 888acdb163cb..29148fe4bf5a 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -146,6 +146,7 @@ config IA64_GENERIC
bool "generic"
select NUMA
select ACPI_NUMA
+ select DMA_DIRECT_OPS
select SWIOTLB
select PCI_MSI
help
@@ -166,6 +167,7 @@ config IA64_GENERIC
config IA64_DIG
bool "DIG-compliant"
+ select DMA_DIRECT_OPS
select SWIOTLB
config IA64_DIG_VTD
@@ -181,6 +183,7 @@ config IA64_HP_ZX1
config IA64_HP_ZX1_SWIOTLB
bool "HP-zx1/sx1000 with software I/O TLB"
+ select DMA_DIRECT_OPS
select SWIOTLB
help
Build a kernel that runs on HP zx1 and sx1000 systems even when they
@@ -204,6 +207,7 @@ config IA64_SGI_UV
bool "SGI-UV"
select NUMA
select ACPI_NUMA
+ select DMA_DIRECT_OPS
select SWIOTLB
help
Selecting this option will optimize the kernel for use on UV based
@@ -214,6 +218,7 @@ config IA64_SGI_UV
config IA64_HP_SIM
bool "Ski-simulator"
+ select DMA_DIRECT_OPS
select SWIOTLB
depends on !PM
diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c
index 41279f0442bd..58969039bed2 100644
--- a/arch/ia64/hp/common/hwsw_iommu.c
+++ b/arch/ia64/hp/common/hwsw_iommu.c
@@ -19,7 +19,7 @@
#include <linux/export.h>
#include <asm/machvec.h>
-extern const struct dma_map_ops sba_dma_ops, ia64_swiotlb_dma_ops;
+extern const struct dma_map_ops sba_dma_ops;
/* swiotlb declarations & definitions: */
extern int swiotlb_late_init_with_default_size (size_t size);
@@ -38,7 +38,7 @@ static inline int use_swiotlb(struct device *dev)
const struct dma_map_ops *hwsw_dma_get_ops(struct device *dev)
{
if (use_swiotlb(dev))
- return &ia64_swiotlb_dma_ops;
+ return &swiotlb_dma_ops;
return &sba_dma_ops;
}
EXPORT_SYMBOL(hwsw_dma_get_ops);
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 8c0a9ae6afec..aec4a3354abe 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -2096,7 +2096,7 @@ static int __init acpi_sba_ioc_init_acpi(void)
/* This has to run before acpi_scan_init(). */
arch_initcall(acpi_sba_ioc_init_acpi);
-extern const struct dma_map_ops ia64_swiotlb_dma_ops;
+extern const struct dma_map_ops swiotlb_dma_ops;
static int __init
sba_init(void)
@@ -2111,7 +2111,7 @@ sba_init(void)
* a successful kdump kernel boot is to use the swiotlb.
*/
if (is_kdump_kernel()) {
- dma_ops = &ia64_swiotlb_dma_ops;
+ dma_ops = &swiotlb_dma_ops;
if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
panic("Unable to initialize software I/O TLB:"
" Try machvec=dig boot option");
@@ -2133,7 +2133,7 @@ sba_init(void)
* If we didn't find something sba_iommu can claim, we
* need to setup the swiotlb and switch to the dig machvec.
*/
- dma_ops = &ia64_swiotlb_dma_ops;
+ dma_ops = &swiotlb_dma_ops;
if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
panic("Unable to find SBA IOMMU or initialize "
"software I/O TLB: Try machvec=dig boot option");
diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c
index 4a9a6e58ad6a..0f8d5fbd86bd 100644
--- a/arch/ia64/kernel/pci-swiotlb.c
+++ b/arch/ia64/kernel/pci-swiotlb.c
@@ -6,8 +6,7 @@
#include <linux/cache.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
-
-#include <asm/swiotlb.h>
+#include <linux/swiotlb.h>
#include <asm/dma.h>
#include <asm/iommu.h>
#include <asm/machvec.h>
@@ -15,40 +14,9 @@
int swiotlb __read_mostly;
EXPORT_SYMBOL(swiotlb);
-static void *ia64_swiotlb_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp,
- unsigned long attrs)
-{
- if (dev->coherent_dma_mask != DMA_BIT_MASK(64))
- gfp |= GFP_DMA32;
- return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
-}
-
-static void ia64_swiotlb_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_addr,
- unsigned long attrs)
-{
- swiotlb_free_coherent(dev, size, vaddr, dma_addr);
-}
-
-const struct dma_map_ops ia64_swiotlb_dma_ops = {
- .alloc = ia64_swiotlb_alloc_coherent,
- .free = ia64_swiotlb_free_coherent,
- .map_page = swiotlb_map_page,
- .unmap_page = swiotlb_unmap_page,
- .map_sg = swiotlb_map_sg_attrs,
- .unmap_sg = swiotlb_unmap_sg_attrs,
- .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
- .sync_single_for_device = swiotlb_sync_single_for_device,
- .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
- .sync_sg_for_device = swiotlb_sync_sg_for_device,
- .dma_supported = swiotlb_dma_supported,
- .mapping_error = swiotlb_dma_mapping_error,
-};
-
void __init swiotlb_dma_init(void)
{
- dma_ops = &ia64_swiotlb_dma_ops;
+ dma_ops = &swiotlb_dma_ops;
swiotlb_init(1);
}
@@ -60,7 +28,7 @@ void __init pci_swiotlb_init(void)
printk(KERN_INFO "PCI-DMA: Re-initialize machine vector.\n");
machvec_init("dig");
swiotlb_init(1);
- dma_ops = &ia64_swiotlb_dma_ops;
+ dma_ops = &swiotlb_dma_ops;
#else
panic("Unable to find Intel IOMMU");
#endif
--
2.14.2
^ permalink raw reply related
* [PATCH 12/22] ia64: replace ZONE_DMA with ZONE_DMA32
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
ia64 uses ZONE_DMA for allocations below 32-bits. These days we
name the zone for that ZONE_DMA32, which will allow to use the
dma-direct and generic swiotlb code as-is, so rename it.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/ia64/Kconfig | 2 +-
arch/ia64/kernel/pci-swiotlb.c | 2 +-
arch/ia64/mm/contig.c | 4 ++--
arch/ia64/mm/discontig.c | 8 ++++----
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 4d18fca885ee..888acdb163cb 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -66,7 +66,7 @@ config 64BIT
select ATA_NONSTANDARD if ATA
default y
-config ZONE_DMA
+config ZONE_DMA32
def_bool y
depends on !IA64_SGI_SN2
diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c
index f1ae873a8c35..4a9a6e58ad6a 100644
--- a/arch/ia64/kernel/pci-swiotlb.c
+++ b/arch/ia64/kernel/pci-swiotlb.c
@@ -20,7 +20,7 @@ static void *ia64_swiotlb_alloc_coherent(struct device *dev, size_t size,
unsigned long attrs)
{
if (dev->coherent_dma_mask != DMA_BIT_MASK(64))
- gfp |= GFP_DMA;
+ gfp |= GFP_DMA32;
return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
}
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
index 52715a71aede..7d64b30913d1 100644
--- a/arch/ia64/mm/contig.c
+++ b/arch/ia64/mm/contig.c
@@ -237,9 +237,9 @@ paging_init (void)
unsigned long max_zone_pfns[MAX_NR_ZONES];
memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
-#ifdef CONFIG_ZONE_DMA
+#ifdef CONFIG_ZONE_DMA32
max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
- max_zone_pfns[ZONE_DMA] = max_dma;
+ max_zone_pfns[ZONE_DMA32] = max_dma;
#endif
max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 9b2d994cddf6..ac46f0d60b66 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -38,7 +38,7 @@ struct early_node_data {
struct ia64_node_data *node_data;
unsigned long pernode_addr;
unsigned long pernode_size;
-#ifdef CONFIG_ZONE_DMA
+#ifdef CONFIG_ZONE_DMA32
unsigned long num_dma_physpages;
#endif
unsigned long min_pfn;
@@ -669,7 +669,7 @@ static __init int count_node_pages(unsigned long start, unsigned long len, int n
{
unsigned long end = start + len;
-#ifdef CONFIG_ZONE_DMA
+#ifdef CONFIG_ZONE_DMA32
if (start <= __pa(MAX_DMA_ADDRESS))
mem_data[node].num_dma_physpages +=
(min(end, __pa(MAX_DMA_ADDRESS)) - start) >>PAGE_SHIFT;
@@ -724,8 +724,8 @@ void __init paging_init(void)
}
memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
-#ifdef CONFIG_ZONE_DMA
- max_zone_pfns[ZONE_DMA] = max_dma;
+#ifdef CONFIG_ZONE_DMA32
+ max_zone_pfns[ZONE_DMA32] = max_dma;
#endif
max_zone_pfns[ZONE_NORMAL] = max_pfn;
free_area_init_nodes(max_zone_pfns);
--
2.14.2
^ permalink raw reply related
* [PATCH 11/22] swiotlb: remove various exports
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
All these symbols are only used by arch dma_ops implementations or
xen-swiotlb. None of which can be modular.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
lib/swiotlb.c | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index bf2d19ee91c1..1eac51ff77a4 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -605,7 +605,6 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
return tlb_addr;
}
-EXPORT_SYMBOL_GPL(swiotlb_tbl_map_single);
/*
* Allocates bounce buffer and returns its kernel virtual address.
@@ -675,7 +674,6 @@ void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr,
}
spin_unlock_irqrestore(&io_tlb_lock, flags);
}
-EXPORT_SYMBOL_GPL(swiotlb_tbl_unmap_single);
void swiotlb_tbl_sync_single(struct device *hwdev, phys_addr_t tlb_addr,
size_t size, enum dma_data_direction dir,
@@ -707,7 +705,6 @@ void swiotlb_tbl_sync_single(struct device *hwdev, phys_addr_t tlb_addr,
BUG();
}
}
-EXPORT_SYMBOL_GPL(swiotlb_tbl_sync_single);
static inline bool dma_coherent_ok(struct device *dev, dma_addr_t addr,
size_t size)
@@ -884,7 +881,6 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
return swiotlb_phys_to_dma(dev, io_tlb_overflow_buffer);
}
-EXPORT_SYMBOL_GPL(swiotlb_map_page);
/*
* Unmap a single streaming mode DMA translation. The dma_addr and size must
@@ -925,7 +921,6 @@ void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
{
unmap_single(hwdev, dev_addr, size, dir, attrs);
}
-EXPORT_SYMBOL_GPL(swiotlb_unmap_page);
/*
* Make physical memory consistent for a single streaming mode DMA translation
@@ -963,7 +958,6 @@ swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
{
swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU);
}
-EXPORT_SYMBOL(swiotlb_sync_single_for_cpu);
void
swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
@@ -971,7 +965,6 @@ swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
{
swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE);
}
-EXPORT_SYMBOL(swiotlb_sync_single_for_device);
/*
* Map a set of buffers described by scatterlist in streaming mode for DMA.
@@ -1023,7 +1016,6 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
}
return nelems;
}
-EXPORT_SYMBOL(swiotlb_map_sg_attrs);
/*
* Unmap a set of streaming mode DMA translations. Again, cpu read rules
@@ -1043,7 +1035,6 @@ swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
unmap_single(hwdev, sg->dma_address, sg_dma_len(sg), dir,
attrs);
}
-EXPORT_SYMBOL(swiotlb_unmap_sg_attrs);
/*
* Make physical memory consistent for a set of streaming mode DMA translations
@@ -1071,7 +1062,6 @@ swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
{
swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU);
}
-EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu);
void
swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
@@ -1079,14 +1069,12 @@ swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
{
swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE);
}
-EXPORT_SYMBOL(swiotlb_sync_sg_for_device);
int
swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr)
{
return (dma_addr == swiotlb_phys_to_dma(hwdev, io_tlb_overflow_buffer));
}
-EXPORT_SYMBOL(swiotlb_dma_mapping_error);
/*
* Return whether the given device DMA address mask can be supported
@@ -1099,7 +1087,6 @@ swiotlb_dma_supported(struct device *hwdev, u64 mask)
{
return swiotlb_phys_to_dma(hwdev, io_tlb_end - 1) <= mask;
}
-EXPORT_SYMBOL(swiotlb_dma_supported);
#ifdef CONFIG_DMA_DIRECT_OPS
void *swiotlb_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
--
2.14.2
^ permalink raw reply related
* [PATCH 10/22] swiotlb: refactor coherent buffer allocation
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
Factor out a new swiotlb_alloc_buffer helper that allocates DMA coherent
memory from the swiotlb bounce buffer.
This allows to simplify the swiotlb_alloc implemenation that uses
dma_direct_alloc to try to allocate a reachable buffer first.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
lib/swiotlb.c | 122 +++++++++++++++++++++++++++++++---------------------------
1 file changed, 65 insertions(+), 57 deletions(-)
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 1a147f1354a1..bf2d19ee91c1 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -709,75 +709,79 @@ void swiotlb_tbl_sync_single(struct device *hwdev, phys_addr_t tlb_addr,
}
EXPORT_SYMBOL_GPL(swiotlb_tbl_sync_single);
-void *
-swiotlb_alloc_coherent(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, gfp_t flags)
+static inline bool dma_coherent_ok(struct device *dev, dma_addr_t addr,
+ size_t size)
{
- bool warn = !(flags & __GFP_NOWARN);
- dma_addr_t dev_addr;
- void *ret;
- int order = get_order(size);
- u64 dma_mask = DMA_BIT_MASK(32);
+ u64 mask = DMA_BIT_MASK(32);
- if (hwdev && hwdev->coherent_dma_mask)
- dma_mask = hwdev->coherent_dma_mask;
+ if (dev && dev->coherent_dma_mask)
+ mask = dev->coherent_dma_mask;
+ return addr + size - 1 <= mask;
+}
- ret = (void *)__get_free_pages(flags, order);
- if (ret) {
- dev_addr = swiotlb_virt_to_bus(hwdev, ret);
- if (dev_addr + size - 1 > dma_mask) {
- /*
- * The allocated memory isn't reachable by the device.
- */
- free_pages((unsigned long) ret, order);
- ret = NULL;
- }
- }
- if (!ret) {
- /*
- * We are either out of memory or the device can't DMA to
- * GFP_DMA memory; fall back on map_single(), which
- * will grab memory from the lowest available address range.
- */
- phys_addr_t paddr = map_single(hwdev, 0, size, DMA_FROM_DEVICE,
- warn ? 0 : DMA_ATTR_NO_WARN);
- if (paddr == SWIOTLB_MAP_ERROR)
- goto err_warn;
+static void *
+swiotlb_alloc_buffer(struct device *dev, size_t size, dma_addr_t *dma_handle,
+ unsigned long attrs)
+{
+ phys_addr_t phys_addr;
+
+ if (swiotlb_force == SWIOTLB_NO_FORCE)
+ goto out_warn;
- ret = phys_to_virt(paddr);
- dev_addr = swiotlb_phys_to_dma(hwdev, paddr);
+ phys_addr = swiotlb_tbl_map_single(dev,
+ swiotlb_phys_to_dma(dev, io_tlb_start),
+ 0, size, DMA_FROM_DEVICE, 0);
+ if (phys_addr == SWIOTLB_MAP_ERROR)
+ goto out_warn;
- /* Confirm address can be DMA'd by device */
- if (dev_addr + size - 1 > dma_mask) {
- printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n",
- (unsigned long long)dma_mask,
- (unsigned long long)dev_addr);
+ *dma_handle = swiotlb_phys_to_dma(dev, phys_addr);
- /*
- * DMA_TO_DEVICE to avoid memcpy in unmap_single.
- * The DMA_ATTR_SKIP_CPU_SYNC is optional.
- */
- swiotlb_tbl_unmap_single(hwdev, paddr,
- size, DMA_TO_DEVICE,
- DMA_ATTR_SKIP_CPU_SYNC);
- goto err_warn;
- }
- }
+ if (dma_coherent_ok(dev, *dma_handle, size))
+ goto out_unmap;
- *dma_handle = dev_addr;
- memset(ret, 0, size);
+ memset(phys_to_virt(phys_addr), 0, size);
+ return phys_to_virt(phys_addr);
- return ret;
+out_unmap:
+ dev_warn(dev, "hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n",
+ (unsigned long long)(dev ? dev->coherent_dma_mask : 0),
+ (unsigned long long)*dma_handle);
-err_warn:
- if (warn && printk_ratelimit()) {
- pr_warn("swiotlb: coherent allocation failed for device %s size=%zu\n",
- dev_name(hwdev), size);
+ /*
+ * DMA_TO_DEVICE to avoid memcpy in unmap_single.
+ * DMA_ATTR_SKIP_CPU_SYNC is optional.
+ */
+ swiotlb_tbl_unmap_single(dev, phys_addr, size, DMA_TO_DEVICE,
+ DMA_ATTR_SKIP_CPU_SYNC);
+out_warn:
+ if ((attrs & DMA_ATTR_NO_WARN) && printk_ratelimit()) {
+ dev_warn(dev,
+ "swiotlb: coherent allocation failed, size=%zu\n",
+ size);
dump_stack();
}
-
return NULL;
}
+
+void *
+swiotlb_alloc_coherent(struct device *hwdev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flags)
+{
+ int order = get_order(size);
+ unsigned long attrs = (flags & __GFP_NOWARN) ? DMA_ATTR_NO_WARN : 0;
+ void *ret;
+
+ ret = (void *)__get_free_pages(flags, order);
+ if (ret) {
+ *dma_handle = swiotlb_virt_to_bus(hwdev, ret);
+ if (dma_coherent_ok(hwdev, *dma_handle, size)) {
+ memset(ret, 0, size);
+ return ret;
+ }
+ }
+
+ return swiotlb_alloc_buffer(hwdev, size, dma_handle, attrs);
+}
EXPORT_SYMBOL(swiotlb_alloc_coherent);
static bool swiotlb_free_buffer(struct device *dev, size_t size,
@@ -1103,6 +1107,10 @@ void *swiotlb_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
{
void *vaddr;
+ /* temporary workaround: */
+ if (gfp & __GFP_NOWARN)
+ attrs |= DMA_ATTR_NO_WARN;
+
/*
* Don't print a warning when the first allocation attempt fails.
* swiotlb_alloc_coherent() will print a warning when the DMA memory
@@ -1112,7 +1120,7 @@ void *swiotlb_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
vaddr = dma_direct_alloc(dev, size, dma_handle, gfp, attrs);
if (!vaddr)
- vaddr = swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
+ vaddr = swiotlb_alloc_buffer(dev, size, dma_handle, attrs);
return vaddr;
}
--
2.14.2
^ permalink raw reply related
* [PATCH 09/22] swiotlb: refactor coherent buffer freeing
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
Factor out a new swiotlb_free_buffer helper that checks if an address
is allocated from the swiotlb bounce buffer, and if yes frees it.
This allows to simplify the swiotlb_free implemenation that uses
dma_direct_free to free the non-bounce buffer allocations.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
lib/swiotlb.c | 35 +++++++++++++++++++++--------------
1 file changed, 21 insertions(+), 14 deletions(-)
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 539fd1099ba9..1a147f1354a1 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -780,22 +780,31 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
}
EXPORT_SYMBOL(swiotlb_alloc_coherent);
+static bool swiotlb_free_buffer(struct device *dev, size_t size,
+ dma_addr_t dma_addr)
+{
+ phys_addr_t phys_addr = dma_to_phys(dev, dma_addr);
+
+ WARN_ON_ONCE(irqs_disabled());
+
+ if (!is_swiotlb_buffer(phys_addr))
+ return false;
+
+ /*
+ * DMA_TO_DEVICE to avoid memcpy in swiotlb_tbl_unmap_single.
+ * DMA_ATTR_SKIP_CPU_SYNC is optional.
+ */
+ swiotlb_tbl_unmap_single(dev, phys_addr, size, DMA_TO_DEVICE,
+ DMA_ATTR_SKIP_CPU_SYNC);
+ return true;
+}
+
void
swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
dma_addr_t dev_addr)
{
- phys_addr_t paddr = dma_to_phys(hwdev, dev_addr);
-
- WARN_ON(irqs_disabled());
- if (!is_swiotlb_buffer(paddr))
+ if (!swiotlb_free_buffer(hwdev, size, dev_addr))
free_pages((unsigned long)vaddr, get_order(size));
- else
- /*
- * DMA_TO_DEVICE to avoid memcpy in swiotlb_tbl_unmap_single.
- * DMA_ATTR_SKIP_CPU_SYNC is optional.
- */
- swiotlb_tbl_unmap_single(hwdev, paddr, size, DMA_TO_DEVICE,
- DMA_ATTR_SKIP_CPU_SYNC);
}
EXPORT_SYMBOL(swiotlb_free_coherent);
@@ -1110,9 +1119,7 @@ void *swiotlb_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
void swiotlb_free(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_addr, unsigned long attrs)
{
- if (is_swiotlb_buffer(dma_to_phys(dev, dma_addr)))
- swiotlb_free_coherent(dev, size, vaddr, dma_addr);
- else
+ if (!swiotlb_free_buffer(dev, size, dma_addr))
dma_direct_free(dev, size, vaddr, dma_addr, attrs);
}
--
2.14.2
^ permalink raw reply related
* [PATCH 08/22] swiotlb: wire up ->dma_supported in swiotlb_dma_ops
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
To properly reject too small DMA masks based on the addressability of the
bounce buffer.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
lib/swiotlb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 0fae2f45c3c0..539fd1099ba9 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -1128,5 +1128,6 @@ const struct dma_map_ops swiotlb_dma_ops = {
.unmap_sg = swiotlb_unmap_sg_attrs,
.map_page = swiotlb_map_page,
.unmap_page = swiotlb_unmap_page,
+ .dma_supported = swiotlb_dma_supported,
};
#endif /* CONFIG_DMA_DIRECT_OPS */
--
2.14.2
^ permalink raw reply related
* [PATCH 07/22] swiotlb: add common swiotlb_map_ops
From: Christoph Hellwig @ 2018-01-10 8:09 UTC (permalink / raw)
To: iommu
Cc: Konrad Rzeszutek Wilk, Michal Simek, Guan Xuetao,
Christian König, linux-arm-kernel, linux-ia64, linux-mips,
linuxppc-dev, x86, linux-arch, linux-kernel
In-Reply-To: <20180110080932.14157-1-hch@lst.de>
Currently all architectures that want to use swiotlb have to implement
their own dma_map_ops instances. Provide a generic one based on the
x86 implementation which first calls into dma_direct to try a full blown
direct mapping implementation (including e.g. CMA) before falling back
allocating from the swiotlb buffer.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/linux/swiotlb.h | 8 ++++++++
lib/swiotlb.c | 43 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+)
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 606375e35d87..5b1f2a00491c 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -66,6 +66,12 @@ extern void swiotlb_tbl_sync_single(struct device *hwdev,
enum dma_sync_target target);
/* Accessory functions. */
+
+void *swiotlb_alloc(struct device *hwdev, size_t size, dma_addr_t *dma_handle,
+ gfp_t flags, unsigned long attrs);
+void swiotlb_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_addr, unsigned long attrs);
+
extern void
*swiotlb_alloc_coherent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, gfp_t flags);
@@ -126,4 +132,6 @@ extern void swiotlb_print_info(void);
extern int is_swiotlb_buffer(phys_addr_t paddr);
extern void swiotlb_set_max_segment(unsigned int);
+extern const struct dma_map_ops swiotlb_dma_ops;
+
#endif /* __LINUX_SWIOTLB_H */
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index cf5311908fa9..0fae2f45c3c0 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -1087,3 +1087,46 @@ swiotlb_dma_supported(struct device *hwdev, u64 mask)
return swiotlb_phys_to_dma(hwdev, io_tlb_end - 1) <= mask;
}
EXPORT_SYMBOL(swiotlb_dma_supported);
+
+#ifdef CONFIG_DMA_DIRECT_OPS
+void *swiotlb_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+ gfp_t gfp, unsigned long attrs)
+{
+ void *vaddr;
+
+ /*
+ * Don't print a warning when the first allocation attempt fails.
+ * swiotlb_alloc_coherent() will print a warning when the DMA memory
+ * allocation ultimately failed.
+ */
+ gfp |= __GFP_NOWARN;
+
+ vaddr = dma_direct_alloc(dev, size, dma_handle, gfp, attrs);
+ if (!vaddr)
+ vaddr = swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
+ return vaddr;
+}
+
+void swiotlb_free(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_addr, unsigned long attrs)
+{
+ if (is_swiotlb_buffer(dma_to_phys(dev, dma_addr)))
+ swiotlb_free_coherent(dev, size, vaddr, dma_addr);
+ else
+ dma_direct_free(dev, size, vaddr, dma_addr, attrs);
+}
+
+const struct dma_map_ops swiotlb_dma_ops = {
+ .mapping_error = swiotlb_dma_mapping_error,
+ .alloc = swiotlb_alloc,
+ .free = swiotlb_free,
+ .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
+ .sync_single_for_device = swiotlb_sync_single_for_device,
+ .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+ .sync_sg_for_device = swiotlb_sync_sg_for_device,
+ .map_sg = swiotlb_map_sg_attrs,
+ .unmap_sg = swiotlb_unmap_sg_attrs,
+ .map_page = swiotlb_map_page,
+ .unmap_page = swiotlb_unmap_page,
+};
+#endif /* CONFIG_DMA_DIRECT_OPS */
--
2.14.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox