Commit 59cc84c8 authored by Frederic Barrat's avatar Frederic Barrat Committed by Michael Ellerman
Browse files

Revert "powerpc/kernel/iommu: Align size for IOMMU_PAGE_SIZE() to save TCEs"



This reverts commit 3c0468d4.

That commit was breaking alignment guarantees for the DMA address when
allocating coherent mappings, as described in
Documentation/core-api/dma-api-howto.rst

It was also noticed by Mellanox' driver:
[ 1515.763621] mlx5_core c002:01:00.0: mlx5_frag_buf_alloc_node:146:(pid 13402): unexpected map alignment: 0x0800000000c61000, page_shift=16
[ 1515.763635] mlx5_core c002:01:00.0: mlx5_cqwq_create:181:(pid
13402): mlx5_frag_buf_alloc_node() failed, -12

Fixes: 3c0468d4 ("powerpc/kernel/iommu: Align size for  IOMMU_PAGE_SIZE() to save TCEs")
Signed-off-by: default avatarFrederic Barrat <fbarrat@linux.ibm.com>
Reviewed-by: default avatarAlexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210526144540.117795-1-fbarrat@linux.ibm.com
parent 1438709e
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -898,7 +898,6 @@ void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
	unsigned int order;
	unsigned int nio_pages, io_order;
	struct page *page;
	size_t size_io = size;

	size = PAGE_ALIGN(size);
	order = get_order(size);
@@ -925,9 +924,8 @@ void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
	memset(ret, 0, size);

	/* Set up tces to cover the allocated range */
	size_io = IOMMU_PAGE_ALIGN(size_io, tbl);
	nio_pages = size_io >> tbl->it_page_shift;
	io_order = get_iommu_order(size_io, tbl);
	nio_pages = size >> tbl->it_page_shift;
	io_order = get_iommu_order(size, tbl);
	mapping = iommu_alloc(dev, tbl, ret, nio_pages, DMA_BIDIRECTIONAL,
			      mask >> tbl->it_page_shift, io_order, 0);
	if (mapping == DMA_MAPPING_ERROR) {
@@ -942,9 +940,10 @@ void iommu_free_coherent(struct iommu_table *tbl, size_t size,
			 void *vaddr, dma_addr_t dma_handle)
{
	if (tbl) {
		size_t size_io = IOMMU_PAGE_ALIGN(size, tbl);
		unsigned int nio_pages = size_io >> tbl->it_page_shift;
		unsigned int nio_pages;

		size = PAGE_ALIGN(size);
		nio_pages = size >> tbl->it_page_shift;
		iommu_free(tbl, dma_handle, nio_pages);
		size = PAGE_ALIGN(size);
		free_pages((unsigned long)vaddr, get_order(size));