diff mbox series

[2/6] drm/buddy: fix range bias

Message ID 20240215174431.285069-8-matthew.auld@intel.com (mailing list archive)
State New, archived
Headers show
Series [1/6] drm/tests/drm_buddy: fix 32b build | expand

Commit Message

Matthew Auld Feb. 15, 2024, 5:44 p.m. UTC
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: afea229fe102 ("drm: improve drm_buddy_alloc function")
Signed-off-by: Matthew 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+
---
 drivers/gpu/drm/drm_buddy.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

Comments

Paneer Selvam, Arunpravin Feb. 16, 2024, 11:40 a.m. UTC | #1
Looks good.

Reviewed-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>



On 2/15/2024 11:14 PM, Matthew Auld wrote:
> 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: afea229fe102 ("drm: improve drm_buddy_alloc function")
> Signed-off-by: Matthew 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+
> ---
>   drivers/gpu/drm/drm_buddy.c | 10 ++++++++++
>   1 file changed, 10 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c
> index c1a99bf4dffd..d09540d4065b 100644
> --- a/drivers/gpu/drm/drm_buddy.c
> +++ b/drivers/gpu/drm/drm_buddy.c
> @@ -332,6 +332,7 @@ alloc_range_bias(struct drm_buddy *mm,
>   		 u64 start, u64 end,
>   		 unsigned int order)
>   {
> +	u64 req_size = mm->chunk_size << order;
>   	struct drm_buddy_block *block;
>   	struct drm_buddy_block *buddy;
>   	LIST_HEAD(dfs);
> @@ -367,6 +368,15 @@ alloc_range_bias(struct drm_buddy *mm,
>   		if (drm_buddy_block_is_allocated(block))
>   			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) &&
>   		    order == drm_buddy_block_order(block)) {
>   			/*
diff mbox series

Patch

diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c
index c1a99bf4dffd..d09540d4065b 100644
--- a/drivers/gpu/drm/drm_buddy.c
+++ b/drivers/gpu/drm/drm_buddy.c
@@ -332,6 +332,7 @@  alloc_range_bias(struct drm_buddy *mm,
 		 u64 start, u64 end,
 		 unsigned int order)
 {
+	u64 req_size = mm->chunk_size << order;
 	struct drm_buddy_block *block;
 	struct drm_buddy_block *buddy;
 	LIST_HEAD(dfs);
@@ -367,6 +368,15 @@  alloc_range_bias(struct drm_buddy *mm,
 		if (drm_buddy_block_is_allocated(block))
 			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) &&
 		    order == drm_buddy_block_order(block)) {
 			/*