Intel-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Arunpravin Paneer Selvam" <arunpravin.paneerselvam@amd.com>,
	dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org,
	intel-xe@lists.freedesktop.org
Subject: Re: [PATCH v5 1/2] gpu/buddy: restore two-pass clear/dirty guard for range-biased allocation
Date: Tue, 20 Oct 2026 08:00:49 +0000	[thread overview]
Message-ID: <sashiko-outbox-178464@kernel.org> (raw)
In-Reply-To: <20261020055537.1640552-1-arunpravin.paneerselvam@amd.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] gpu/buddy: block_incompatible() mishandles split and mixed blocks in __alloc_range_bias()
--

commit 6dff7f0e6dce9c68ecb98f2d911199843d2b4401
Author: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>

gpu/buddy: restore two-pass clear/dirty guard for range-biased allocation

This commit introduces a two-pass search in __gpu_buddy_alloc_range_bias()
using block_incompatible() in the strict pass to prevent range-restricted
allocations from splitting opposite-class (clear vs. dirty) blocks unless
no matching blocks exist in the range.

> diff --git a/drivers/gpu/buddy.c b/drivers/gpu/buddy.c
> index 503f7d5934e4b..91935c71c5255 100644
> --- a/drivers/gpu/buddy.c
> +++ b/drivers/gpu/buddy.c
> @@ -1240,11 +1240,19 @@ static void __gpu_buddy_undo_splits(struct gpu_buddy *mm,
>  	}
>  }
>  
> +static bool block_incompatible(struct gpu_buddy_block *block, unsigned int flags)
> +{
> +	bool needs_clear = flags & GPU_BUDDY_CLEAR_ALLOCATION;
> +
> +	return needs_clear != gpu_buddy_block_is_clear(block);
> +}
> +
>  static struct gpu_buddy_block *
>  __alloc_range_bias(struct gpu_buddy *mm,
>  		   u64 start, u64 end,
>  		   unsigned int order,
> -		   unsigned long flags)
> +		   unsigned long flags,
> +		   bool fallback)
>  {

[ ... ]

> @@ -1298,6 +1304,9 @@ __alloc_range_bias(struct gpu_buddy *mm,
>  				continue;
>  		}
>  
> +		if (!fallback && block_incompatible(block, flags))
> +			continue;
> +
>  		if (contains(start, end, block_start, block_end) &&
>  		    order == gpu_buddy_block_order(block)) {
>  			/*
> @@ -1315,38 +1324,8 @@ __alloc_range_bias(struct gpu_buddy *mm,
>  				goto err_undo;
>  		}
>  
> -		/*
> -		 * Top-down is a strict address-placement policy, so when it is
> -		 * requested we ignore clear steering and simply descend the
> -		 * right (higher-address) child first. Only a non-top-down clear
> -		 * request biases the descent towards clear/has_clear subtrees.
> -		 */
> -		if ((flags & GPU_BUDDY_CLEAR_ALLOCATION) &&
> -		    !(flags & GPU_BUDDY_TOPDOWN_ALLOCATION)) {
> -			struct gpu_buddy_block *prefer;
> -
> -			if (gpu_buddy_block_is_clear(block->right))
> -				prefer = block->right;
> -			else if (gpu_buddy_block_is_clear(block->left))
> -				prefer = block->left;
> -			else if (block->right->has_clear)
> -				prefer = block->right;
> -			else if (block->left->has_clear)
> -				prefer = block->left;
> -			else
> -				prefer = block->right;
> -
> -			if (prefer == block->right) {
> -				list_add(&block->left->tmp_link, &dfs);
> -				list_add(&block->right->tmp_link, &dfs);
> -			} else {
> -				list_add(&block->right->tmp_link, &dfs);
> -				list_add(&block->left->tmp_link, &dfs);
> -			}
> -		} else {
> -			list_add(&block->left->tmp_link, &dfs);
> -			list_add(&block->right->tmp_link, &dfs);
> -		}
> +		list_add(&block->left->tmp_link, &dfs);
> +		list_add(&block->right->tmp_link, &dfs);
>  	} while (1);

[Severity: High]
Does calling block_incompatible() on every visited node in
__alloc_range_bias() before checking whether the block is split or mixed
mishandle internal GPU_BUDDY_SPLIT nodes and coalesced GPU_BLOCK_MIXED free
blocks?

First, when mark_split() transitions a block to GPU_BUDDY_SPLIT, it leaves
the previous GPU_BUDDY_HEADER_CLEAR bit intact on the internal node:

drivers/gpu/buddy.c:mark_split() {
	block->header &= ~GPU_BUDDY_HEADER_STATE;
	block->header |= GPU_BUDDY_SPLIT;
	...
}

Because gpu_buddy_init() initializes roots as dirty, any root or ancestor
split while dirty keeps gpu_buddy_block_is_clear(block) == false while any
descendant remains allocated. Conversely, a clear block that is split and
later has a descendant freed as dirty keeps gpu_buddy_block_is_clear(block)
== true on the split ancestor.

When __gpu_buddy_alloc_range_bias() runs the first pass (fallback = false),
__alloc_range_bias() evaluates block_incompatible(block, flags) on those
GPU_BUDDY_SPLIT ancestors and skips the entire subtree without descending
into its children. If no other root satisfies the request, the first pass
returns -ENOSPC and __gpu_buddy_alloc_range_bias() falls back to the second
pass (fallback = true), where block_incompatible() is disabled and the
clear/has_clear child-ordering preference has been removed, causing the
search to split the highest-address extent regardless of class.

Second, __gpu_buddy_free() coalesces adjacent clear and dirty free buddies
into a single GPU_BUDDY_FREE block with state GPU_BLOCK_MIXED, which has
gpu_buddy_block_is_clear(block) == false and block->has_clear == true:

1. For clear range allocations (flags & GPU_BUDDY_CLEAR_ALLOCATION), Pass 1
   sees gpu_buddy_block_is_clear(block) == false on a GPU_BLOCK_MIXED block
   and skips it via block_incompatible() without splitting it to reach the
   clear sub-blocks inside. Pass 2 then splits the mixed block without clear
   child-steering and unconditionally visits block->right first, returning a
   dirty block whenever the clear half is in block->left.

2. For dirty range allocations (!(flags & GPU_BUDDY_CLEAR_ALLOCATION)),
   block_incompatible() returns false on a higher-order GPU_BLOCK_MIXED
   block because gpu_buddy_block_is_clear(block) is false. Pass 1 then calls
   split_block(mm, block), which reclassifies block->left and block->right
   via mark_free(). If the child overlapping [start, end) is clear while the
   dirty child lies outside [start, end), Pass 1 rejects the clear child via
   block_incompatible() and skips the other child without calling
   __gpu_buddy_undo_splits().

Wouldn't leaving that split GPU_BLOCK_MIXED block unmerged keep both
children in GPU_BUDDY_FREE state, preventing ancestor coalescing on teardown
and triggering gpu_buddy_assert(gpu_buddy_block_is_free(mm->roots[i])) while
leaking the split child gpu_buddy_block structures in gpu_buddy_fini()?

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261020055537.1640552-1-arunpravin.paneerselvam@amd.com?part=1

  parent reply	other threads:[~2026-10-20  8:01 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-20  5:55 [PATCH v5 1/2] gpu/buddy: restore two-pass clear/dirty guard for range-biased allocation Arunpravin Paneer Selvam
2026-10-20  5:55 ` [PATCH v5 2/2] gpu/buddy: add range-restricted contiguous allocation fallback Arunpravin Paneer Selvam
2026-10-20  8:08   ` sashiko-bot
2026-10-20  6:35 ` ✓ i915.CI.BAT: success for series starting with [v5,1/2] gpu/buddy: restore two-pass clear/dirty guard for range-biased allocation Patchwork
2026-10-20  8:00 ` sashiko-bot [this message]
2026-10-20  9:52   ` [PATCH v5 1/2] " Matthew Auld
2026-10-20 10:39     ` Matthew Auld
2026-10-20 12:09 ` ✗ i915.CI.Full: failure for series starting with [v5,1/2] " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-178464@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=arunpravin.paneerselvam@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox