From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from va-2-28.ptr.blmpb.com (va-2-28.ptr.blmpb.com [209.127.231.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0B2B23EDE5E for ; Wed, 15 Jul 2026 09:27:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.127.231.28 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784107643; cv=none; b=MnuNJNOKQSzgZRDd4Ih1z07wG31o9XbsBjC9K4v87ryQpjF+Nh/a3GXyw79LPgmSf4BCZNxnoOd/h7V7/EezZZJEDorzfb7mUi3H8GG2r6Rvs2wuBS3FBu1pzA3Kf4SW4r12CUAzSxfWMaHJkwZ/mrUesiuEHnanB3Lr5VcOZGI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784107643; c=relaxed/simple; bh=ZFRzg/lSmDdQRvO04NiVIHaAkXtlk3/sktuDLU3zrCo=; h=To:Cc:From:Date:References:Content-Type:In-Reply-To:Subject: Message-Id:Mime-Version:Content-Disposition; b=Gy7A1A472Bd0UNqu7AOH6KAosdOgEuvFicBlyPL5EGIhrINFYCoRiwcb8gSR1Aisix/FH1YEOeH5sheERiUUOxSh85C6ANLHHI388CfxaImMDBdquOkevQ/wTRd7eZOUfzD39Nog/85Jat3ARVYwvPH/GWEtoYQ6VwBMNW6DLlU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=picoheart.com; spf=pass smtp.mailfrom=picoheart.com; dkim=pass (2048-bit key) header.d=picoheart.com header.i=@picoheart.com header.b=Bvnu3jqN; arc=none smtp.client-ip=209.127.231.28 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=picoheart.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=picoheart.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=picoheart.com header.i=@picoheart.com header.b="Bvnu3jqN" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=feishu2604151535; d=picoheart.com; t=1784107629; h=from:subject: mime-version:from:date:message-id:subject:to:cc:reply-to:content-type: mime-version:in-reply-to:message-id; bh=Ktj0wj7Y7uKnHqBv88iQF2zzd3kExNVGvafF+8u1e+Y=; b=Bvnu3jqNS6G4EyprBYIFzgMiAuLmZKpmeh56DZ02IHrIu8rbuouYShxGr0dsMW4x68ArVf QsfFGlu+pjHzTdEUwU8BsCV43Id4SEAiu61I2MrGAtsxfbbLMsWrk9Jumjbcmowhvm7Xe+ sbQIC/gxddNwBwOfYpBhPq+G2dkm6Q6rTWmApNehnVfjNqveto1xU+2ibQgpEGWBEUQelv 0B7Ysl5mTyv6tvicjGauqrnhbsQUPX8fLbE9uLoQtUFs+o8wCGmjjD/994+xKiG+TFeajv HtfSwqIBBek37WemwO+LoOl0d3wROBUOxpgW7LoQx0BQvdENgZtZOImaiF/eRg== To: , , , , , Cc: , X-Original-From: Zhaoyu Liu From: "Zhaoyu Liu" Date: Wed, 15 Jul 2026 17:27:03 +0800 References: Received: from hostpc ([124.160.26.250]) by smtp.feishu.cn with ESMTPS; Wed, 15 Jul 2026 17:27:06 +0800 Content-Type: text/plain; charset=UTF-8 In-Reply-To: Subject: Re: [PATCH v2] gpu: buddy: avoid repeated builds of root dfs when alloc range Message-Id: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 Content-Disposition: inline X-Lms-Return-Path: Content-Transfer-Encoding: 7bit On Mon, Jul 13, 2026 at 09:17:15PM +0800, Zhaoyu Liu wrote: Hi, Could you please help review and merge this patch? And I'll submit additional new patches for follow-up work later. Thanks, zackary > The buddy allocator previously pre-built a DFS list by inserting all > root blocks via list_add_tail() before every allocation call in > __alloc_range_bias() and __gpu_buddy_alloc_range(). This is wasteful > when the allocation can be satisfied by the first root or by sub-blocks > produced from splits, as the remaining roots are never consumed. > > Introduce __get_candidate_block() which unifies the block acquisition > logic for both __alloc_range_bias() and __alloc_range(): it first > checks the DFS list (populated by splits during allocation or > pre-filled by the caller for trim), and only when the list is exhausted > does it lazily fetch the next root block through a cursor. > > When the caller pre-fills the DFS list (trim scenario), the cursor is > initialized to mm->n_roots to disable root iteration entirely, > preserving the original behavior. > > Signed-off-by: Zhaoyu Liu > Suggested-by: Arun Pravin > --- > > v2: > - Change __get_candidate_block to inline > - Link to v1: https://lore.kernel.org/all/ak+ECwsuSljmvyKd@hostpc/ > > --- > drivers/gpu/buddy.c | 61 ++++++++++++++++++++++++++++++--------------- > 1 file changed, 41 insertions(+), 20 deletions(-) > > diff --git a/drivers/gpu/buddy.c b/drivers/gpu/buddy.c > index dc81fe0301ce..63b3959973fa 100644 > --- a/drivers/gpu/buddy.c > +++ b/drivers/gpu/buddy.c > @@ -700,6 +700,41 @@ static void __gpu_buddy_undo_splits(struct gpu_buddy *mm, > } > } > > +/** > + * __get_candidate_block - Get a candidate block for allocation. > + * @mm: GPU buddy manager > + * @dfs: List of candidate blocks. Populated in two ways: (1) pre-filled by > + * the caller before allocation with blocks available for allocation, > + * and (2) extended during allocation by block splits, which add the > + * resulting sub-blocks for subsequent finer-grained allocation. > + * @cursor: Pointer to current root index, advanced when iterating roots. > + * Pass in a value >= mm->n_roots to disable root iteration entirely, > + * restricting block acquisition to @dfs only; this is used in the > + * trim scenario where only pre-split sub-blocks should be considered. > + * > + * Return: Pointer to the acquired block on success, ERR_PTR(-ENOSPC) when no > + * more blocks are available. > + */ > +static inline struct gpu_buddy_block* > +__get_candidate_block(struct gpu_buddy *mm, struct list_head *dfs, > + uint32_t *cursor) > +{ > + struct gpu_buddy_block *block; > + > + block = list_first_entry_or_null(dfs, > + struct gpu_buddy_block, > + tmp_link); > + if (block) { > + list_del(&block->tmp_link); > + return block; > + } > + > + if (*cursor >= mm->n_roots) > + return ERR_PTR(-ENOSPC); > + > + return mm->roots[(*cursor)++]; > +} > + > static struct gpu_buddy_block * > __alloc_range_bias(struct gpu_buddy *mm, > u64 start, u64 end, > @@ -711,25 +746,18 @@ __alloc_range_bias(struct gpu_buddy *mm, > struct gpu_buddy_block *block; > LIST_HEAD(dfs); > int err; > - int i; > + uint32_t cursor = 0; > > end = end - 1; > > - for (i = 0; i < mm->n_roots; ++i) > - list_add_tail(&mm->roots[i]->tmp_link, &dfs); > - > do { > u64 block_start; > u64 block_end; > > - block = list_first_entry_or_null(&dfs, > - struct gpu_buddy_block, > - tmp_link); > - if (!block) > + block = __get_candidate_block(mm, &dfs, &cursor); > + if (IS_ERR(block)) > break; > > - list_del(&block->tmp_link); > - > if (gpu_buddy_block_order(block) < order) > continue; > > @@ -1023,6 +1051,7 @@ static int __alloc_range(struct gpu_buddy *mm, > LIST_HEAD(allocated); > u64 end; > int err; > + uint32_t cursor = list_empty(dfs) ? 0 : mm->n_roots; > > end = start + size - 1; > > @@ -1030,14 +1059,10 @@ static int __alloc_range(struct gpu_buddy *mm, > u64 block_start; > u64 block_end; > > - block = list_first_entry_or_null(dfs, > - struct gpu_buddy_block, > - tmp_link); > - if (!block) > + block = __get_candidate_block(mm, dfs, &cursor); > + if (IS_ERR(block)) > break; > > - list_del(&block->tmp_link); > - > block_start = gpu_buddy_block_offset(block); > block_end = block_start + gpu_buddy_block_size(mm, block) - 1; > > @@ -1109,10 +1134,6 @@ static int __gpu_buddy_alloc_range(struct gpu_buddy *mm, > struct list_head *blocks) > { > LIST_HEAD(dfs); > - int i; > - > - for (i = 0; i < mm->n_roots; ++i) > - list_add_tail(&mm->roots[i]->tmp_link, &dfs); > > return __alloc_range(mm, &dfs, start, size, > blocks, total_allocated_on_err); > -- > 2.34.1