aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2018-05-22 07:50:09 -0400
committerJoerg Roedel <jroedel@suse.de>2018-05-29 10:57:58 -0400
commit4b123757eeaab1d522605b4469ee1adc18a80c90 (patch)
tree0307f0cad26e227a1881598a6e633bfeefd84cc4
parentf793b13ef0c9c11971334eb1c2544f81865b0d74 (diff)
iommu/io-pgtable-arm: Make allocations NUMA-aware
We would generally expect pagetables to be read by the IOMMU more than written by the CPU, so in NUMA systems it makes sense to locate them close to the former and avoid cross-node pagetable walks if at all possible. As it turns out, we already have a handle on the IOMMU device for the sake of coherency management, so it's trivial to grab the appropriate NUMA node when allocating new pagetable pages. Note that we drop the semantics of alloc_pages_exact(), but that's fine since they have never been necessary: the only time we're allocating more than one page is for stage 2 top-level concatenation, but since that is based on the number of IPA bits, the size is always some exact power of two anyway. Acked-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r--drivers/iommu/io-pgtable-arm.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 4ffdd88b1566..010a254305dd 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -231,12 +231,17 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
231 struct io_pgtable_cfg *cfg) 231 struct io_pgtable_cfg *cfg)
232{ 232{
233 struct device *dev = cfg->iommu_dev; 233 struct device *dev = cfg->iommu_dev;
234 int order = get_order(size);
235 struct page *p;
234 dma_addr_t dma; 236 dma_addr_t dma;
235 void *pages = alloc_pages_exact(size, gfp | __GFP_ZERO); 237 void *pages;
236 238
237 if (!pages) 239 VM_BUG_ON((gfp & __GFP_HIGHMEM));
240 p = alloc_pages_node(dev_to_node(dev), gfp | __GFP_ZERO, order);
241 if (!p)
238 return NULL; 242 return NULL;
239 243
244 pages = page_address(p);
240 if (!(cfg->quirks & IO_PGTABLE_QUIRK_NO_DMA)) { 245 if (!(cfg->quirks & IO_PGTABLE_QUIRK_NO_DMA)) {
241 dma = dma_map_single(dev, pages, size, DMA_TO_DEVICE); 246 dma = dma_map_single(dev, pages, size, DMA_TO_DEVICE);
242 if (dma_mapping_error(dev, dma)) 247 if (dma_mapping_error(dev, dma))
@@ -256,7 +261,7 @@ out_unmap:
256 dev_err(dev, "Cannot accommodate DMA translation for IOMMU page tables\n"); 261 dev_err(dev, "Cannot accommodate DMA translation for IOMMU page tables\n");
257 dma_unmap_single(dev, dma, size, DMA_TO_DEVICE); 262 dma_unmap_single(dev, dma, size, DMA_TO_DEVICE);
258out_free: 263out_free:
259 free_pages_exact(pages, size); 264 __free_pages(p, order);
260 return NULL; 265 return NULL;
261} 266}
262 267
@@ -266,7 +271,7 @@ static void __arm_lpae_free_pages(void *pages, size_t size,
266 if (!(cfg->quirks & IO_PGTABLE_QUIRK_NO_DMA)) 271 if (!(cfg->quirks & IO_PGTABLE_QUIRK_NO_DMA))
267 dma_unmap_single(cfg->iommu_dev, __arm_lpae_dma_addr(pages), 272 dma_unmap_single(cfg->iommu_dev, __arm_lpae_dma_addr(pages),
268 size, DMA_TO_DEVICE); 273 size, DMA_TO_DEVICE);
269 free_pages_exact(pages, size); 274 free_pages((unsigned long)pages, get_order(size));
270} 275}
271 276
272static void __arm_lpae_sync_pte(arm_lpae_iopte *ptep, 277static void __arm_lpae_sync_pte(arm_lpae_iopte *ptep,