All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Auld <matthew.auld@intel.com>
To: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>,
	dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org
Cc: christian.koenig@amd.com, alexander.deucher@amd.com,
	mario.limonciello@amd.com, felix.kuehling@amd.com
Subject: Re: [PATCH v9 3/3] drm/tests: Add a test case for drm buddy clear allocation
Date: Tue, 26 Mar 2024 17:46:58 +0000	[thread overview]
Message-ID: <7936855e-f4f4-4b60-a2ff-146782607b16@intel.com> (raw)
In-Reply-To: <20240318214058.2014-3-Arunpravin.PaneerSelvam@amd.com>

On 18/03/2024 21:40, Arunpravin Paneer Selvam wrote:
> Add a new test case for the drm buddy clear and dirty
> allocation.
> 
> Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
> Suggested-by: Matthew Auld <matthew.auld@intel.com>
> ---
>   drivers/gpu/drm/tests/drm_buddy_test.c | 127 +++++++++++++++++++++++++
>   1 file changed, 127 insertions(+)
> 
> diff --git a/drivers/gpu/drm/tests/drm_buddy_test.c b/drivers/gpu/drm/tests/drm_buddy_test.c
> index 454ad9952f56..d355a6e61893 100644
> --- a/drivers/gpu/drm/tests/drm_buddy_test.c
> +++ b/drivers/gpu/drm/tests/drm_buddy_test.c
> @@ -19,6 +19,132 @@ static inline u64 get_size(int order, u64 chunk_size)
>   	return (1 << order) * chunk_size;
>   }
>   
> +static void drm_test_buddy_alloc_clear(struct kunit *test)
> +{
> +	unsigned long n_pages, total, i = 0;
> +	const unsigned long ps = SZ_4K;
> +	struct drm_buddy_block *block;
> +	const int max_order = 12;
> +	LIST_HEAD(allocated);
> +	struct drm_buddy mm;
> +	unsigned int order;
> +	u64 mm_size, size;

Maybe just make these two u32 or unsigned long. That should be big 
enough, plus avoids any kind of 32b compilation bugs below.

> +	LIST_HEAD(dirty);
> +	LIST_HEAD(clean);
> +
> +	mm_size = PAGE_SIZE << max_order;

s/PAGE_SIZE/SZ_4K/ below also.

> +	KUNIT_EXPECT_FALSE(test, drm_buddy_init(&mm, mm_size, ps));
> +
> +	KUNIT_EXPECT_EQ(test, mm.max_order, max_order);
> +
> +	/**

Drop the extra *, since is not actual kernel-doc. Below also.

> +	 * Idea is to allocate and free some random portion of the address space,
> +	 * returning those pages as non-dirty and randomly alternate between
> +	 * requesting dirty and non-dirty pages (not going over the limit
> +	 * we freed as non-dirty), putting that into two separate lists.
> +	 * Loop over both lists at the end checking that the dirty list
> +	 * is indeed all dirty pages and vice versa. Free it all again,
> +	 * keeping the dirty/clear status.
> +	 */
> +	KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
> +							    5 * ps, ps, &allocated,
> +							    DRM_BUDDY_TOPDOWN_ALLOCATION),
> +				"buddy_alloc hit an error size=%u\n", 5 * ps);
> +	drm_buddy_free_list(&mm, &allocated, DRM_BUDDY_CLEARED);
> +
> +	n_pages = 10;
> +	do {
> +		unsigned long flags;
> +		struct list_head *list;
> +		int slot = i % 2;
> +
> +		if (slot == 0) {
> +			list = &dirty;
> +			flags = 0;
> +		} else if (slot == 1) {

Could just be else {

> +			list = &clean;
> +			flags = DRM_BUDDY_CLEAR_ALLOCATION;
> +		}
> +
> +		KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
> +								    ps, ps, list,
> +								    flags),
> +					"buddy_alloc hit an error size=%u\n", ps);
> +	} while (++i < n_pages);
> +
> +	list_for_each_entry(block, &clean, link)
> +		KUNIT_EXPECT_EQ(test, drm_buddy_block_is_clear(block), true);
> +
> +	list_for_each_entry(block, &dirty, link)
> +		KUNIT_EXPECT_EQ(test, drm_buddy_block_is_clear(block), false);
> +
> +	drm_buddy_free_list(&mm, &clean, DRM_BUDDY_CLEARED);
> +
> +	/**
> +	 * Trying to go over the clear limit for some allocation.
> +	 * The allocation should never fail with reasonable page-size.
> +	 */
> +	KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
> +							    10 * ps, ps, &clean,
> +							    DRM_BUDDY_CLEAR_ALLOCATION),
> +				"buddy_alloc hit an error size=%u\n", 10 * ps);
> +
> +	drm_buddy_free_list(&mm, &clean, DRM_BUDDY_CLEARED);
> +	drm_buddy_free_list(&mm, &dirty, 0);
> +	drm_buddy_fini(&mm);
> +
> +	KUNIT_EXPECT_FALSE(test, drm_buddy_init(&mm, mm_size, ps));
> +
> +	/**
> +	 * Create a new mm. Intentionally fragment the address space by creating
> +	 * two alternating lists. Free both lists, one as dirty the other as clean.
> +	 * Try to allocate double the previous size with matching min_page_size. The
> +	 * allocation should never fail as it calls the force_merge. Also check that
> +	 * the page is always dirty after force_merge. Free the page as dirty, then
> +	 * repeat the whole thing, increment the order until we hit the max_order.
> +	 */
> +
> +	order = 1;
> +	do {
> +		size = PAGE_SIZE << order;
> +		i = 0;
> +		n_pages = mm_size / ps;
> +		do {
> +			struct list_head *list;
> +			int slot = i % 2;
> +
> +			if (slot == 0)
> +				list = &dirty;
> +			else if (slot == 1)

else

> +				list = &clean;
> +
> +			KUNIT_ASSERT_FALSE_MSG(test,
> +					       drm_buddy_alloc_blocks(&mm, 0, mm_size,
> +								      ps, ps, list, 0),
> +					       "buddy_alloc hit an error size=%u\n",
> +					       ps);
> +		} while (++i < n_pages);

I think we only need to do this once at the beginning, and then just 
loop over each order starting from one? Otherwise on the first iteration 
here we fragment the entire address space, but then only allocate single 
order=1. And then we repeat the whole fragmentation again, which seems 
unnecessary.

> +
> +		drm_buddy_free_list(&mm, &clean, DRM_BUDDY_CLEARED);
> +		drm_buddy_free_list(&mm, &dirty, 0);
> +
> +		KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
> +								    size, size, &allocated,
> +								    DRM_BUDDY_CLEAR_ALLOCATION),
> +					"buddy_alloc hit an error size=%u\n", size);

size=%llu or better just make size u32.

> +		total = 0;
> +		list_for_each_entry(block, &allocated, link) {
> +			KUNIT_EXPECT_EQ(test, drm_buddy_block_is_clear(block), false);
> +			total += drm_buddy_block_size(&mm, block);
> +		}
> +		KUNIT_EXPECT_EQ(test, total, size);
> +
> +		drm_buddy_free_list(&mm, &allocated, 0);
> +	} while (++order <= max_order);

I think would be good to also do some non-power-of-two mm size. Just to 
ensure we get some coverage for the multi-root force_merge during fini. 
Something simple like create new mm here, allocate random size, free as 
cleared, then call fini.

Looks good otherwise.

> +
> +	drm_buddy_fini(&mm);
> +}
> +
>   static void drm_test_buddy_alloc_contiguous(struct kunit *test)
>   {
>   	const unsigned long ps = SZ_4K, mm_size = 16 * 3 * SZ_4K;
> @@ -368,6 +494,7 @@ static struct kunit_case drm_buddy_tests[] = {
>   	KUNIT_CASE(drm_test_buddy_alloc_pessimistic),
>   	KUNIT_CASE(drm_test_buddy_alloc_pathological),
>   	KUNIT_CASE(drm_test_buddy_alloc_contiguous),
> +	KUNIT_CASE(drm_test_buddy_alloc_clear),
>   	{}
>   };
>   

  reply	other threads:[~2024-03-26 17:47 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-18 21:40 [PATCH v9 1/3] drm/buddy: Implement tracking clear page feature Arunpravin Paneer Selvam
2024-03-18 21:40 ` [PATCH v9 2/3] drm/amdgpu: Enable clear page functionality Arunpravin Paneer Selvam
2024-03-19 10:28   ` Christian König
2024-03-19 11:41     ` Paneer Selvam, Arunpravin
2024-03-19 13:47       ` Christian König
2024-03-19 13:57         ` Paneer Selvam, Arunpravin
2024-03-26 13:38   ` Alex Deucher
2024-03-26 13:59     ` Paneer Selvam, Arunpravin
2024-03-26 14:01       ` Alex Deucher
2024-03-26 14:53         ` Alex Deucher
2024-03-27  8:23           ` Paneer Selvam, Arunpravin
2024-04-02  8:17           ` Christian König
2024-04-03  9:01             ` Michel Dänzer
2024-03-18 21:40 ` [PATCH v9 3/3] drm/tests: Add a test case for drm buddy clear allocation Arunpravin Paneer Selvam
2024-03-26 17:46   ` Matthew Auld [this message]
2024-03-25 13:37 ` [PATCH v9 1/3] drm/buddy: Implement tracking clear page feature Paneer Selvam, Arunpravin
2024-03-26 18:09 ` Matthew Auld
2024-03-28 16:07   ` Paneer Selvam, Arunpravin
2024-03-28 16:48     ` Matthew Auld
2024-04-01 11:07       ` Paneer Selvam, Arunpravin
2024-04-05 15:43         ` Matthew Auld

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=7936855e-f4f4-4b60-a2ff-146782607b16@intel.com \
    --to=matthew.auld@intel.com \
    --cc=Arunpravin.PaneerSelvam@amd.com \
    --cc=alexander.deucher@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=felix.kuehling@amd.com \
    --cc=mario.limonciello@amd.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.