On 4/18/2025 1:49 AM, Juan Yescas wrote: > This change sets the allocation orders for the different page sizes > (4k, 16k, 64k) based on PAGE_SHIFT. Before this change, the orders > for large page sizes were calculated incorrectly, this caused system > heap to allocate from 2% to 4% more memory on 16KiB page size kernels. > > This change was tested on 4k/16k page size kernels. > > Signed-off-by: Juan Yescas <[email protected]> > Acked-by: John Stultz <[email protected]> > Reviewed-by: T.J. Mercier <[email protected]> > --- > > Changes in v2: > - Add John's Acked-by tag. > - Add TJ's Reviewed-by tag > - Use dma-buf: system_heap: in the subject since this is specific to the > system heap, as per TJ. > - Remove extra space in if statement. > > Changes in v3: > - Remove defines for the orders as per Christian. > - Update the order array for 64k page sizes as per TJ > > drivers/dma-buf/heaps/system_heap.c | 21 ++++++++++++++++++--- > 1 file changed, 18 insertions(+), 3 deletions(-) > > diff --git a/drivers/dma-buf/heaps/system_heap.c > b/drivers/dma-buf/heaps/system_heap.c > index 26d5dc89ea16..8c10c0f2b473 100644 > --- a/drivers/dma-buf/heaps/system_heap.c > +++ b/drivers/dma-buf/heaps/system_heap.c > @@ -18,6 +18,7 @@ > #include <linux/mm.h> > #include <linux/module.h> > #include <linux/scatterlist.h> > +#include <linux/sizes.h> > #include <linux/slab.h> > #include <linux/vmalloc.h> > > @@ -44,14 +45,28 @@ struct dma_heap_attachment { > #define HIGH_ORDER_GFP (((GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN \ > | __GFP_NORETRY) & ~__GFP_RECLAIM) \ > | __GFP_COMP) > -static gfp_t order_flags[] = {HIGH_ORDER_GFP, HIGH_ORDER_GFP, LOW_ORDER_GFP}; > /* > * The selection of the orders used for allocation (1MB, 64K, 4K) is designed > * to match with the sizes often found in IOMMUs. Using order 4 pages instead > * of order 0 pages can significantly improve the performance of many IOMMUs > * by reducing TLB pressure and time spent updating page tables. > + * > + * Note: When the order is 0, the minimum allocation is PAGE_SIZE. The > possible > + * page sizes for ARM devices could be 4K, 16K and 64K. > + */ > +#if (PAGE_SIZE == SZ_64K) > +static gfp_t order_flags[] = {HIGH_ORDER_GFP, LOW_ORDER_GFP}; > +/* 1MiB allocs are calculated with (2 ^ (20 - PAGE_SHIFT)) * PAGE_SIZE = > 1MiB */ > +static const unsigned int orders[] = {20 - PAGE_SHIFT, 0}; > +#else > +static gfp_t order_flags[] = {HIGH_ORDER_GFP, HIGH_ORDER_GFP, LOW_ORDER_GFP}; > +/* > + * 1MiB allocs are calculated with (2 ^ (20 - PAGE_SHIFT)) * PAGE_SIZE = 1MiB > + * 64KiB allocs are calculated with (2 ^ (16 - PAGE_SHIFT)) * PAGE_SIZE = > 64KiB > */ > -static const unsigned int orders[] = {8, 4, 0}; > +static const unsigned int orders[] = {20 - PAGE_SHIFT, 16 - PAGE_SHIFT, 0}; > +#endif > + > #define NUM_ORDERS ARRAY_SIZE(orders) > > static struct sg_table *dup_sg_table(struct sg_table *table) > @@ -318,7 +333,7 @@ static struct page *alloc_largest_available(unsigned long > size, > int i; > > for (i = 0; i < NUM_ORDERS; i++) { > - if (size < (PAGE_SIZE << orders[i])) > + if (size < (PAGE_SIZE << orders[i])) > continue; > if (max_order < orders[i]) > continue;
Hello Juan, I've posted a respin of the patch by extending upon your work, Can you please review? Aplogies for adding signed-off by, will drop it in v2. Link - https://lore.kernel.org/all/[email protected]/
