* [PATCH v3] dma-buf: system_heap: Set allocation orders for larger page sizes
@ 2025-04-17 20:19 Juan Yescas
2026-09-22 12:10 ` Pankaj Patil
0 siblings, 1 reply; 3+ messages in thread
From: Juan Yescas @ 2025-04-17 20:19 UTC (permalink / raw)
To: Sumit Semwal, Benjamin Gaignard, Brian Starkey, John Stultz,
T.J. Mercier, Christian König, linux-media, dri-devel,
linaro-mm-sig, linux-kernel
Cc: jyescas, baohua, dmitry.osipenko, jaewon31.kim, surenb, kaleshsingh
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 <jyescas@google.com>
Acked-by: John Stultz <jstultz@google.com>
Reviewed-by: T.J. Mercier <tjmercier@google.com>
---
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;
--
2.49.0.805.g082f7c87e0-goog
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v3] dma-buf: system_heap: Set allocation orders for larger page sizes
2025-04-17 20:19 [PATCH v3] dma-buf: system_heap: Set allocation orders for larger page sizes Juan Yescas
@ 2026-09-22 12:10 ` Pankaj Patil
2026-09-25 15:29 ` Juan Yescas
0 siblings, 1 reply; 3+ messages in thread
From: Pankaj Patil @ 2026-09-22 12:10 UTC (permalink / raw)
To: Juan Yescas, Sumit Semwal, Benjamin Gaignard, Brian Starkey,
John Stultz, T.J. Mercier, Christian König, linux-media,
dri-devel, linaro-mm-sig, linux-kernel
Cc: baohua, dmitry.osipenko, jaewon31.kim, surenb, kaleshsingh
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 <jyescas@google.com>
> Acked-by: John Stultz <jstultz@google.com>
> Reviewed-by: T.J. Mercier <tjmercier@google.com>
> ---
>
> 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/20260921-dma_buf_improvement-v1-1-23d82e771dec@oss.qualcomm.com/
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v3] dma-buf: system_heap: Set allocation orders for larger page sizes
2026-09-22 12:10 ` Pankaj Patil
@ 2026-09-25 15:29 ` Juan Yescas
0 siblings, 0 replies; 3+ messages in thread
From: Juan Yescas @ 2026-09-25 15:29 UTC (permalink / raw)
To: Pankaj Patil
Cc: Sumit Semwal, Benjamin Gaignard, Brian Starkey, John Stultz,
T.J. Mercier, Christian König, linux-media, dri-devel,
linaro-mm-sig, linux-kernel, baohua, dmitry.osipenko,
jaewon31.kim, surenb, kaleshsingh
On Tue, Sep 22, 2026 at 5:11 AM Pankaj Patil
<pankaj.patil@oss.qualcomm.com> wrote:
>
> 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 <jyescas@google.com>
> > Acked-by: John Stultz <jstultz@google.com>
> > Reviewed-by: T.J. Mercier <tjmercier@google.com>
> > ---
> >
> > 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/20260921-dma_buf_improvement-v1-1-23d82e771dec@oss.qualcomm.com/
>
Hi Pankaj,
There is another change that fixes the problem and adds the 2MiB
order. It has already been
reviewed the Christian König:
https://lore.kernel.org/all/20260914212258.2657788-3-dave@stgolabs.net/
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-25 15:30 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-17 20:19 [PATCH v3] dma-buf: system_heap: Set allocation orders for larger page sizes Juan Yescas
2026-09-22 12:10 ` Pankaj Patil
2026-09-25 15:29 ` Juan Yescas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®