FAILED: patch "[PATCH] gpu/buddy: bail out of try_harder when alignment cannot be" failed to apply to 6.12-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 56bc6384314fb9ae98975fb2af8b143097ede3dc
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026072017-endless-bagging-0d2e@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 56bc6384314fb9ae98975fb2af8b143097ede3dc Mon Sep 17 00:00:00 2001
From: Arunpravin Paneer Selvam <[email protected]>
Date: Thu, 9 Jul 2026 18:40:50 +0530
Subject: [PATCH] gpu/buddy: bail out of try_harder when alignment cannot be
honoured
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The try_harder contiguous fallback could return a range whose start offset did not match the caller's min_block_size. When a candidate's start is misaligned, realign it: free the misaligned run and reallocate exactly @size at the next lower min_block_size boundary. This keeps the returned size unchanged with no surplus to trim, and rejects the request only when no aligned candidate fits.
v2: align misaligned candidates down to min_block_size instead of
bailing out, for both the RHS and LHS paths (Matthew).
drivers/gpu/buddy.c +46 -21
@@ -1084,22 +1084,30 @@ static int __gpu_buddy_alloc_range(struct gpu_buddy *mm, blocks, total_allocated_on_err); } +static int __alloc_contig_aligned_retry (struct gpu_buddy *mm, +u64 unaligned_offset, +u64 size, +u64 min_block_size, +struct list_head *blocks) +{ +u64 aligned_offset =round_down (unaligned_offset, min_block_size); + +return __gpu_buddy_alloc_range (mm, aligned_offset, size,NULL , blocks); +} +static int __alloc_contig_try_harder (struct gpu_buddy *mm,u64 size,u64 min_block_size,struct list_head *blocks) { -u64 rhs_offset, lhs_offset, lhs_size, filled; +u64 rhs_offset, lhs_offset, filled;struct gpu_buddy_block *block;unsigned int tree, order; -LIST_HEAD (blocks_lhs); -unsigned long pages;u64 modify_size;int err; modify_size =rounddown_pow_of_two (size); - pages = modify_size >>ilog2 (mm->chunk_size); - order =fls (pages) -1 ; + order =ilog2 (modify_size) -ilog2 (mm->chunk_size);if (order ==0 )return -ENOSPC ;
@@ -1115,31 +1123,48 @@ static int __alloc_contig_try_harder(struct gpu_buddy *mm,while (iter) { block =rbtree_get_free_block (iter); -/* Allocate blocks traversing RHS */ rhs_offset =gpu_buddy_block_offset (block); + +/* Allocate blocks traversing RHS */ err =__gpu_buddy_alloc_range (mm, rhs_offset, size, &filled, blocks); -if (!err || err != -ENOSPC ) +if (err && err != -ENOSPC )return err; - - lhs_size =max ((size - filled), min_block_size); -if (!IS_ALIGNED (lhs_size, min_block_size)) - lhs_size =round_up (lhs_size, min_block_size); - -/* Allocate blocks traversing LHS */ - lhs_offset =gpu_buddy_block_offset (block) - lhs_size; - err =__gpu_buddy_alloc_range (mm, lhs_offset, lhs_size, -NULL , &blocks_lhs); -if (!err) { -list_splice (&blocks_lhs, blocks); +if (!err &&IS_ALIGNED (rhs_offset, min_block_size))return 0 ; - }else if (err != -ENOSPC ) { +if (!err) { +/* Allocate the unaligned RHS offset using round_down */ +gpu_buddy_free_list_internal (mm, blocks); + err =__alloc_contig_aligned_retry (mm, rhs_offset, + size, + min_block_size, + blocks); +if (!err) +return 0 ; +if (err != -ENOSPC ) { +gpu_buddy_free_list_internal (mm, blocks); +return err; + } + goto next; + } + +if (size - filled > rhs_offset) + goto next; + + lhs_offset = rhs_offset - (size - filled); + +/* Allocate the unaligned LHS offset using round_down */ +gpu_buddy_free_list_internal (mm, blocks); + err =__alloc_contig_aligned_retry (mm, lhs_offset, size, + min_block_size, blocks); +if (!err) +return 0 ; +if (err != -ENOSPC ) {gpu_buddy_free_list_internal (mm, blocks);return err; } -/* Free blocks for the next iteration */ +next:gpu_buddy_free_list_internal (mm, blocks); - iter =rb_prev (iter); } }
Sasha Levin
maintainerPATCH 1/2 gpu: Move DRM buddy allocator one level up (part two)
From: Joel Fernandes <[email protected]>
[ Upstream commit ba110db8e1bc206c13fd7d985e79b033f53bfdea ]
Move the DRM buddy allocator one level up so that it can be used by GPU drivers (example, nova-core) that have usecases other than DRM (such as VFIO vGPU support). Modify the API, structures and Kconfigs to use "gpu_buddy" terminology. Adapt the drivers and tests to use the new API.
The commit cannot be split due to bisectability, however no functional change is intended. Verified by running K-UNIT tests and build tested various configurations.
[airlied: I've split this into two so git can find copies easier. I've also just nuked drm_random library, that stuff needs to be done elsewhere and only the buddy tests seem to be using it].
Stable-dep-of: 56bc6384314f ("gpu/buddy: bail out of try_harder when alignment cannot be honoured")
---
Documentation/gpu/drm-mm.rst | 10 +-
drivers/gpu/Kconfig | 13 +
drivers/gpu/Makefile | 3 +-
drivers/gpu/buddy.c | 1322 +++++++++++++++++
drivers/gpu/drm/Kconfig | 6 +-
drivers/gpu/drm/Makefile | 1 -
.../gpu/drm/amd/amdgpu/amdgpu_res_cursor.h | 12 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 77 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h | 18 +-
drivers/gpu/drm/drm_buddy.c | 1279 +---------------
drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +-
drivers/gpu/drm/i915/i915_scatterlist.c | 10 +-
drivers/gpu/drm/i915/i915_ttm_buddy_manager.c | 55 +-
drivers/gpu/drm/i915/i915_ttm_buddy_manager.h | 4 +-
.../drm/i915/selftests/intel_memory_region.c | 20 +-
drivers/gpu/drm/tests/Makefile | 1 -
drivers/gpu/drm/tests/drm_exec_test.c | 2 -
drivers/gpu/drm/tests/drm_mm_test.c | 2 -
.../gpu/drm/ttm/tests/ttm_bo_validate_test.c | 4 +-
drivers/gpu/drm/ttm/tests/ttm_mock_manager.c | 18 +-
drivers/gpu/drm/ttm/tests/ttm_mock_manager.h | 4 +-
drivers/gpu/drm/xe/xe_res_cursor.h | 34 +-
drivers/gpu/drm/xe/xe_ttm_vram_mgr.c | 73 +-
drivers/gpu/drm/xe/xe_ttm_vram_mgr_types.h | 4 +-
drivers/gpu/tests/Makefile | 4 +
.../gpu_buddy_test.c} | 316 ++--
.../lib/drm_random.c => tests/gpu_random.c} | 18 +-
.../lib/drm_random.h => tests/gpu_random.h} | 18 +-
drivers/video/Kconfig | 1 +
include/drm/drm_buddy.h | 174 +--
include/linux/gpu_buddy.h | 188 +++
31 files changed, 1903 insertions(+), 1790 deletions(-)
create mode 100644 drivers/gpu/Kconfig
create mode 100644 drivers/gpu/buddy.c
create mode 100644 drivers/gpu/tests/Makefile
rename drivers/gpu/{drm/tests/drm_buddy_test.c => tests/gpu_buddy_test.c} (70%)
rename drivers/gpu/{drm/lib/drm_random.c => tests/gpu_random.c} (58%)
rename drivers/gpu/{drm/lib/drm_random.h => tests/gpu_random.h} (53%)
create mode 100644 include/linux/gpu_buddy.hDocumentation/gpu/drm-mm.rst +8 -2
@@ -509,8 +509,14 @@ DRM GPUVM Function References DRM Buddy Allocator =================== -DRM Buddy Function References ------------------------------ +Buddy Allocator Function References (GPU buddy) +----------------------------------------------- + +.. kernel-doc:: drivers/gpu/buddy.c + :export: + +DRM Buddy Specific Logging Function References +---------------------------------------------- .. kernel-doc:: drivers/gpu/drm/drm_buddy.c :export:
drivers/gpu/Kconfig new file +13 -0
@@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 + +config GPU_BUDDY + bool + help + A page based buddy allocator for GPU memory. + +config GPU_BUDDY_KUNIT_TEST + tristate "KUnit tests for GPU buddy allocator" if !KUNIT_ALL_TESTS + depends on GPU_BUDDY && KUNIT + default KUNIT_ALL_TESTS + help + KUnit tests for the GPU buddy allocator.
drivers/gpu/Makefile +2 -1
@@ -2,6 +2,7 @@ # drm/tegra depends on host1x, so if both drivers are built-in care must be # taken to initialize them in the correct order. Link order is the only way # to ensure this currently. -obj-y += host1x/ drm/ vga/ +obj-y += host1x/ drm/ vga/ tests/ obj-$(CONFIG_IMX_IPUV3_CORE) += ipu-v3/ obj-$(CONFIG_TRACE_GPU_MEM) += trace/ +obj-$(CONFIG_GPU_BUDDY) += buddy.o
drivers/gpu/buddy.c new file +1322 -0
1,322 lines not on this page · raw message
drivers/gpu/drm/Kconfig +1 -5
@@ -85,7 +85,6 @@ config DRM_KUNIT_TEST select DRM_EXPORT_FOR_TESTS if m select DRM_GEM_SHMEM_HELPER select DRM_KUNIT_TEST_HELPERS - select DRM_LIB_RANDOM select PRIME_NUMBERS default KUNIT_ALL_TESTS help
@@ -325,6 +324,7 @@ config DRM_GPUVM config DRM_BUDDY tristate depends on DRM + select GPU_BUDDY help A page based buddy allocator
@@ -507,10 +507,6 @@ config DRM_EXPORT_FOR_TESTS config DRM_PANEL_BACKLIGHT_QUIRKS tristate -config DRM_LIB_RANDOM - bool - default n - config DRM_PRIVACY_SCREEN bool default n
drivers/gpu/drm/Makefile +0 -1
@@ -75,7 +75,6 @@ drm-y := \ drm_vblank_work.o \ drm_vma_manager.o \ drm_writeback.o -drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o drm-$(CONFIG_COMPAT) += drm_ioc32.o drm-$(CONFIG_DRM_PANEL) += drm_panel.o drm-$(CONFIG_OF) += drm_of.o
drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h +6 -6
@@ -55,7 +55,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res, uint64_t start, uint64_t size, struct amdgpu_res_cursor *cur) { - struct drm_buddy_block *block; + struct gpu_buddy_block *block;struct list_head *head, *next;struct drm_mm_node *node;
@@ -71,7 +71,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res, head = &to_amdgpu_vram_mgr_resource (res)->blocks; block =list_first_entry_or_null (head, - struct drm_buddy_block, + struct gpu_buddy_block, link);if (!block) goto fallback;
@@ -81,7 +81,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res, next = block->link.next;if (next != head) - block = list_entry(next, struct drm_buddy_block, link); + block = list_entry(next, struct gpu_buddy_block, link); } cur->start =amdgpu_vram_mgr_block_start (block) + start;
@@ -124,7 +124,7 @@ static inline void amdgpu_res_first(struct ttm_resource *res,*/ static inline void amdgpu_res_next (struct amdgpu_res_cursor *cur,uint64_t size) { -struct drm_buddy_block *block; +struct gpu_buddy_block *block;struct drm_mm_node *node;struct list_head *next;
@@ -145,7 +145,7 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size) block = cur->node; next = block->link.next; - block = list_entry(next, struct drm_buddy_block, link); + block = list_entry(next, struct gpu_buddy_block, link); cur->node = block; cur->start =amdgpu_vram_mgr_block_start (block);
@@ -173,7 +173,7 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size)*/ static inline bool amdgpu_res_cleared (struct amdgpu_res_cursor *cur) { -struct drm_buddy_block *block; +struct gpu_buddy_block *block;switch (cur->mem_type) {case TTM_PL_VRAM :
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +39 -38
251 lines not on this page · raw message
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h +9 -9
@@ -24,11 +24,11 @@ #ifndef __AMDGPU_VRAM_MGR_H__ #define __AMDGPU_VRAM_MGR_H__ -#include <drm/drm_buddy.h> +#include <linux/gpu_buddy.h> struct amdgpu_vram_mgr { struct ttm_resource_manager manager; - struct drm_buddy mm; + struct gpu_buddy mm; /* protects access to buffer objects */ struct mutex lock; struct list_head reservations_pending;
@@ -43,19 +43,19 @@ struct amdgpu_vram_mgr_resource {unsigned long flags; }; -static inline u64 amdgpu_vram_mgr_block_start (struct drm_buddy_block *block) +static inline u64 amdgpu_vram_mgr_block_start (struct gpu_buddy_block *block) { -return drm_buddy_block_offset (block); +return gpu_buddy_block_offset (block); } -static inline u64 amdgpu_vram_mgr_block_size (struct drm_buddy_block *block) +static inline u64 amdgpu_vram_mgr_block_size (struct gpu_buddy_block *block) { -return (u64 )PAGE_SIZE <<drm_buddy_block_order (block); +return (u64 )PAGE_SIZE <<gpu_buddy_block_order (block); } -static inline bool amdgpu_vram_mgr_is_cleared (struct drm_buddy_block *block) +static inline bool amdgpu_vram_mgr_is_cleared (struct gpu_buddy_block *block) { -return drm_buddy_block_is_clear (block); +return gpu_buddy_block_is_clear (block); } static inline struct amdgpu_vram_mgr_resource *
@@ -66,7 +66,7 @@ to_amdgpu_vram_mgr_resource(struct ttm_resource *res)static inline void amdgpu_vram_mgr_set_cleared (struct ttm_resource *res) { -to_amdgpu_vram_mgr_resource (res)->flags |=DRM_BUDDY_CLEARED ; +to_amdgpu_vram_mgr_resource (res)->flags |=GPU_BUDDY_CLEARED ; }#endif
drivers/gpu/drm/drm_buddy.c +13 -1266
1,265 lines not on this page · raw message
drivers/gpu/drm/i915/gem/i915_gem_ttm.c +1 -1
Lines of this file are not shown. View the raw message.
drivers/gpu/drm/i915/i915_scatterlist.c +5 -5
Lines of this file are not shown. View the raw message.
drivers/gpu/drm/i915/i915_ttm_buddy_manager.c +28 -27
55 lines not on this page · raw message
drivers/gpu/drm/i915/i915_ttm_buddy_manager.h +2 -2
Lines of this file are not shown. View the raw message.
drivers/gpu/drm/i915/selftests/intel_memory_region.c +10 -10
Lines of this file are not shown. View the raw message.
drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c +2 -2
Lines of this file are not shown. View the raw message.
drivers/gpu/drm/ttm/tests/ttm_mock_manager.c +9 -9
Lines of this file are not shown. View the raw message.
drivers/gpu/drm/ttm/tests/ttm_mock_manager.h +2 -2
Lines of this file are not shown. View the raw message.
drivers/gpu/drm/xe/xe_ttm_vram_mgr.c +37 -36
73 lines not on this page · raw message
drivers/gpu/drm/xe/xe_ttm_vram_mgr_types.h +2 -2
Lines of this file are not shown. View the raw message.
drivers/gpu/tests/gpu_buddy_test.c renamed from drivers/gpu/drm/tests/drm_buddy_test.c +158 -158
316 lines not on this page · raw message
drivers/gpu/tests/gpu_random.c renamed from drivers/gpu/drm/lib/drm_random.c +9 -9
Lines of this file are not shown. View the raw message.
drivers/gpu/tests/gpu_random.h renamed from drivers/gpu/drm/lib/drm_random.h +9 -9
Lines of this file are not shown. View the raw message.
include/drm/drm_buddy.h +6 -168
174 lines not on this page · raw message
include/linux/gpu_buddy.h new file +188 -0
188 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.53.0
Part of the diff is not shown here. View the raw message.
Sasha Levin
maintainerPATCH 2/2 gpu/buddy: bail out of try_harder when alignment cannot be honoured
From: Arunpravin Paneer Selvam <[email protected]>
[ Upstream commit 56bc6384314fb9ae98975fb2af8b143097ede3dc ]
The try_harder contiguous fallback could return a range whose start offset did not match the caller's min_block_size. When a candidate's start is misaligned, realign it: free the misaligned run and reallocate exactly @size at the next lower min_block_size boundary. This keeps the returned size unchanged with no surplus to trim, and rejects the request only when no aligned candidate fits.
v2: align misaligned candidates down to min_block_size instead of
bailing out, for both the RHS and LHS paths (Matthew).
--- drivers/gpu/buddy.c | 63 +++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 19 deletions(-)
drivers/gpu/buddy.c +44 -19
@@ -901,22 +901,30 @@ static int __gpu_buddy_alloc_range(struct gpu_buddy *mm, blocks, total_allocated_on_err); } +static int __alloc_contig_aligned_retry (struct gpu_buddy *mm, +u64 unaligned_offset, +u64 size, +u64 min_block_size, +struct list_head *blocks) +{ +u64 aligned_offset =round_down (unaligned_offset, min_block_size); + +return __gpu_buddy_alloc_range (mm, aligned_offset, size,NULL , blocks); +} +static int __alloc_contig_try_harder (struct gpu_buddy *mm,u64 size,u64 min_block_size,struct list_head *blocks) { -u64 rhs_offset, lhs_offset, lhs_size, filled; +u64 rhs_offset, lhs_offset, filled;struct gpu_buddy_block *block;unsigned int tree, order; -LIST_HEAD (blocks_lhs); -unsigned long pages;u64 modify_size;int err; modify_size =rounddown_pow_of_two (size); - pages = modify_size >>ilog2 (mm->chunk_size); - order =fls (pages) -1 ; + order =ilog2 (modify_size) -ilog2 (mm->chunk_size);if (order ==0 )return -ENOSPC ;
@@ -932,31 +940,48 @@ static int __alloc_contig_try_harder(struct gpu_buddy *mm,while (iter) { block =rbtree_get_free_block (iter); -/* Allocate blocks traversing RHS */ rhs_offset =gpu_buddy_block_offset (block); + +/* Allocate blocks traversing RHS */ err =__gpu_buddy_alloc_range (mm, rhs_offset, size, &filled, blocks); -if (!err || err != -ENOSPC ) +if (err && err != -ENOSPC )return err; +if (!err &&IS_ALIGNED (rhs_offset, min_block_size)) +return 0 ; +if (!err) { +/* Allocate the unaligned RHS offset using round_down */ +gpu_buddy_free_list_internal (mm, blocks); + err =__alloc_contig_aligned_retry (mm, rhs_offset, + size, + min_block_size, + blocks); +if (!err) +return 0 ; +if (err != -ENOSPC ) { +gpu_buddy_free_list_internal (mm, blocks); +return err; + } + goto next; + } - lhs_size =max ((size - filled), min_block_size); -if (!IS_ALIGNED (lhs_size, min_block_size)) - lhs_size =round_up (lhs_size, min_block_size); +if (size - filled > rhs_offset) + goto next; -/* Allocate blocks traversing LHS */ - lhs_offset =gpu_buddy_block_offset (block) - lhs_size; - err =__gpu_buddy_alloc_range (mm, lhs_offset, lhs_size, -NULL , &blocks_lhs); -if (!err) { -list_splice (&blocks_lhs, blocks); + lhs_offset = rhs_offset - (size - filled); + +/* Allocate the unaligned LHS offset using round_down */ +gpu_buddy_free_list_internal (mm, blocks); + err =__alloc_contig_aligned_retry (mm, lhs_offset, size, + min_block_size, blocks); +if (!err)return 0 ; - }else if (err != -ENOSPC ) { +if (err != -ENOSPC ) {gpu_buddy_free_list_internal (mm, blocks);return err; } -/* Free blocks for the next iteration */ +next:gpu_buddy_free_list_internal (mm, blocks); - iter =rb_prev (iter); } }
Signature · 1 line
2.53.0