Skip to content

Commit cde76ac

Browse files
Lin.Caojfvogel
authored andcommitted
drm/buddy: fix issue that force_merge cannot free all roots
[ Upstream commit 467dce3 ] If buddy manager have more than one roots and each root have sub-block need to be free. When drm_buddy_fini called, the first loop of force_merge will merge and free all of the sub block of first root, which offset is 0x0 and size is biggest(more than have of the mm size). In subsequent force_merge rounds, if we use 0 as start and use remaining mm size as end, the block of other roots will be skipped in __force_merge function. It will cause the other roots can not be freed. Solution: use roots' offset as the start could fix this issue. Signed-off-by: Lin.Cao <lincao12@amd.com> Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241226070116.309290-1-Arunpravin.PaneerSelvam@amd.com Signed-off-by: Sasha Levin <sashal@kernel.org> (cherry picked from commit aa52c70ae1322430da509e5ee98f817f2dcae2ed) Signed-off-by: Jack Vogel <jack.vogel@oracle.com>
1 parent 84e2468 commit cde76ac

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

drivers/gpu/drm/drm_buddy.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,15 +324,16 @@ EXPORT_SYMBOL(drm_buddy_init);
324324
*/
325325
void drm_buddy_fini(struct drm_buddy *mm)
326326
{
327-
u64 root_size, size;
327+
u64 root_size, size, start;
328328
unsigned int order;
329329
int i;
330330

331331
size = mm->size;
332332

333333
for (i = 0; i < mm->n_roots; ++i) {
334334
order = ilog2(size) - ilog2(mm->chunk_size);
335-
__force_merge(mm, 0, size, order);
335+
start = drm_buddy_block_offset(mm->roots[i]);
336+
__force_merge(mm, start, start + size, order);
336337

337338
WARN_ON(!drm_buddy_block_is_free(mm->roots[i]));
338339
drm_block_free(mm, mm->roots[i]);

0 commit comments

Comments
 (0)