Skip to content

Commit

Permalink
Merge tag 'dma-mapping-6.6-2023-08-29' of git://git.infradead.org/use…
Browse files Browse the repository at this point in the history
…rs/hch/dma-mapping

Pull dma-maping updates from Christoph Hellwig:

 - allow dynamic sizing of the swiotlb buffer, to cater for secure
   virtualization workloads that require all I/O to be bounce buffered
   (Petr Tesarik)

 - move a declaration to a header (Arnd Bergmann)

 - check for memory region overlap in dma-contiguous (Binglei Wang)

 - remove the somewhat dangerous runtime swiotlb-xen enablement and
   unexport is_swiotlb_active (Christoph Hellwig, Juergen Gross)

 - per-node CMA improvements (Yajun Deng)

* tag 'dma-mapping-6.6-2023-08-29' of git://git.infradead.org/users/hch/dma-mapping:
  swiotlb: optimize get_max_slots()
  swiotlb: move slot allocation explanation comment where it belongs
  swiotlb: search the software IO TLB only if the device makes use of it
  swiotlb: allocate a new memory pool when existing pools are full
  swiotlb: determine potential physical address limit
  swiotlb: if swiotlb is full, fall back to a transient memory pool
  swiotlb: add a flag whether SWIOTLB is allowed to grow
  swiotlb: separate memory pool data from other allocator data
  swiotlb: add documentation and rename swiotlb_do_find_slots()
  swiotlb: make io_tlb_default_mem local to swiotlb.c
  swiotlb: bail out of swiotlb_init_late() if swiotlb is already allocated
  dma-contiguous: check for memory region overlap
  dma-contiguous: support numa CMA for specified node
  dma-contiguous: support per-numa CMA for all architectures
  dma-mapping: move arch_dma_set_mask() declaration to header
  swiotlb: unexport is_swiotlb_active
  x86: always initialize xen-swiotlb when xen-pcifront is enabling
  xen/pci: add flag for PCI passthrough being possible
  • Loading branch information
torvalds committed Aug 30, 2023
2 parents 3d3dfeb + d069ed2 commit 6c1b980
Show file tree
Hide file tree
Showing 23 changed files with 910 additions and 187 deletions.
13 changes: 12 additions & 1 deletion Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@
kernel/dma/contiguous.c

cma_pernuma=nn[MG]
[ARM64,KNL,CMA]
[KNL,CMA]
Sets the size of kernel per-numa memory area for
contiguous memory allocations. A value of 0 disables
per-numa CMA altogether. And If this option is not
Expand All @@ -706,6 +706,17 @@
which is located in node nid, if the allocation fails,
they will fallback to the global default memory area.

numa_cma=<node>:nn[MG][,<node>:nn[MG]]
[KNL,CMA]
Sets the size of kernel numa memory area for
contiguous memory allocations. It will reserve CMA
area for the specified node.

With numa CMA enabled, DMA users on node nid will
first try to allocate buffer from the numa area
which is located in node nid, if the allocation fails,
they will fallback to the global default memory area.

cmo_free_hint= [PPC] Format: { yes | no }
Specify whether pages are marked as being inactive
when they are freed. This is used in CMO environments
Expand Down
10 changes: 4 additions & 6 deletions arch/arm/xen/mm.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,10 @@ static int __init xen_mm_init(void)
return 0;

/* we can work with the default swiotlb */
if (!io_tlb_default_mem.nslabs) {
rc = swiotlb_init_late(swiotlb_size_or_default(),
xen_swiotlb_gfp(), NULL);
if (rc < 0)
return rc;
}
rc = swiotlb_init_late(swiotlb_size_or_default(),
xen_swiotlb_gfp(), NULL);
if (rc < 0)
return rc;

cflush.op = 0;
cflush.a.dev_bus_addr = 0;
Expand Down
2 changes: 0 additions & 2 deletions arch/arm64/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,6 @@ void __init bootmem_init(void)
arm64_hugetlb_cma_reserve();
#endif

dma_pernuma_cma_reserve();

kvm_hyp_reserve();

/*
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/pci/pci-octeon.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ static int __init octeon_pci_setup(void)

/* BAR1 movable regions contiguous to cover the swiotlb */
octeon_bar1_pci_phys =
io_tlb_default_mem.start & ~((1ull << 22) - 1);
default_swiotlb_base() & ~((1ull << 22) - 1);

for (index = 0; index < 32; index++) {
union cvmx_pci_bar1_indexx bar1_index;
Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/kernel/dma-mask.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0

#include <linux/dma-mapping.h>
#include <linux/dma-map-ops.h>
#include <linux/export.h>
#include <asm/machdep.h>

Expand Down
6 changes: 0 additions & 6 deletions arch/x86/include/asm/xen/swiotlb-xen.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@
#ifndef _ASM_X86_SWIOTLB_XEN_H
#define _ASM_X86_SWIOTLB_XEN_H

#ifdef CONFIG_SWIOTLB_XEN
extern int pci_xen_swiotlb_init_late(void);
#else
static inline int pci_xen_swiotlb_init_late(void) { return -ENXIO; }
#endif

int xen_swiotlb_fixup(void *buf, unsigned long nslabs);
int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
unsigned int address_bits,
Expand Down
29 changes: 7 additions & 22 deletions arch/x86/kernel/pci-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,15 @@ static inline void __init pci_swiotlb_detect(void)
#endif /* CONFIG_SWIOTLB */

#ifdef CONFIG_SWIOTLB_XEN
static bool xen_swiotlb_enabled(void)
{
return xen_initial_domain() || x86_swiotlb_enable ||
(IS_ENABLED(CONFIG_XEN_PCIDEV_FRONTEND) && xen_pv_pci_possible);
}

static void __init pci_xen_swiotlb_init(void)
{
if (!xen_initial_domain() && !x86_swiotlb_enable)
if (!xen_swiotlb_enabled())
return;
x86_swiotlb_enable = true;
x86_swiotlb_flags |= SWIOTLB_ANY;
Expand All @@ -83,27 +89,6 @@ static void __init pci_xen_swiotlb_init(void)
if (IS_ENABLED(CONFIG_PCI))
pci_request_acs();
}

int pci_xen_swiotlb_init_late(void)
{
if (dma_ops == &xen_swiotlb_dma_ops)
return 0;

/* we can work with the default swiotlb */
if (!io_tlb_default_mem.nslabs) {
int rc = swiotlb_init_late(swiotlb_size_or_default(),
GFP_KERNEL, xen_swiotlb_fixup);
if (rc < 0)
return rc;
}

/* XXX: this switches the dma ops under live devices! */
dma_ops = &xen_swiotlb_dma_ops;
if (IS_ENABLED(CONFIG_PCI))
pci_request_acs();
return 0;
}
EXPORT_SYMBOL_GPL(pci_xen_swiotlb_init_late);
#else
static inline void __init pci_xen_swiotlb_init(void)
{
Expand Down
6 changes: 6 additions & 0 deletions arch/x86/xen/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
/* Number of pages released from the initial allocation. */
unsigned long xen_released_pages;

/* Memory map would allow PCI passthrough. */
bool xen_pv_pci_possible;

/* E820 map used during setting up memory. */
static struct e820_table xen_e820_table __initdata;

Expand Down Expand Up @@ -814,6 +817,9 @@ char * __init xen_memory_setup(void)
chunk_size = size;
type = xen_e820_table.entries[i].type;

if (type == E820_TYPE_RESERVED)
xen_pv_pci_possible = true;

if (type == E820_TYPE_RAM) {
if (addr < mem_end) {
chunk_size = min(size, mem_end - addr);
Expand Down
4 changes: 1 addition & 3 deletions drivers/base/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3108,9 +3108,7 @@ void device_initialize(struct device *dev)
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
dev->dma_coherent = dma_default_coherent;
#endif
#ifdef CONFIG_SWIOTLB
dev->dma_io_tlb_mem = &io_tlb_default_mem;
#endif
swiotlb_dev_init(dev);
}
EXPORT_SYMBOL_GPL(device_initialize);

Expand Down
6 changes: 0 additions & 6 deletions drivers/pci/xen-pcifront.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include <linux/bitops.h>
#include <linux/time.h>
#include <linux/ktime.h>
#include <linux/swiotlb.h>
#include <xen/platform_pci.h>

#include <asm/xen/swiotlb-xen.h>
Expand Down Expand Up @@ -669,11 +668,6 @@ static int pcifront_connect_and_init_dma(struct pcifront_device *pdev)

spin_unlock(&pcifront_dev_lock);

if (!err && !is_swiotlb_active(&pdev->xdev->dev)) {
err = pci_xen_swiotlb_init_late();
if (err)
dev_err(&pdev->xdev->dev, "Could not setup SWIOTLB!\n");
}
return err;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/xen/swiotlb-xen.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ xen_swiotlb_sync_sg_for_device(struct device *dev, struct scatterlist *sgl,
static int
xen_swiotlb_dma_supported(struct device *hwdev, u64 mask)
{
return xen_phys_to_dma(hwdev, io_tlb_default_mem.end - 1) <= mask;
return xen_phys_to_dma(hwdev, default_swiotlb_limit()) <= mask;
}

const struct dma_map_ops xen_swiotlb_dma_ops = {
Expand Down
10 changes: 9 additions & 1 deletion include/linux/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,10 @@ struct device_physical_location {
* @dma_pools: Dma pools (if dma'ble device).
* @dma_mem: Internal for coherent mem override.
* @cma_area: Contiguous memory area for dma allocations
* @dma_io_tlb_mem: Pointer to the swiotlb pool used. Not for driver use.
* @dma_io_tlb_mem: Software IO TLB allocator. Not for driver use.
* @dma_io_tlb_pools: List of transient swiotlb memory pools.
* @dma_io_tlb_lock: Protects changes to the list of active pools.
* @dma_uses_io_tlb: %true if device has used the software IO TLB.
* @archdata: For arch-specific additions.
* @of_node: Associated device tree node.
* @fwnode: Associated device node supplied by platform firmware.
Expand Down Expand Up @@ -731,6 +734,11 @@ struct device {
#endif
#ifdef CONFIG_SWIOTLB
struct io_tlb_mem *dma_io_tlb_mem;
#endif
#ifdef CONFIG_SWIOTLB_DYNAMIC
struct list_head dma_io_tlb_pools;
spinlock_t dma_io_tlb_lock;
bool dma_uses_io_tlb;
#endif
/* arch specific additions */
struct dev_archdata archdata;
Expand Down
12 changes: 6 additions & 6 deletions include/linux/dma-map-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,6 @@ static inline void dma_free_contiguous(struct device *dev, struct page *page,
}
#endif /* CONFIG_DMA_CMA*/

#ifdef CONFIG_DMA_PERNUMA_CMA
void dma_pernuma_cma_reserve(void);
#else
static inline void dma_pernuma_cma_reserve(void) { }
#endif /* CONFIG_DMA_PERNUMA_CMA */

#ifdef CONFIG_DMA_DECLARE_COHERENT
int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,
dma_addr_t device_addr, size_t size);
Expand Down Expand Up @@ -343,6 +337,12 @@ void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t dma_addr, unsigned long attrs);

#ifdef CONFIG_ARCH_HAS_DMA_SET_MASK
void arch_dma_set_mask(struct device *dev, u64 mask);
#else
#define arch_dma_set_mask(dev, mask) do { } while (0)
#endif

#ifdef CONFIG_MMU
/*
* Page protection so that devices that can't snoop CPU caches can use the
Expand Down
2 changes: 2 additions & 0 deletions include/linux/dma-mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,8 @@ static inline void dma_sync_sgtable_for_device(struct device *dev,
#define dma_get_sgtable(d, t, v, h, s) dma_get_sgtable_attrs(d, t, v, h, s, 0)
#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, 0)

bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size);

static inline void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp)
{
Expand Down
Loading

0 comments on commit 6c1b980

Please sign in to comment.