Skip to content

Commit c4b17af

Browse files
Ganapatrao Kulkarnijoergroedel
authored andcommitted
iommu/dma: Use NUMA aware memory allocations in __iommu_dma_alloc_pages()
Change function __iommu_dma_alloc_pages() to allocate pages for DMA from respective device NUMA node. The ternary operator which would be for alloc_pages_node() is tidied along with this. The motivation for this change is to have a policy for page allocation consistent with direct DMA mapping, which attempts to allocate pages local to the device, as mentioned in [1]. In addition, for certain workloads it has been observed a marginal performance improvement. The patch caused an observation of 0.9% average throughput improvement for running tcrypt with HiSilicon crypto engine. We also include a modification to use kvzalloc() for kzalloc()/vzalloc() combination. [1] https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1692998.html Signed-off-by: Ganapatrao Kulkarni <ganapatrao.kulkarni@cavium.com> [JPG: Added kvzalloc(), drop pages ** being device local, remove ternary operator, update message] Signed-off-by: John Garry <john.garry@huawei.com> Reviewed-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent 51eb780 commit c4b17af

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

drivers/iommu/dma-iommu.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -449,20 +449,17 @@ static void __iommu_dma_free_pages(struct page **pages, int count)
449449
kvfree(pages);
450450
}
451451

452-
static struct page **__iommu_dma_alloc_pages(unsigned int count,
453-
unsigned long order_mask, gfp_t gfp)
452+
static struct page **__iommu_dma_alloc_pages(struct device *dev,
453+
unsigned int count, unsigned long order_mask, gfp_t gfp)
454454
{
455455
struct page **pages;
456-
unsigned int i = 0, array_size = count * sizeof(*pages);
456+
unsigned int i = 0, nid = dev_to_node(dev);
457457

458458
order_mask &= (2U << MAX_ORDER) - 1;
459459
if (!order_mask)
460460
return NULL;
461461

462-
if (array_size <= PAGE_SIZE)
463-
pages = kzalloc(array_size, GFP_KERNEL);
464-
else
465-
pages = vzalloc(array_size);
462+
pages = kvzalloc(count * sizeof(*pages), GFP_KERNEL);
466463
if (!pages)
467464
return NULL;
468465

@@ -481,10 +478,12 @@ static struct page **__iommu_dma_alloc_pages(unsigned int count,
481478
for (order_mask &= (2U << __fls(count)) - 1;
482479
order_mask; order_mask &= ~order_size) {
483480
unsigned int order = __fls(order_mask);
481+
gfp_t alloc_flags = gfp;
484482

485483
order_size = 1U << order;
486-
page = alloc_pages((order_mask - order_size) ?
487-
gfp | __GFP_NORETRY : gfp, order);
484+
if (order_mask > order_size)
485+
alloc_flags |= __GFP_NORETRY;
486+
page = alloc_pages_node(nid, alloc_flags, order);
488487
if (!page)
489488
continue;
490489
if (!order)
@@ -569,7 +568,8 @@ struct page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
569568
alloc_sizes = min_size;
570569

571570
count = PAGE_ALIGN(size) >> PAGE_SHIFT;
572-
pages = __iommu_dma_alloc_pages(count, alloc_sizes >> PAGE_SHIFT, gfp);
571+
pages = __iommu_dma_alloc_pages(dev, count, alloc_sizes >> PAGE_SHIFT,
572+
gfp);
573573
if (!pages)
574574
return NULL;
575575

0 commit comments

Comments
 (0)