linux-next: manual merge of the amdgpu tree with the drm-misc tree
From: Mark Brown
Date: Mon Sep 14 2026 - 09:38:52 EST
Hi all,
Today's linux-next merge of the amdgpu tree got a conflict in:
drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c
between commits:
3a2c4d55e32ad ("treewide: refresh kmalloc_obj() conversions")
32fbec62a3e9f ("drm/amdgpu: dm: Convert to atomic_create_state")
from the drm-misc tree and commits:
29d303de7669a ("drm/amd/display: Cover crtc duplicate_state stream and null guard")
b40f65c12577b ("drm/amd/display: Cover crtc destroy callback")
fa67092e4674c ("drm/amd/display: Add reset_state existing-state branch test")
from the amdgpu tree.
I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging. You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.
diff --cc drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c
index 17bd64611a823,544445fbc7706..0000000000000
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c
@@@ -1404,18 -1504,118 +1504,118 @@@ static void dm_test_crtc_duplicate_stat
amdgpu_dm_crtc_destroy_state(crtc, dup);
}
+/* Tests for amdgpu_dm_crtc_create_state() */
+
+ /**
+ * dm_test_crtc_duplicate_state_retains_stream - Test duplicate retains the stream
+ * @test: The KUnit test context
+ *
+ * When the current CRTC state carries a DC stream, duplicating the state must
+ * copy the stream pointer and take an additional reference on it. Destroying
+ * the duplicate then drops that reference back to the KUnit-managed one.
+ */
+ static void dm_test_crtc_duplicate_state_retains_stream(struct kunit *test)
+ {
+ struct dc_stream_state *stream;
+ struct drm_crtc *crtc;
+ struct dm_crtc_state *cur;
+ struct drm_crtc_state *dup;
+ struct dm_crtc_state *dm_dup;
+ struct dc_link *link;
+
+ crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
+ cur = kunit_kzalloc(test, sizeof(*cur), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cur);
+
+ link = dm_kunit_alloc_link(test);
+ stream = dm_kunit_alloc_stream(test, link);
+
+ cur->stream = stream;
+ crtc->state = &cur->base;
+
+ dup = amdgpu_dm_crtc_duplicate_state(crtc);
+ KUNIT_ASSERT_NOT_NULL(test, dup);
+
+ dm_dup = to_dm_crtc_state(dup);
+ KUNIT_EXPECT_PTR_EQ(test, dm_dup->stream, stream);
+ /* The duplicate took a second reference on top of the managed one. */
+ KUNIT_EXPECT_EQ(test, kref_read(&stream->refcount), 2);
+
+ /* Destroying the duplicate drops back to the KUnit-managed reference. */
+ amdgpu_dm_crtc_destroy_state(crtc, dup);
+ KUNIT_EXPECT_EQ(test, kref_read(&stream->refcount), 1);
+ }
+
+ /**
+ * dm_test_crtc_duplicate_state_null_state_returns_null - Test guard on missing state
+ * @test: The KUnit test context
+ *
+ * Duplicating a CRTC whose current state is NULL must trip the WARN_ON guard
+ * and return NULL without allocating a new state.
+ */
+ static void dm_test_crtc_duplicate_state_null_state_returns_null(struct kunit *test)
+ {
+ struct drm_crtc *crtc;
+
+ crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
+ crtc->state = NULL;
+
+ KUNIT_EXPECT_NULL(test, amdgpu_dm_crtc_duplicate_state(crtc));
+ }
+
-/* Tests for amdgpu_dm_crtc_destroy() */
-
+ /**
+ * dm_test_crtc_destroy_cleans_up_and_frees - Test destroy tears down the CRTC
+ * @test: The KUnit test context
+ *
+ * amdgpu_dm_crtc_destroy() is the drm_crtc .destroy callback: it must run
+ * drm_crtc_cleanup() and free the CRTC. Initialise a CRTC with a primary plane
+ * so it is registered on the device (num_crtc == 1), then destroy it and verify
+ * the CRTC was unregistered (num_crtc back to 0). The CRTC is a plain (unmanaged)
+ * allocation because amdgpu_dm_crtc_destroy() kfree()s it.
+ */
+ static void dm_test_crtc_destroy_cleans_up_and_frees(struct kunit *test)
+ {
+ struct amdgpu_device *adev;
+ struct amdgpu_crtc *acrtc;
+ struct drm_plane *plane;
+ int ret;
+
+ adev = dm_kunit_alloc_adev(test);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
+
+ plane = drm_kunit_helper_create_primary_plane(test, &adev->ddev,
+ NULL, NULL, NULL, 0, NULL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
+
+ /* amdgpu_dm_crtc_destroy() kfree()s the CRTC, so use a plain alloc. */
+ acrtc = kzalloc_obj(*acrtc, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, acrtc);
+
+ ret = drm_crtc_init_with_planes(&adev->ddev, &acrtc->base, plane,
+ NULL, &dm_test_crtc_funcs, NULL);
+ KUNIT_ASSERT_EQ(test, ret, 0);
+ KUNIT_EXPECT_EQ(test, adev->ddev.mode_config.num_crtc, 1);
+
+ amdgpu_dm_crtc_destroy(&acrtc->base);
+
+ /* drm_crtc_cleanup() ran: the CRTC was unregistered from the device. */
+ KUNIT_EXPECT_EQ(test, adev->ddev.mode_config.num_crtc, 0);
+ }
+
-/* Tests for amdgpu_dm_crtc_reset_state() */
++/* Tests for amdgpu_dm_crtc_destroy() */
+
/**
- * dm_test_crtc_reset_state_allocates_state - Test reset installs a fresh state
+ * dm_test_crtc_create_state_allocates_state - Test create_state allocates a fresh state
* @test: The KUnit test context
*
- * Resetting a CRTC with no existing state must allocate and install a new
- * drm_crtc_state.
+ * Creating state for a CRTC must allocate a new drm_crtc_state.
*/
-static void dm_test_crtc_reset_state_allocates_state(struct kunit *test)
+static void dm_test_crtc_create_state_allocates_state(struct kunit *test)
{
struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+ struct drm_crtc_state *crtc_state;
struct drm_crtc *crtc;
crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL);
@@@ -1423,13 -1623,56 +1623,55 @@@
crtc->dev = &adev->ddev;
crtc->state = NULL;
- amdgpu_dm_crtc_reset_state(crtc);
+ crtc_state = amdgpu_dm_crtc_create_state(crtc);
+ KUNIT_EXPECT_NOT_ERR_OR_NULL(test, crtc_state);
- KUNIT_EXPECT_NOT_NULL(test, crtc->state);
-
- if (crtc->state)
- amdgpu_dm_crtc_destroy_state(crtc, crtc->state);
+ if (!IS_ERR(crtc_state))
+ amdgpu_dm_crtc_destroy_state(crtc, crtc_state);
}
+ /**
+ * dm_test_crtc_reset_state_replaces_existing - Test reset frees the old state
+ * @test: The KUnit test context
+ *
+ * Resetting a CRTC that already carries a state must destroy the existing
+ * state before installing a fresh one. The old state holds a stream reference,
+ * so a successful reset drops that reference (via amdgpu_dm_crtc_destroy_state)
+ * and leaves the CRTC with a new, non-NULL state.
+ */
+ static void dm_test_crtc_reset_state_replaces_existing(struct kunit *test)
+ {
+ struct amdgpu_device *adev = dm_kunit_alloc_adev(test);
+ struct dc_stream_state *stream;
+ struct dm_crtc_state *old;
+ struct drm_crtc *crtc;
+ struct dc_link *link;
+
+ crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
+ crtc->dev = &adev->ddev;
+
+ link = dm_kunit_alloc_link(test);
+ stream = dm_kunit_alloc_stream(test, link);
+ /* Extra ref so destroying the old state drops back to the managed one. */
+ kref_get(&stream->refcount);
+
+ /* reset_state kfree()s the old state, so use a plain (unmanaged) alloc. */
+ old = kzalloc_obj(*old, GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old);
+ old->stream = stream;
+ crtc->state = &old->base;
+
+ amdgpu_dm_crtc_reset_state(crtc);
+
+ /* Old state was destroyed (stream ref dropped) and a new one installed. */
+ KUNIT_EXPECT_EQ(test, kref_read(&stream->refcount), 1);
+ KUNIT_EXPECT_NOT_NULL(test, crtc->state);
+
+ if (crtc->state)
+ amdgpu_dm_crtc_destroy_state(crtc, crtc->state);
+ }
+
/* Tests for amdgpu_dm_crtc_destroy_state() */
/**
@@@ -1906,8 -2634,13 +2633,12 @@@ static struct kunit_case amdgpu_dm_crtc
KUNIT_CASE(dm_test_count_crtc_active_planes_mixed),
/* amdgpu_dm_crtc_duplicate_state */
KUNIT_CASE(dm_test_crtc_duplicate_state_copies_fields),
+ /* amdgpu_dm_crtc_create_state */
+ KUNIT_CASE(dm_test_crtc_create_state_allocates_state),
+ KUNIT_CASE(dm_test_crtc_duplicate_state_retains_stream),
+ KUNIT_CASE(dm_test_crtc_duplicate_state_null_state_returns_null),
+ /* amdgpu_dm_crtc_destroy */
+ KUNIT_CASE(dm_test_crtc_destroy_cleans_up_and_frees),
- /* amdgpu_dm_crtc_reset_state */
- KUNIT_CASE(dm_test_crtc_reset_state_allocates_state),
- KUNIT_CASE(dm_test_crtc_reset_state_replaces_existing),
/* amdgpu_dm_crtc_destroy_state */
KUNIT_CASE(dm_test_crtc_destroy_state_no_stream),
KUNIT_CASE(dm_test_crtc_destroy_state_releases_stream),
Attachment:
signature.asc
Description: PGP signature