Commit f41900e4 authored by Matthew Auld's avatar Matthew Auld Committed by Christian König

drm/buddy: fix range bias

There is a corner case here where start/end is after/before the block
range we are currently checking. If so we need to be sure that splitting
the block will eventually give use the block size we need. To do that we
should adjust the block range to account for the start/end, and only
continue with the split if the size/alignment will fit the requested
size. Not doing so can result in leaving split blocks unmerged when it
eventually fails.

Fixes: afea229f ("drm: improve drm_buddy_alloc function")
Signed-off-by: default avatarMatthew Auld <matthew.auld@intel.com>
Cc: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: <stable@vger.kernel.org> # v5.18+
Reviewed-by: default avatarArunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240219121851.25774-4-matthew.auld@intel.comSigned-off-by: default avatarChristian König <christian.koenig@amd.com>
parent 00d6a284
...@@ -332,6 +332,7 @@ alloc_range_bias(struct drm_buddy *mm, ...@@ -332,6 +332,7 @@ alloc_range_bias(struct drm_buddy *mm,
u64 start, u64 end, u64 start, u64 end,
unsigned int order) unsigned int order)
{ {
u64 req_size = mm->chunk_size << order;
struct drm_buddy_block *block; struct drm_buddy_block *block;
struct drm_buddy_block *buddy; struct drm_buddy_block *buddy;
LIST_HEAD(dfs); LIST_HEAD(dfs);
...@@ -367,6 +368,15 @@ alloc_range_bias(struct drm_buddy *mm, ...@@ -367,6 +368,15 @@ alloc_range_bias(struct drm_buddy *mm,
if (drm_buddy_block_is_allocated(block)) if (drm_buddy_block_is_allocated(block))
continue; continue;
if (block_start < start || block_end > end) {
u64 adjusted_start = max(block_start, start);
u64 adjusted_end = min(block_end, end);
if (round_down(adjusted_end + 1, req_size) <=
round_up(adjusted_start, req_size))
continue;
}
if (contains(start, end, block_start, block_end) && if (contains(start, end, block_start, block_end) &&
order == drm_buddy_block_order(block)) { order == drm_buddy_block_order(block)) {
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment