Hi everyone,
Here is the v2 of the conversion of DRM selftests to KUnit. Some style changes were made to align to the drm_format_helper series [1] and the documentation [2], as renaming the kunit_suite and the test cases to use underscores as suggested, changing the filenames and using a generic symbol to group all tests at the config menu.
Moreover, in the previous version of the series, the drm_cmdline_parser tests were broken into multiple test functions. As pointed out by Shuan Khan, it made the tests harder to comprehend. So, the refactoring was dropped and straightforward conversion of the tests was made without any functional changes.
Thanks for your attention and any feedback is welcomed!
Best Regards, - Maíra Canal
v1 -> v2: https://lore.kernel.org/dri-devel/20220615135824.15522-1-maira.canal@usp.br/...
- The suites no longer end in _tests (David Gow). - Remove the TODO entry involving the conversion of selftests to KUnit (Javier Martinez Canillas). - Change the filenames to match the documentation: use *_test.c (Javier Martinez Canillas). - Add MODULE_LICENSE to all tests (kernel test robot). - Make use of a generic symbol to group all tests - DRM_KUNIT_TEST (Javier Martinez Canillas). - Add .kunitconfig on the first patch (it was on the second patch of the series). - Straightforward conversion of the drm_cmdline_parser tests without functional changes (Shuah Khan) - Add David's Tested-by tags
[1] https://lore.kernel.org/dri-devel/20220620160640.3790-1-jose.exposito89@gmai... [2] https://www.kernel.org/doc/html/latest/dev-tools/kunit/style.html
Arthur Grillo (1): drm: selftest: convert drm_mm selftest to KUnit
Maíra Canal (8): drm: selftest: convert drm_damage_helper selftest to KUnit drm: selftest: convert drm_cmdline_parser selftest to KUnit drm: selftest: convert drm_rect selftest to KUnit drm: selftest: convert drm_format selftest to KUnit drm: selftest: convert drm_plane_helper selftest to KUnit drm: selftest: convert drm_dp_mst_helper selftest to KUnit drm: selftest: convert drm_framebuffer selftest to KUnit drm: selftest: convert drm_buddy selftest to KUnit
Documentation/gpu/todo.rst | 11 - drivers/gpu/drm/Kconfig | 15 +- drivers/gpu/drm/Makefile | 2 +- drivers/gpu/drm/selftests/Makefile | 8 - .../gpu/drm/selftests/drm_buddy_selftests.h | 15 - .../gpu/drm/selftests/drm_cmdline_selftests.h | 68 - drivers/gpu/drm/selftests/drm_mm_selftests.h | 28 - .../gpu/drm/selftests/drm_modeset_selftests.h | 40 - drivers/gpu/drm/selftests/drm_selftest.c | 109 -- drivers/gpu/drm/selftests/drm_selftest.h | 41 - drivers/gpu/drm/selftests/test-drm_buddy.c | 994 -------------- .../drm/selftests/test-drm_cmdline_parser.c | 1141 ----------------- .../drm/selftests/test-drm_damage_helper.c | 667 ---------- drivers/gpu/drm/selftests/test-drm_format.c | 280 ---- .../drm/selftests/test-drm_modeset_common.c | 32 - .../drm/selftests/test-drm_modeset_common.h | 52 - drivers/gpu/drm/tests/.kunitconfig | 3 + drivers/gpu/drm/tests/Makefile | 6 + drivers/gpu/drm/tests/drm_buddy_test.c | 748 +++++++++++ .../gpu/drm/tests/drm_cmdline_parser_test.c | 1078 ++++++++++++++++ .../gpu/drm/tests/drm_damage_helper_test.c | 633 +++++++++ .../drm_dp_mst_helper_test.c} | 84 +- drivers/gpu/drm/tests/drm_format_test.c | 284 ++++ .../drm_framebuffer_test.c} | 25 +- .../test-drm_mm.c => tests/drm_mm_test.c} | 1135 +++++++--------- .../drm_plane_helper_test.c} | 103 +- .../test-drm_rect.c => tests/drm_rect_test.c} | 124 +- 27 files changed, 3395 insertions(+), 4331 deletions(-) delete mode 100644 drivers/gpu/drm/selftests/Makefile delete mode 100644 drivers/gpu/drm/selftests/drm_buddy_selftests.h delete mode 100644 drivers/gpu/drm/selftests/drm_cmdline_selftests.h delete mode 100644 drivers/gpu/drm/selftests/drm_mm_selftests.h delete mode 100644 drivers/gpu/drm/selftests/drm_modeset_selftests.h delete mode 100644 drivers/gpu/drm/selftests/drm_selftest.c delete mode 100644 drivers/gpu/drm/selftests/drm_selftest.h delete mode 100644 drivers/gpu/drm/selftests/test-drm_buddy.c delete mode 100644 drivers/gpu/drm/selftests/test-drm_cmdline_parser.c delete mode 100644 drivers/gpu/drm/selftests/test-drm_damage_helper.c delete mode 100644 drivers/gpu/drm/selftests/test-drm_format.c delete mode 100644 drivers/gpu/drm/selftests/test-drm_modeset_common.c delete mode 100644 drivers/gpu/drm/selftests/test-drm_modeset_common.h create mode 100644 drivers/gpu/drm/tests/.kunitconfig create mode 100644 drivers/gpu/drm/tests/Makefile create mode 100644 drivers/gpu/drm/tests/drm_buddy_test.c create mode 100644 drivers/gpu/drm/tests/drm_cmdline_parser_test.c create mode 100644 drivers/gpu/drm/tests/drm_damage_helper_test.c rename drivers/gpu/drm/{selftests/test-drm_dp_mst_helper.c => tests/drm_dp_mst_helper_test.c} (73%) create mode 100644 drivers/gpu/drm/tests/drm_format_test.c rename drivers/gpu/drm/{selftests/test-drm_framebuffer.c => tests/drm_framebuffer_test.c} (96%) rename drivers/gpu/drm/{selftests/test-drm_mm.c => tests/drm_mm_test.c} (58%) rename drivers/gpu/drm/{selftests/test-drm_plane_helper.c => tests/drm_plane_helper_test.c} (62%) rename drivers/gpu/drm/{selftests/test-drm_rect.c => tests/drm_rect_test.c} (53%)
Considering the current adoption of the KUnit framework, convert the DRM damage helper selftest to the KUnit API.
Tested-by: David Gow davidgow@google.com Co-developed-by: Arthur Grillo arthur.grillo@usp.br Signed-off-by: Arthur Grillo arthur.grillo@usp.br Signed-off-by: Maíra Canal maira.canal@usp.br --- drivers/gpu/drm/Kconfig | 19 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/selftests/Makefile | 3 +- .../gpu/drm/selftests/drm_modeset_selftests.h | 21 - .../drm/selftests/test-drm_damage_helper.c | 667 ------------------ .../drm/selftests/test-drm_modeset_common.h | 21 - drivers/gpu/drm/tests/.kunitconfig | 3 + drivers/gpu/drm/tests/Makefile | 3 + .../gpu/drm/tests/drm_damage_helper_test.c | 633 +++++++++++++++++ 9 files changed, 660 insertions(+), 711 deletions(-) delete mode 100644 drivers/gpu/drm/selftests/test-drm_damage_helper.c create mode 100644 drivers/gpu/drm/tests/.kunitconfig create mode 100644 drivers/gpu/drm/tests/Makefile create mode 100644 drivers/gpu/drm/tests/drm_damage_helper_test.c
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index e88c497fa010..f49639bcdbff 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -70,6 +70,25 @@ config DRM_DEBUG_SELFTEST
If in doubt, say "N".
+config DRM_KUNIT_TEST + tristate "KUnit tests for DRM" if !KUNIT_ALL_TESTS + depends on DRM && KUNIT + select PRIME_NUMBERS + select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_HELPER + select DRM_LIB_RANDOM + select DRM_KMS_HELPER + select DRM_BUDDY + select DRM_EXPORT_FOR_TESTS if m + default KUNIT_ALL_TESTS + help + This option provides a KUnit module that can be used to run + all unit tests on the DRM API. This option is not useful for + distributions or general kernels, but only for kernel + developers working on DRM and associated drivers. + + If in doubt, say "N". + config DRM_KMS_HELPER tristate depends on DRM diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 15fe3163f822..ebc82c5fa65f 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -76,6 +76,7 @@ obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o #
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/ +obj-$(CONFIG_DRM_KUNIT_TEST) += tests/
obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index 5ba5f9138c95..7a1a732e0a1b 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,8 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ test-drm_format.o test-drm_framebuffer.o \ - test-drm_damage_helper.o test-drm_dp_mst_helper.o \ - test-drm_rect.o + test-drm_dp_mst_helper.o test-drm_rect.o
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o test-drm_cmdline_parser.o \ test-drm_buddy.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h index 782e285ca383..4787b3b70709 100644 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h @@ -15,26 +15,5 @@ selftest(check_drm_format_block_width, igt_check_drm_format_block_width) selftest(check_drm_format_block_height, igt_check_drm_format_block_height) selftest(check_drm_format_min_pitch, igt_check_drm_format_min_pitch) selftest(check_drm_framebuffer_create, igt_check_drm_framebuffer_create) -selftest(damage_iter_no_damage, igt_damage_iter_no_damage) -selftest(damage_iter_no_damage_fractional_src, igt_damage_iter_no_damage_fractional_src) -selftest(damage_iter_no_damage_src_moved, igt_damage_iter_no_damage_src_moved) -selftest(damage_iter_no_damage_fractional_src_moved, igt_damage_iter_no_damage_fractional_src_moved) -selftest(damage_iter_no_damage_not_visible, igt_damage_iter_no_damage_not_visible) -selftest(damage_iter_no_damage_no_crtc, igt_damage_iter_no_damage_no_crtc) -selftest(damage_iter_no_damage_no_fb, igt_damage_iter_no_damage_no_fb) -selftest(damage_iter_simple_damage, igt_damage_iter_simple_damage) -selftest(damage_iter_single_damage, igt_damage_iter_single_damage) -selftest(damage_iter_single_damage_intersect_src, igt_damage_iter_single_damage_intersect_src) -selftest(damage_iter_single_damage_outside_src, igt_damage_iter_single_damage_outside_src) -selftest(damage_iter_single_damage_fractional_src, igt_damage_iter_single_damage_fractional_src) -selftest(damage_iter_single_damage_intersect_fractional_src, igt_damage_iter_single_damage_intersect_fractional_src) -selftest(damage_iter_single_damage_outside_fractional_src, igt_damage_iter_single_damage_outside_fractional_src) -selftest(damage_iter_single_damage_src_moved, igt_damage_iter_single_damage_src_moved) -selftest(damage_iter_single_damage_fractional_src_moved, igt_damage_iter_single_damage_fractional_src_moved) -selftest(damage_iter_damage, igt_damage_iter_damage) -selftest(damage_iter_damage_one_intersect, igt_damage_iter_damage_one_intersect) -selftest(damage_iter_damage_one_outside, igt_damage_iter_damage_one_outside) -selftest(damage_iter_damage_src_moved, igt_damage_iter_damage_src_moved) -selftest(damage_iter_damage_not_visible, igt_damage_iter_damage_not_visible) selftest(dp_mst_calc_pbn_mode, igt_dp_mst_calc_pbn_mode) selftest(dp_mst_sideband_msg_req_decode, igt_dp_mst_sideband_msg_req_decode) diff --git a/drivers/gpu/drm/selftests/test-drm_damage_helper.c b/drivers/gpu/drm/selftests/test-drm_damage_helper.c deleted file mode 100644 index 8d8d8e214c28..000000000000 --- a/drivers/gpu/drm/selftests/test-drm_damage_helper.c +++ /dev/null @@ -1,667 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Test case for drm_damage_helper functions - */ - -#define pr_fmt(fmt) "drm_damage_helper: " fmt - -#include <drm/drm_damage_helper.h> -#include <drm/drm_plane.h> -#include <drm/drm_drv.h> - -#include "test-drm_modeset_common.h" - -struct drm_driver mock_driver; -static struct drm_device mock_device; -static struct drm_object_properties mock_obj_props; -static struct drm_plane mock_plane; -static struct drm_property mock_prop; - -static void mock_setup(struct drm_plane_state *state) -{ - static bool setup_done = false; - - state->plane = &mock_plane; - - if (setup_done) - return; - - /* just enough so that drm_plane_enable_fb_damage_clips() works */ - mock_device.driver = &mock_driver; - mock_device.mode_config.prop_fb_damage_clips = &mock_prop; - mock_plane.dev = &mock_device; - mock_obj_props.count = 0; - mock_plane.base.properties = &mock_obj_props; - mock_prop.base.id = 1; /* 0 is an invalid id */ - mock_prop.dev = &mock_device; - - drm_plane_enable_fb_damage_clips(&mock_plane); -} - -static void set_plane_src(struct drm_plane_state *state, int x1, int y1, int x2, - int y2) -{ - state->src.x1 = x1; - state->src.y1 = y1; - state->src.x2 = x2; - state->src.y2 = y2; -} - -static void set_damage_clip(struct drm_mode_rect *r, int x1, int y1, int x2, - int y2) -{ - r->x1 = x1; - r->y1 = y1; - r->x2 = x2; - r->y2 = y2; -} - -static void set_damage_blob(struct drm_property_blob *damage_blob, - struct drm_mode_rect *r, uint32_t size) -{ - damage_blob->length = size; - damage_blob->data = r; -} - -static void set_plane_damage(struct drm_plane_state *state, - struct drm_property_blob *damage_blob) -{ - state->fb_damage_clips = damage_blob; -} - -static bool check_damage_clip(struct drm_plane_state *state, struct drm_rect *r, - int x1, int y1, int x2, int y2) -{ - /* - * Round down x1/y1 and round up x2/y2. This is because damage is not in - * 16.16 fixed point so to catch all pixels. - */ - int src_x1 = state->src.x1 >> 16; - int src_y1 = state->src.y1 >> 16; - int src_x2 = (state->src.x2 >> 16) + !!(state->src.x2 & 0xFFFF); - int src_y2 = (state->src.y2 >> 16) + !!(state->src.y2 & 0xFFFF); - - if (x1 >= x2 || y1 >= y2) { - pr_err("Cannot have damage clip with no dimension.\n"); - return false; - } - - if (x1 < src_x1 || y1 < src_y1 || x2 > src_x2 || y2 > src_y2) { - pr_err("Damage cannot be outside rounded plane src.\n"); - return false; - } - - if (r->x1 != x1 || r->y1 != y1 || r->x2 != x2 || r->y2 != y2) { - pr_err("Damage = %d %d %d %d\n", r->x1, r->y1, r->x2, r->y2); - return false; - } - - return true; -} - -const struct drm_framebuffer fb = { - .width = 2048, - .height = 2048 -}; - -/* common mocked structs many tests need */ -#define MOCK_VARIABLES() \ - struct drm_plane_state old_state; \ - struct drm_plane_state state = { \ - .crtc = ZERO_SIZE_PTR, \ - .fb = (struct drm_framebuffer *) &fb, \ - .visible = true, \ - }; \ - mock_setup(&old_state); \ - mock_setup(&state); - -int igt_damage_iter_no_damage(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - /* Plane src same as fb size. */ - set_plane_src(&old_state, 0, 0, fb.width << 16, fb.height << 16); - set_plane_src(&state, 0, 0, fb.width << 16, fb.height << 16); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 1, "Should return plane src as damage."); - FAIL_ON(!check_damage_clip(&state, &clip, 0, 0, 2048, 2048)); - - return 0; -} - -int igt_damage_iter_no_damage_fractional_src(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - /* Plane src has fractional part. */ - set_plane_src(&old_state, 0x3fffe, 0x3fffe, - 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); - set_plane_src(&state, 0x3fffe, 0x3fffe, - 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 1, "Should return rounded off plane src as damage."); - FAIL_ON(!check_damage_clip(&state, &clip, 3, 3, 1028, 772)); - - return 0; -} - -int igt_damage_iter_no_damage_src_moved(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - /* Plane src moved since old plane state. */ - set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); - set_plane_src(&state, 10 << 16, 10 << 16, - (10 + 1024) << 16, (10 + 768) << 16); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 1, "Should return plane src as damage."); - FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 1034, 778)); - - return 0; -} - -int igt_damage_iter_no_damage_fractional_src_moved(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - /* Plane src has fractional part and it moved since old plane state. */ - set_plane_src(&old_state, 0x3fffe, 0x3fffe, - 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); - set_plane_src(&state, 0x40002, 0x40002, - 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 1, "Should return plane src as damage."); - FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773)); - - return 0; -} - -int igt_damage_iter_no_damage_not_visible(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - state.visible = false; - - mock_setup(&old_state); - - set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); - set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 0, "Should have no damage."); - - return 0; -} - -int igt_damage_iter_no_damage_no_crtc(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - state.crtc = NULL; - - set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); - set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 0, "Should have no damage."); - - return 0; -} - -int igt_damage_iter_no_damage_no_fb(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_plane_state old_state; - struct drm_rect clip; - uint32_t num_hits = 0; - - struct drm_plane_state state = { - .crtc = ZERO_SIZE_PTR, - .fb = 0, - }; - - mock_setup(&old_state); - - set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); - set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 0, "Should have no damage."); - - return 0; -} - -int igt_damage_iter_simple_damage(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_property_blob damage_blob; - struct drm_mode_rect damage; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); - set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); - /* Damage set to plane src */ - set_damage_clip(&damage, 0, 0, 1024, 768); - set_damage_blob(&damage_blob, &damage, sizeof(damage)); - set_plane_damage(&state, &damage_blob); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 1, "Should return damage when set."); - FAIL_ON(!check_damage_clip(&state, &clip, 0, 0, 1024, 768)); - - return 0; -} - -int igt_damage_iter_single_damage(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_property_blob damage_blob; - struct drm_mode_rect damage; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); - set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); - set_damage_clip(&damage, 256, 192, 768, 576); - set_damage_blob(&damage_blob, &damage, sizeof(damage)); - set_plane_damage(&state, &damage_blob); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 1, "Should return damage when set."); - FAIL_ON(!check_damage_clip(&state, &clip, 256, 192, 768, 576)); - - return 0; -} - -int igt_damage_iter_single_damage_intersect_src(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_property_blob damage_blob; - struct drm_mode_rect damage; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); - set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); - /* Damage intersect with plane src. */ - set_damage_clip(&damage, 256, 192, 1360, 768); - set_damage_blob(&damage_blob, &damage, sizeof(damage)); - set_plane_damage(&state, &damage_blob); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 1, "Should return damage clipped to src."); - FAIL_ON(!check_damage_clip(&state, &clip, 256, 192, 1024, 768)); - - return 0; -} - -int igt_damage_iter_single_damage_outside_src(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_property_blob damage_blob; - struct drm_mode_rect damage; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); - set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); - /* Damage clip outside plane src */ - set_damage_clip(&damage, 1360, 1360, 1380, 1380); - set_damage_blob(&damage_blob, &damage, sizeof(damage)); - set_plane_damage(&state, &damage_blob); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 0, "Should have no damage."); - - return 0; -} - -int igt_damage_iter_single_damage_fractional_src(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_property_blob damage_blob; - struct drm_mode_rect damage; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - /* Plane src has fractional part. */ - set_plane_src(&old_state, 0x40002, 0x40002, - 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); - set_plane_src(&state, 0x40002, 0x40002, - 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); - set_damage_clip(&damage, 10, 10, 256, 330); - set_damage_blob(&damage_blob, &damage, sizeof(damage)); - set_plane_damage(&state, &damage_blob); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 1, "Should return damage when set."); - FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 256, 330)); - - return 0; -} - -int igt_damage_iter_single_damage_intersect_fractional_src(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_property_blob damage_blob; - struct drm_mode_rect damage; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - /* Plane src has fractional part. */ - set_plane_src(&old_state, 0x40002, 0x40002, - 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); - set_plane_src(&state, 0x40002, 0x40002, - 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); - /* Damage intersect with plane src. */ - set_damage_clip(&damage, 10, 1, 1360, 330); - set_damage_blob(&damage_blob, &damage, sizeof(damage)); - set_plane_damage(&state, &damage_blob); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 1, "Should return damage clipped to rounded off src."); - FAIL_ON(!check_damage_clip(&state, &clip, 10, 4, 1029, 330)); - - return 0; -} - -int igt_damage_iter_single_damage_outside_fractional_src(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_property_blob damage_blob; - struct drm_mode_rect damage; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - /* Plane src has fractional part. */ - set_plane_src(&old_state, 0x40002, 0x40002, - 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); - set_plane_src(&state, 0x40002, 0x40002, - 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); - /* Damage clip outside plane src */ - set_damage_clip(&damage, 1360, 1360, 1380, 1380); - set_damage_blob(&damage_blob, &damage, sizeof(damage)); - set_plane_damage(&state, &damage_blob); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 0, "Should have no damage."); - - return 0; -} - -int igt_damage_iter_single_damage_src_moved(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_property_blob damage_blob; - struct drm_mode_rect damage; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - /* Plane src moved since old plane state. */ - set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); - set_plane_src(&state, 10 << 16, 10 << 16, - (10 + 1024) << 16, (10 + 768) << 16); - set_damage_clip(&damage, 20, 30, 256, 256); - set_damage_blob(&damage_blob, &damage, sizeof(damage)); - set_plane_damage(&state, &damage_blob); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 1, "Should return plane src as damage."); - FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 1034, 778)); - - return 0; -} - -int igt_damage_iter_single_damage_fractional_src_moved(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_property_blob damage_blob; - struct drm_mode_rect damage; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - /* Plane src with fractional part moved since old plane state. */ - set_plane_src(&old_state, 0x3fffe, 0x3fffe, - 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); - set_plane_src(&state, 0x40002, 0x40002, - 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); - /* Damage intersect with plane src. */ - set_damage_clip(&damage, 20, 30, 1360, 256); - set_damage_blob(&damage_blob, &damage, sizeof(damage)); - set_plane_damage(&state, &damage_blob); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 1, "Should return rounded off plane src as damage."); - FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773)); - - return 0; -} - -int igt_damage_iter_damage(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_property_blob damage_blob; - struct drm_mode_rect damage[2]; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); - set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); - /* 2 damage clips. */ - set_damage_clip(&damage[0], 20, 30, 200, 180); - set_damage_clip(&damage[1], 240, 200, 280, 250); - set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); - set_plane_damage(&state, &damage_blob); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) { - if (num_hits == 0) - FAIL_ON(!check_damage_clip(&state, &clip, 20, 30, 200, 180)); - if (num_hits == 1) - FAIL_ON(!check_damage_clip(&state, &clip, 240, 200, 280, 250)); - num_hits++; - } - - FAIL(num_hits != 2, "Should return damage when set."); - - return 0; -} - -int igt_damage_iter_damage_one_intersect(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_property_blob damage_blob; - struct drm_mode_rect damage[2]; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - set_plane_src(&old_state, 0x40002, 0x40002, - 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); - set_plane_src(&state, 0x40002, 0x40002, - 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); - /* 2 damage clips, one intersect plane src. */ - set_damage_clip(&damage[0], 20, 30, 200, 180); - set_damage_clip(&damage[1], 2, 2, 1360, 1360); - set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); - set_plane_damage(&state, &damage_blob); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) { - if (num_hits == 0) - FAIL_ON(!check_damage_clip(&state, &clip, 20, 30, 200, 180)); - if (num_hits == 1) - FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773)); - num_hits++; - } - - FAIL(num_hits != 2, "Should return damage when set."); - - return 0; -} - -int igt_damage_iter_damage_one_outside(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_property_blob damage_blob; - struct drm_mode_rect damage[2]; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16); - set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16); - /* 2 damage clips, one outside plane src. */ - set_damage_clip(&damage[0], 1360, 1360, 1380, 1380); - set_damage_clip(&damage[1], 240, 200, 280, 250); - set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); - set_plane_damage(&state, &damage_blob); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 1, "Should return damage when set."); - FAIL_ON(!check_damage_clip(&state, &clip, 240, 200, 280, 250)); - - return 0; -} - -int igt_damage_iter_damage_src_moved(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_property_blob damage_blob; - struct drm_mode_rect damage[2]; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - set_plane_src(&old_state, 0x40002, 0x40002, - 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); - set_plane_src(&state, 0x3fffe, 0x3fffe, - 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); - /* 2 damage clips, one outside plane src. */ - set_damage_clip(&damage[0], 1360, 1360, 1380, 1380); - set_damage_clip(&damage[1], 240, 200, 280, 250); - set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); - set_plane_damage(&state, &damage_blob); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 1, "Should return round off plane src as damage."); - FAIL_ON(!check_damage_clip(&state, &clip, 3, 3, 1028, 772)); - - return 0; -} - -int igt_damage_iter_damage_not_visible(void *ignored) -{ - struct drm_atomic_helper_damage_iter iter; - struct drm_property_blob damage_blob; - struct drm_mode_rect damage[2]; - struct drm_rect clip; - uint32_t num_hits = 0; - - MOCK_VARIABLES(); - - state.visible = false; - - set_plane_src(&old_state, 0x40002, 0x40002, - 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); - set_plane_src(&state, 0x3fffe, 0x3fffe, - 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); - /* 2 damage clips, one outside plane src. */ - set_damage_clip(&damage[0], 1360, 1360, 1380, 1380); - set_damage_clip(&damage[1], 240, 200, 280, 250); - set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); - set_plane_damage(&state, &damage_blob); - drm_atomic_helper_damage_iter_init(&iter, &old_state, &state); - drm_atomic_for_each_plane_damage(&iter, &clip) - num_hits++; - - FAIL(num_hits != 0, "Should not return any damage."); - - return 0; -} diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h index cfb51d8da2bc..c29354e59cec 100644 --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h @@ -25,27 +25,6 @@ int igt_check_drm_format_block_width(void *ignored); int igt_check_drm_format_block_height(void *ignored); int igt_check_drm_format_min_pitch(void *ignored); int igt_check_drm_framebuffer_create(void *ignored); -int igt_damage_iter_no_damage(void *ignored); -int igt_damage_iter_no_damage_fractional_src(void *ignored); -int igt_damage_iter_no_damage_src_moved(void *ignored); -int igt_damage_iter_no_damage_fractional_src_moved(void *ignored); -int igt_damage_iter_no_damage_not_visible(void *ignored); -int igt_damage_iter_no_damage_no_crtc(void *ignored); -int igt_damage_iter_no_damage_no_fb(void *ignored); -int igt_damage_iter_simple_damage(void *ignored); -int igt_damage_iter_single_damage(void *ignored); -int igt_damage_iter_single_damage_intersect_src(void *ignored); -int igt_damage_iter_single_damage_outside_src(void *ignored); -int igt_damage_iter_single_damage_fractional_src(void *ignored); -int igt_damage_iter_single_damage_intersect_fractional_src(void *ignored); -int igt_damage_iter_single_damage_outside_fractional_src(void *ignored); -int igt_damage_iter_single_damage_src_moved(void *ignored); -int igt_damage_iter_single_damage_fractional_src_moved(void *ignored); -int igt_damage_iter_damage(void *ignored); -int igt_damage_iter_damage_one_intersect(void *ignored); -int igt_damage_iter_damage_one_outside(void *ignored); -int igt_damage_iter_damage_src_moved(void *ignored); -int igt_damage_iter_damage_not_visible(void *ignored); int igt_dp_mst_calc_pbn_mode(void *ignored); int igt_dp_mst_sideband_msg_req_decode(void *ignored);
diff --git a/drivers/gpu/drm/tests/.kunitconfig b/drivers/gpu/drm/tests/.kunitconfig new file mode 100644 index 000000000000..6ec04b4c979d --- /dev/null +++ b/drivers/gpu/drm/tests/.kunitconfig @@ -0,0 +1,3 @@ +CONFIG_KUNIT=y +CONFIG_DRM=y +CONFIG_DRM_KUNIT_TEST=y diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile new file mode 100644 index 000000000000..181ac2c9977a --- /dev/null +++ b/drivers/gpu/drm/tests/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_DRM_KUNIT_TEST) += drm_damage_helper_test.o diff --git a/drivers/gpu/drm/tests/drm_damage_helper_test.c b/drivers/gpu/drm/tests/drm_damage_helper_test.c new file mode 100644 index 000000000000..fff2c39c6f34 --- /dev/null +++ b/drivers/gpu/drm/tests/drm_damage_helper_test.c @@ -0,0 +1,633 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test case for drm_damage_helper functions + */ + +#include <kunit/test.h> +#include <drm/drm_damage_helper.h> +#include <drm/drm_plane.h> +#include <drm/drm_drv.h> + +struct drm_damage_mock { + struct drm_driver driver; + struct drm_device device; + struct drm_object_properties obj_props; + struct drm_plane plane; + struct drm_property prop; + struct drm_framebuffer fb; + struct drm_plane_state state; + struct drm_plane_state old_state; +}; + +static int drm_damage_helper_init(struct kunit *test) +{ + struct drm_damage_mock *mock; + + mock = kunit_kzalloc(test, sizeof(*mock), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mock); + + mock->fb.width = 2048; + mock->fb.height = 2048; + + mock->state.crtc = ZERO_SIZE_PTR; + mock->state.fb = &mock->fb; + mock->state.visible = true; + + mock->old_state.plane = &mock->plane; + mock->state.plane = &mock->plane; + + /* just enough so that drm_plane_enable_fb_damage_clips() works */ + mock->device.driver = &mock->driver; + mock->device.mode_config.prop_fb_damage_clips = &mock->prop; + mock->plane.dev = &mock->device; + mock->obj_props.count = 0; + mock->plane.base.properties = &mock->obj_props; + mock->prop.base.id = 1; /* 0 is an invalid id */ + mock->prop.dev = &mock->device; + + drm_plane_enable_fb_damage_clips(&mock->plane); + + test->priv = mock; + + return 0; +} + +static void set_plane_src(struct drm_plane_state *state, int x1, int y1, int x2, + int y2) +{ + state->src.x1 = x1; + state->src.y1 = y1; + state->src.x2 = x2; + state->src.y2 = y2; +} + +static void set_damage_clip(struct drm_mode_rect *r, int x1, int y1, int x2, + int y2) +{ + r->x1 = x1; + r->y1 = y1; + r->x2 = x2; + r->y2 = y2; +} + +static void set_damage_blob(struct drm_property_blob *damage_blob, + struct drm_mode_rect *r, uint32_t size) +{ + damage_blob->length = size; + damage_blob->data = r; +} + +static void set_plane_damage(struct drm_plane_state *state, + struct drm_property_blob *damage_blob) +{ + state->fb_damage_clips = damage_blob; +} + +static void check_damage_clip(struct kunit *test, struct drm_rect *r, + int x1, int y1, int x2, int y2) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_plane_state state = mock->state; + + /* + * Round down x1/y1 and round up x2/y2. This is because damage is not in + * 16.16 fixed point so to catch all pixels. + */ + int src_x1 = state.src.x1 >> 16; + int src_y1 = state.src.y1 >> 16; + int src_x2 = (state.src.x2 >> 16) + !!(state.src.x2 & 0xFFFF); + int src_y2 = (state.src.y2 >> 16) + !!(state.src.y2 & 0xFFFF); + + if (x1 >= x2 || y1 >= y2) + KUNIT_FAIL(test, "Cannot have damage clip with no dimension."); + if (x1 < src_x1 || y1 < src_y1 || x2 > src_x2 || y2 > src_y2) + KUNIT_FAIL(test, "Damage cannot be outside rounded plane src."); + if (r->x1 != x1 || r->y1 != y1 || r->x2 != x2 || r->y2 != y2) + KUNIT_FAIL(test, "Damage = %d %d %d %d, want = %d %d %d %d", + r->x1, r->y1, r->x2, r->y2, x1, y1, x2, y2); +} + +static void igt_damage_iter_no_damage(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_rect clip; + uint32_t num_hits = 0; + + /* Plane src same as fb size. */ + set_plane_src(&mock->old_state, 0, 0, mock->fb.width << 16, mock->fb.height << 16); + set_plane_src(&mock->state, 0, 0, mock->fb.width << 16, mock->fb.height << 16); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return plane src as damage."); + check_damage_clip(test, &clip, 0, 0, 2048, 2048); +} + +static void igt_damage_iter_no_damage_fractional_src(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_rect clip; + uint32_t num_hits = 0; + + /* Plane src has fractional part. */ + set_plane_src(&mock->old_state, 0x3fffe, 0x3fffe, + 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); + set_plane_src(&mock->state, 0x3fffe, 0x3fffe, + 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, + "Should return rounded off plane src as damage."); + check_damage_clip(test, &clip, 3, 3, 1028, 772); +} + +static void igt_damage_iter_no_damage_src_moved(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_rect clip; + uint32_t num_hits = 0; + + /* Plane src moved since old plane state. */ + set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16); + set_plane_src(&mock->state, 10 << 16, 10 << 16, + (10 + 1024) << 16, (10 + 768) << 16); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return plane src as damage."); + check_damage_clip(test, &clip, 10, 10, 1034, 778); +} + +static void igt_damage_iter_no_damage_fractional_src_moved(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_rect clip; + uint32_t num_hits = 0; + + /* Plane src has fractional part and it moved since old plane state. */ + set_plane_src(&mock->old_state, 0x3fffe, 0x3fffe, + 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); + set_plane_src(&mock->state, 0x40002, 0x40002, + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return plane src as damage."); + check_damage_clip(test, &clip, 4, 4, 1029, 773); +} + +static void igt_damage_iter_no_damage_not_visible(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_rect clip; + uint32_t num_hits = 0; + + mock->state.visible = false; + + set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16); + set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage."); +} + +static void igt_damage_iter_no_damage_no_crtc(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_rect clip; + uint32_t num_hits = 0; + + mock->state.crtc = NULL; + + set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16); + set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage."); +} + +static void igt_damage_iter_no_damage_no_fb(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_rect clip; + uint32_t num_hits = 0; + + mock->state.fb = NULL; + + set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16); + set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage."); +} + +static void igt_damage_iter_simple_damage(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_property_blob damage_blob; + struct drm_mode_rect damage; + struct drm_rect clip; + uint32_t num_hits = 0; + + set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16); + set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16); + /* Damage set to plane src */ + set_damage_clip(&damage, 0, 0, 1024, 768); + set_damage_blob(&damage_blob, &damage, sizeof(damage)); + set_plane_damage(&mock->state, &damage_blob); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set."); + check_damage_clip(test, &clip, 0, 0, 1024, 768); +} + +static void igt_damage_iter_single_damage(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_property_blob damage_blob; + struct drm_mode_rect damage; + struct drm_rect clip; + uint32_t num_hits = 0; + + set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16); + set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16); + set_damage_clip(&damage, 256, 192, 768, 576); + set_damage_blob(&damage_blob, &damage, sizeof(damage)); + set_plane_damage(&mock->state, &damage_blob); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set."); + check_damage_clip(test, &clip, 256, 192, 768, 576); +} + +static void igt_damage_iter_single_damage_intersect_src(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_property_blob damage_blob; + struct drm_mode_rect damage; + struct drm_rect clip; + uint32_t num_hits = 0; + + set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16); + set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16); + /* Damage intersect with plane src. */ + set_damage_clip(&damage, 256, 192, 1360, 768); + set_damage_blob(&damage_blob, &damage, sizeof(damage)); + set_plane_damage(&mock->state, &damage_blob); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage clipped to src."); + check_damage_clip(test, &clip, 256, 192, 1024, 768); +} + +static void igt_damage_iter_single_damage_outside_src(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_property_blob damage_blob; + struct drm_mode_rect damage; + struct drm_rect clip; + uint32_t num_hits = 0; + + set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16); + set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16); + /* Damage clip outside plane src */ + set_damage_clip(&damage, 1360, 1360, 1380, 1380); + set_damage_blob(&damage_blob, &damage, sizeof(damage)); + set_plane_damage(&mock->state, &damage_blob); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage."); +} + +static void igt_damage_iter_single_damage_fractional_src(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_property_blob damage_blob; + struct drm_mode_rect damage; + struct drm_rect clip; + uint32_t num_hits = 0; + + /* Plane src has fractional part. */ + set_plane_src(&mock->old_state, 0x40002, 0x40002, + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); + set_plane_src(&mock->state, 0x40002, 0x40002, + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); + set_damage_clip(&damage, 10, 10, 256, 330); + set_damage_blob(&damage_blob, &damage, sizeof(damage)); + set_plane_damage(&mock->state, &damage_blob); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set."); + check_damage_clip(test, &clip, 10, 10, 256, 330); +} + +static void igt_damage_iter_single_damage_intersect_fractional_src( + struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_property_blob damage_blob; + struct drm_mode_rect damage; + struct drm_rect clip; + uint32_t num_hits = 0; + + /* Plane src has fractional part. */ + set_plane_src(&mock->old_state, 0x40002, 0x40002, + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); + set_plane_src(&mock->state, 0x40002, 0x40002, + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); + /* Damage intersect with plane src. */ + set_damage_clip(&damage, 10, 1, 1360, 330); + set_damage_blob(&damage_blob, &damage, sizeof(damage)); + set_plane_damage(&mock->state, &damage_blob); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, + "Should return damage clipped to rounded off src."); + check_damage_clip(test, &clip, 10, 4, 1029, 330); +} + +static void igt_damage_iter_single_damage_outside_fractional_src( + struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_property_blob damage_blob; + struct drm_mode_rect damage; + struct drm_rect clip; + uint32_t num_hits = 0; + + /* Plane src has fractional part. */ + set_plane_src(&mock->old_state, 0x40002, 0x40002, + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); + set_plane_src(&mock->state, 0x40002, 0x40002, + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); + /* Damage clip outside plane src */ + set_damage_clip(&damage, 1360, 1360, 1380, 1380); + set_damage_blob(&damage_blob, &damage, sizeof(damage)); + set_plane_damage(&mock->state, &damage_blob); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage."); +} + +static void igt_damage_iter_single_damage_src_moved(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_property_blob damage_blob; + struct drm_mode_rect damage; + struct drm_rect clip; + uint32_t num_hits = 0; + + /* Plane src moved since old plane state. */ + set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16); + set_plane_src(&mock->state, 10 << 16, 10 << 16, + (10 + 1024) << 16, (10 + 768) << 16); + set_damage_clip(&damage, 20, 30, 256, 256); + set_damage_blob(&damage_blob, &damage, sizeof(damage)); + set_plane_damage(&mock->state, &damage_blob); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, + "Should return plane src as damage."); + check_damage_clip(test, &clip, 10, 10, 1034, 778); +} + +static void igt_damage_iter_single_damage_fractional_src_moved( + struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_property_blob damage_blob; + struct drm_mode_rect damage; + struct drm_rect clip; + uint32_t num_hits = 0; + + /* Plane src with fractional part moved since old plane state. */ + set_plane_src(&mock->old_state, 0x3fffe, 0x3fffe, + 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); + set_plane_src(&mock->state, 0x40002, 0x40002, + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); + /* Damage intersect with plane src. */ + set_damage_clip(&damage, 20, 30, 1360, 256); + set_damage_blob(&damage_blob, &damage, sizeof(damage)); + set_plane_damage(&mock->state, &damage_blob); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, + "Should return rounded off plane as damage."); + check_damage_clip(test, &clip, 4, 4, 1029, 773); +} + +static void igt_damage_iter_damage(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_property_blob damage_blob; + struct drm_mode_rect damage[2]; + struct drm_rect clip; + uint32_t num_hits = 0; + + set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16); + set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16); + /* 2 damage clips. */ + set_damage_clip(&damage[0], 20, 30, 200, 180); + set_damage_clip(&damage[1], 240, 200, 280, 250); + set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); + set_plane_damage(&mock->state, &damage_blob); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) { + if (num_hits == 0) + check_damage_clip(test, &clip, 20, 30, 200, 180); + if (num_hits == 1) + check_damage_clip(test, &clip, 240, 200, 280, 250); + num_hits++; + } + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 2, "Should return damage when set."); +} + +static void igt_damage_iter_damage_one_intersect(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_property_blob damage_blob; + struct drm_mode_rect damage[2]; + struct drm_rect clip; + uint32_t num_hits = 0; + + set_plane_src(&mock->old_state, 0x40002, 0x40002, + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); + set_plane_src(&mock->state, 0x40002, 0x40002, + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); + /* 2 damage clips, one intersect plane src. */ + set_damage_clip(&damage[0], 20, 30, 200, 180); + set_damage_clip(&damage[1], 2, 2, 1360, 1360); + set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); + set_plane_damage(&mock->state, &damage_blob); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) { + if (num_hits == 0) + check_damage_clip(test, &clip, 20, 30, 200, 180); + if (num_hits == 1) + check_damage_clip(test, &clip, 4, 4, 1029, 773); + num_hits++; + } + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 2, "Should return damage when set."); +} + +static void igt_damage_iter_damage_one_outside(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_property_blob damage_blob; + struct drm_mode_rect damage[2]; + struct drm_rect clip; + uint32_t num_hits = 0; + + set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16); + set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16); + /* 2 damage clips, one outside plane src. */ + set_damage_clip(&damage[0], 1360, 1360, 1380, 1380); + set_damage_clip(&damage[1], 240, 200, 280, 250); + set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); + set_plane_damage(&mock->state, &damage_blob); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set."); + check_damage_clip(test, &clip, 240, 200, 280, 250); +} + +static void igt_damage_iter_damage_src_moved(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_property_blob damage_blob; + struct drm_mode_rect damage[2]; + struct drm_rect clip; + uint32_t num_hits = 0; + + set_plane_src(&mock->old_state, 0x40002, 0x40002, + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); + set_plane_src(&mock->state, 0x3fffe, 0x3fffe, + 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); + /* 2 damage clips, one outside plane src. */ + set_damage_clip(&damage[0], 1360, 1360, 1380, 1380); + set_damage_clip(&damage[1], 240, 200, 280, 250); + set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); + set_plane_damage(&mock->state, &damage_blob); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, + "Should return round off plane src as damage."); + check_damage_clip(test, &clip, 3, 3, 1028, 772); +} + +static void igt_damage_iter_damage_not_visible(struct kunit *test) +{ + struct drm_damage_mock *mock = test->priv; + struct drm_atomic_helper_damage_iter iter; + struct drm_property_blob damage_blob; + struct drm_mode_rect damage[2]; + struct drm_rect clip; + uint32_t num_hits = 0; + + mock->state.visible = false; + + set_plane_src(&mock->old_state, 0x40002, 0x40002, + 0x40002 + (1024 << 16), 0x40002 + (768 << 16)); + set_plane_src(&mock->state, 0x3fffe, 0x3fffe, + 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16)); + /* 2 damage clips, one outside plane src. */ + set_damage_clip(&damage[0], 1360, 1360, 1380, 1380); + set_damage_clip(&damage[1], 240, 200, 280, 250); + set_damage_blob(&damage_blob, &damage[0], sizeof(damage)); + set_plane_damage(&mock->state, &damage_blob); + drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state); + drm_atomic_for_each_plane_damage(&iter, &clip) + num_hits++; + + KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should not return any damage."); +} + +static struct kunit_case drm_damage_helper_tests[] = { + KUNIT_CASE(igt_damage_iter_no_damage), + KUNIT_CASE(igt_damage_iter_no_damage_fractional_src), + KUNIT_CASE(igt_damage_iter_no_damage_src_moved), + KUNIT_CASE(igt_damage_iter_no_damage_fractional_src_moved), + KUNIT_CASE(igt_damage_iter_no_damage_not_visible), + KUNIT_CASE(igt_damage_iter_no_damage_no_crtc), + KUNIT_CASE(igt_damage_iter_no_damage_no_fb), + KUNIT_CASE(igt_damage_iter_simple_damage), + KUNIT_CASE(igt_damage_iter_single_damage), + KUNIT_CASE(igt_damage_iter_single_damage_intersect_src), + KUNIT_CASE(igt_damage_iter_single_damage_outside_src), + KUNIT_CASE(igt_damage_iter_single_damage_fractional_src), + KUNIT_CASE(igt_damage_iter_single_damage_intersect_fractional_src), + KUNIT_CASE(igt_damage_iter_single_damage_outside_fractional_src), + KUNIT_CASE(igt_damage_iter_single_damage_src_moved), + KUNIT_CASE(igt_damage_iter_single_damage_fractional_src_moved), + KUNIT_CASE(igt_damage_iter_damage), + KUNIT_CASE(igt_damage_iter_damage_one_intersect), + KUNIT_CASE(igt_damage_iter_damage_one_outside), + KUNIT_CASE(igt_damage_iter_damage_src_moved), + KUNIT_CASE(igt_damage_iter_damage_not_visible), + { } +}; + +static struct kunit_suite drm_damage_helper_test_suite = { + .name = "drm_damage_helper", + .init = drm_damage_helper_init, + .test_cases = drm_damage_helper_tests, +}; + +kunit_test_suite(drm_damage_helper_test_suite); + +MODULE_LICENSE("GPL");
Considering the current adoption of the KUnit framework, convert the DRM cmdline parser selftest to the KUnit API.
Tested-by: David Gow davidgow@google.com Co-developed-by: Arthur Grillo arthur.grillo@usp.br Signed-off-by: Arthur Grillo arthur.grillo@usp.br Signed-off-by: Maíra Canal maira.canal@usp.br --- drivers/gpu/drm/selftests/Makefile | 2 +- .../gpu/drm/selftests/drm_cmdline_selftests.h | 68 - .../drm/selftests/test-drm_cmdline_parser.c | 1141 ----------------- drivers/gpu/drm/tests/Makefile | 2 +- .../gpu/drm/tests/drm_cmdline_parser_test.c | 1078 ++++++++++++++++ 5 files changed, 1080 insertions(+), 1211 deletions(-) delete mode 100644 drivers/gpu/drm/selftests/drm_cmdline_selftests.h delete mode 100644 drivers/gpu/drm/selftests/test-drm_cmdline_parser.c create mode 100644 drivers/gpu/drm/tests/drm_cmdline_parser_test.c
diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index 7a1a732e0a1b..8633bb9ea717 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -3,5 +3,5 @@ test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ test-drm_format.o test-drm_framebuffer.o \ test-drm_dp_mst_helper.o test-drm_rect.o
-obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o test-drm_cmdline_parser.o \ +obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o \ test-drm_buddy.o diff --git a/drivers/gpu/drm/selftests/drm_cmdline_selftests.h b/drivers/gpu/drm/selftests/drm_cmdline_selftests.h deleted file mode 100644 index 29e367db6118..000000000000 --- a/drivers/gpu/drm/selftests/drm_cmdline_selftests.h +++ /dev/null @@ -1,68 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* List each unit test as selftest(function) - * - * The name is used as both an enum and expanded as igt__name to create - * a module parameter. It must be unique and legal for a C identifier. - * - * Tests are executed in order by igt/drm_mm - */ - -#define cmdline_test(test) selftest(test, test) - -cmdline_test(drm_cmdline_test_force_d_only) -cmdline_test(drm_cmdline_test_force_D_only_dvi) -cmdline_test(drm_cmdline_test_force_D_only_hdmi) -cmdline_test(drm_cmdline_test_force_D_only_not_digital) -cmdline_test(drm_cmdline_test_force_e_only) -cmdline_test(drm_cmdline_test_margin_only) -cmdline_test(drm_cmdline_test_interlace_only) -cmdline_test(drm_cmdline_test_res) -cmdline_test(drm_cmdline_test_res_missing_x) -cmdline_test(drm_cmdline_test_res_missing_y) -cmdline_test(drm_cmdline_test_res_bad_y) -cmdline_test(drm_cmdline_test_res_missing_y_bpp) -cmdline_test(drm_cmdline_test_res_vesa) -cmdline_test(drm_cmdline_test_res_vesa_rblank) -cmdline_test(drm_cmdline_test_res_rblank) -cmdline_test(drm_cmdline_test_res_bpp) -cmdline_test(drm_cmdline_test_res_bad_bpp) -cmdline_test(drm_cmdline_test_res_refresh) -cmdline_test(drm_cmdline_test_res_bad_refresh) -cmdline_test(drm_cmdline_test_res_bpp_refresh) -cmdline_test(drm_cmdline_test_res_bpp_refresh_interlaced) -cmdline_test(drm_cmdline_test_res_bpp_refresh_margins) -cmdline_test(drm_cmdline_test_res_bpp_refresh_force_off) -cmdline_test(drm_cmdline_test_res_bpp_refresh_force_on_off) -cmdline_test(drm_cmdline_test_res_bpp_refresh_force_on) -cmdline_test(drm_cmdline_test_res_bpp_refresh_force_on_analog) -cmdline_test(drm_cmdline_test_res_bpp_refresh_force_on_digital) -cmdline_test(drm_cmdline_test_res_bpp_refresh_interlaced_margins_force_on) -cmdline_test(drm_cmdline_test_res_margins_force_on) -cmdline_test(drm_cmdline_test_res_vesa_margins) -cmdline_test(drm_cmdline_test_res_invalid_mode) -cmdline_test(drm_cmdline_test_res_bpp_wrong_place_mode) -cmdline_test(drm_cmdline_test_name) -cmdline_test(drm_cmdline_test_name_bpp) -cmdline_test(drm_cmdline_test_name_refresh) -cmdline_test(drm_cmdline_test_name_bpp_refresh) -cmdline_test(drm_cmdline_test_name_refresh_wrong_mode) -cmdline_test(drm_cmdline_test_name_refresh_invalid_mode) -cmdline_test(drm_cmdline_test_name_option) -cmdline_test(drm_cmdline_test_name_bpp_option) -cmdline_test(drm_cmdline_test_rotate_0) -cmdline_test(drm_cmdline_test_rotate_90) -cmdline_test(drm_cmdline_test_rotate_180) -cmdline_test(drm_cmdline_test_rotate_270) -cmdline_test(drm_cmdline_test_rotate_multiple) -cmdline_test(drm_cmdline_test_rotate_invalid_val) -cmdline_test(drm_cmdline_test_rotate_truncated) -cmdline_test(drm_cmdline_test_hmirror) -cmdline_test(drm_cmdline_test_vmirror) -cmdline_test(drm_cmdline_test_margin_options) -cmdline_test(drm_cmdline_test_multiple_options) -cmdline_test(drm_cmdline_test_invalid_option) -cmdline_test(drm_cmdline_test_bpp_extra_and_option) -cmdline_test(drm_cmdline_test_extra_and_option) -cmdline_test(drm_cmdline_test_freestanding_options) -cmdline_test(drm_cmdline_test_freestanding_force_e_and_options) -cmdline_test(drm_cmdline_test_panel_orientation) diff --git a/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c b/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c deleted file mode 100644 index d96cd890def6..000000000000 --- a/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c +++ /dev/null @@ -1,1141 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (c) 2019 Bootlin - */ - -#define pr_fmt(fmt) "drm_cmdline: " fmt - -#include <linux/kernel.h> -#include <linux/module.h> - -#include <drm/drm_connector.h> -#include <drm/drm_modes.h> - -#define TESTS "drm_cmdline_selftests.h" -#include "drm_selftest.h" -#include "test-drm_modeset_common.h" - -static const struct drm_connector no_connector = {}; - -static int drm_cmdline_test_force_e_only(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("e", - &no_connector, - &mode)); - FAIL_ON(mode.specified); - FAIL_ON(mode.refresh_specified); - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON); - - return 0; -} - -static int drm_cmdline_test_force_D_only_not_digital(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("D", - &no_connector, - &mode)); - FAIL_ON(mode.specified); - FAIL_ON(mode.refresh_specified); - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON); - - return 0; -} - -static const struct drm_connector connector_hdmi = { - .connector_type = DRM_MODE_CONNECTOR_HDMIB, -}; - -static int drm_cmdline_test_force_D_only_hdmi(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("D", - &connector_hdmi, - &mode)); - FAIL_ON(mode.specified); - FAIL_ON(mode.refresh_specified); - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON_DIGITAL); - - return 0; -} - -static const struct drm_connector connector_dvi = { - .connector_type = DRM_MODE_CONNECTOR_DVII, -}; - -static int drm_cmdline_test_force_D_only_dvi(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("D", - &connector_dvi, - &mode)); - FAIL_ON(mode.specified); - FAIL_ON(mode.refresh_specified); - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON_DIGITAL); - - return 0; -} - -static int drm_cmdline_test_force_d_only(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("d", - &no_connector, - &mode)); - FAIL_ON(mode.specified); - FAIL_ON(mode.refresh_specified); - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_OFF); - - return 0; -} - -static int drm_cmdline_test_margin_only(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("m", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_interlace_only(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("i", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_res(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_res_missing_x(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("x480", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_res_missing_y(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("1024x", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_res_bad_y(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("1024xtest", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_res_missing_y_bpp(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("1024x-24", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_res_vesa(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480M", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(!mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_res_vesa_rblank(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480MR", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(!mode.rb); - FAIL_ON(!mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_res_rblank(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480R", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(!mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_res_bpp(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(!mode.bpp_specified); - FAIL_ON(mode.bpp != 24); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_res_bad_bpp(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("720x480-test", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_res_refresh(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480@60", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(!mode.refresh_specified); - FAIL_ON(mode.refresh != 60); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_res_bad_refresh(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("720x480@refresh", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_res_bpp_refresh(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(!mode.refresh_specified); - FAIL_ON(mode.refresh != 60); - - FAIL_ON(!mode.bpp_specified); - FAIL_ON(mode.bpp != 24); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_res_bpp_refresh_interlaced(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60i", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(!mode.refresh_specified); - FAIL_ON(mode.refresh != 60); - - FAIL_ON(!mode.bpp_specified); - FAIL_ON(mode.bpp != 24); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(!mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_res_bpp_refresh_margins(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60m", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(!mode.refresh_specified); - FAIL_ON(mode.refresh != 60); - - FAIL_ON(!mode.bpp_specified); - FAIL_ON(mode.bpp != 24); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(!mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_res_bpp_refresh_force_off(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60d", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(!mode.refresh_specified); - FAIL_ON(mode.refresh != 60); - - FAIL_ON(!mode.bpp_specified); - FAIL_ON(mode.bpp != 24); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_OFF); - - return 0; -} - -static int drm_cmdline_test_res_bpp_refresh_force_on_off(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("720x480-24@60de", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_res_bpp_refresh_force_on(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60e", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(!mode.refresh_specified); - FAIL_ON(mode.refresh != 60); - - FAIL_ON(!mode.bpp_specified); - FAIL_ON(mode.bpp != 24); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON); - - return 0; -} - -static int drm_cmdline_test_res_bpp_refresh_force_on_analog(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60D", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(!mode.refresh_specified); - FAIL_ON(mode.refresh != 60); - - FAIL_ON(!mode.bpp_specified); - FAIL_ON(mode.bpp != 24); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON); - - return 0; -} - -static int drm_cmdline_test_res_bpp_refresh_force_on_digital(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - static const struct drm_connector connector = { - .connector_type = DRM_MODE_CONNECTOR_DVII, - }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60D", - &connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(!mode.refresh_specified); - FAIL_ON(mode.refresh != 60); - - FAIL_ON(!mode.bpp_specified); - FAIL_ON(mode.bpp != 24); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON_DIGITAL); - - return 0; -} - -static int drm_cmdline_test_res_bpp_refresh_interlaced_margins_force_on(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60ime", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(!mode.refresh_specified); - FAIL_ON(mode.refresh != 60); - - FAIL_ON(!mode.bpp_specified); - FAIL_ON(mode.bpp != 24); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(!mode.interlace); - FAIL_ON(!mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON); - - return 0; -} - -static int drm_cmdline_test_res_margins_force_on(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480me", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(!mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON); - - return 0; -} - -static int drm_cmdline_test_res_vesa_margins(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480Mm", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(!mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(!mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_res_invalid_mode(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("720x480f", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_res_bpp_wrong_place_mode(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("720x480e-24", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_name(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("NTSC", - &no_connector, - &mode)); - FAIL_ON(strcmp(mode.name, "NTSC")); - FAIL_ON(mode.refresh_specified); - FAIL_ON(mode.bpp_specified); - - return 0; -} - -static int drm_cmdline_test_name_bpp(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("NTSC-24", - &no_connector, - &mode)); - FAIL_ON(strcmp(mode.name, "NTSC")); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(!mode.bpp_specified); - FAIL_ON(mode.bpp != 24); - - return 0; -} - -static int drm_cmdline_test_name_bpp_refresh(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("NTSC-24@60", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_name_refresh(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("NTSC@60", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_name_refresh_wrong_mode(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("NTSC@60m", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_name_refresh_invalid_mode(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("NTSC@60f", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_name_option(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("NTSC,rotate=180", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(strcmp(mode.name, "NTSC")); - FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_180); - - return 0; -} - -static int drm_cmdline_test_name_bpp_option(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("NTSC-24,rotate=180", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(strcmp(mode.name, "NTSC")); - FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_180); - FAIL_ON(!mode.bpp_specified); - FAIL_ON(mode.bpp != 24); - - return 0; -} - -static int drm_cmdline_test_rotate_0(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=0", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_0); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_rotate_90(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=90", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_90); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_rotate_180(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=180", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_180); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_rotate_270(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=270", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_270); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_rotate_multiple(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("720x480,rotate=0,rotate=90", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_rotate_invalid_val(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("720x480,rotate=42", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_rotate_truncated(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("720x480,rotate=", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_hmirror(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,reflect_x", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - FAIL_ON(mode.rotation_reflection != (DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_X)); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_vmirror(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,reflect_y", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - FAIL_ON(mode.rotation_reflection != (DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y)); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_margin_options(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,margin_right=14,margin_left=24,margin_bottom=36,margin_top=42", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - FAIL_ON(mode.tv_margins.right != 14); - FAIL_ON(mode.tv_margins.left != 24); - FAIL_ON(mode.tv_margins.bottom != 36); - FAIL_ON(mode.tv_margins.top != 42); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_multiple_options(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=270,reflect_x", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - FAIL_ON(mode.rotation_reflection != (DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_X)); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_invalid_option(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(drm_mode_parse_command_line_for_connector("720x480,test=42", - &no_connector, - &mode)); - - return 0; -} - -static int drm_cmdline_test_bpp_extra_and_option(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24e,rotate=180", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_180); - - FAIL_ON(mode.refresh_specified); - - FAIL_ON(!mode.bpp_specified); - FAIL_ON(mode.bpp != 24); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON); - - return 0; -} - -static int drm_cmdline_test_extra_and_option(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480e,rotate=180", - &no_connector, - &mode)); - FAIL_ON(!mode.specified); - FAIL_ON(mode.xres != 720); - FAIL_ON(mode.yres != 480); - FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_180); - - FAIL_ON(mode.refresh_specified); - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON); - - return 0; -} - -static int drm_cmdline_test_freestanding_options(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("margin_right=14,margin_left=24,margin_bottom=36,margin_top=42", - &no_connector, - &mode)); - FAIL_ON(mode.specified); - FAIL_ON(mode.refresh_specified); - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.tv_margins.right != 14); - FAIL_ON(mode.tv_margins.left != 24); - FAIL_ON(mode.tv_margins.bottom != 36); - FAIL_ON(mode.tv_margins.top != 42); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -static int drm_cmdline_test_freestanding_force_e_and_options(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("e,margin_right=14,margin_left=24,margin_bottom=36,margin_top=42", - &no_connector, - &mode)); - FAIL_ON(mode.specified); - FAIL_ON(mode.refresh_specified); - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.tv_margins.right != 14); - FAIL_ON(mode.tv_margins.left != 24); - FAIL_ON(mode.tv_margins.bottom != 36); - FAIL_ON(mode.tv_margins.top != 42); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_ON); - - return 0; -} - -static int drm_cmdline_test_panel_orientation(void *ignored) -{ - struct drm_cmdline_mode mode = { }; - - FAIL_ON(!drm_mode_parse_command_line_for_connector("panel_orientation=upside_down", - &no_connector, - &mode)); - FAIL_ON(mode.specified); - FAIL_ON(mode.refresh_specified); - FAIL_ON(mode.bpp_specified); - - FAIL_ON(mode.panel_orientation != DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP); - - FAIL_ON(mode.rb); - FAIL_ON(mode.cvt); - FAIL_ON(mode.interlace); - FAIL_ON(mode.margins); - FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); - - return 0; -} - -#include "drm_selftest.c" - -static int __init test_drm_cmdline_init(void) -{ - int err; - - err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL); - - return err > 0 ? 0 : err; -} -module_init(test_drm_cmdline_init); - -MODULE_AUTHOR("Maxime Ripard maxime.ripard@bootlin.com"); -MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index 181ac2c9977a..f9929ac10765 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_DRM_KUNIT_TEST) += drm_damage_helper_test.o +obj-$(CONFIG_DRM_KUNIT_TEST) += drm_damage_helper_test.o drm_cmdline_parser_test.o diff --git a/drivers/gpu/drm/tests/drm_cmdline_parser_test.c b/drivers/gpu/drm/tests/drm_cmdline_parser_test.c new file mode 100644 index 000000000000..ca7669350c64 --- /dev/null +++ b/drivers/gpu/drm/tests/drm_cmdline_parser_test.c @@ -0,0 +1,1078 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 Bootlin + */ + +#include <kunit/test.h> +#include <drm/drm_connector.h> +#include <drm/drm_modes.h> + +static const struct drm_connector no_connector = {}; + +static void drm_cmdline_test_force_e_only(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("e", + &no_connector, + &mode)); + KUNIT_EXPECT_FALSE(test, mode.specified); + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON); +} + +static void drm_cmdline_test_force_D_only_not_digital(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("D", + &no_connector, + &mode)); + KUNIT_EXPECT_FALSE(test, mode.specified); + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON); +} + +static const struct drm_connector connector_hdmi = { + .connector_type = DRM_MODE_CONNECTOR_HDMIB, +}; + +static void drm_cmdline_test_force_D_only_hdmi(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("D", + &connector_hdmi, + &mode)); + KUNIT_EXPECT_FALSE(test, mode.specified); + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON_DIGITAL); +} + +static const struct drm_connector connector_dvi = { + .connector_type = DRM_MODE_CONNECTOR_DVII, +}; + +static void drm_cmdline_test_force_D_only_dvi(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("D", + &connector_dvi, + &mode)); + KUNIT_EXPECT_FALSE(test, mode.specified); + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON_DIGITAL); +} + +static void drm_cmdline_test_force_d_only(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("d", + &no_connector, + &mode)); + KUNIT_EXPECT_FALSE(test, mode.specified); + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_OFF); +} + +static void drm_cmdline_test_margin_only(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("m", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_interlace_only(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("i", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_res(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_res_missing_x(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("x480", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_res_missing_y(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("1024x", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_res_bad_y(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("1024xtest", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_res_missing_y_bpp(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("1024x-24", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_res_vesa(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480M", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_TRUE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_res_vesa_rblank(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480MR", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_TRUE(test, mode.rb); + KUNIT_EXPECT_TRUE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_res_rblank(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480R", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_TRUE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_res_bpp(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480-24", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_TRUE(test, mode.bpp_specified); + KUNIT_EXPECT_EQ(test, mode.bpp, 24); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_res_bad_bpp(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("720x480-test", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_res_refresh(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480@60", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_TRUE(test, mode.refresh_specified); + KUNIT_EXPECT_EQ(test, mode.refresh, 60); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_res_bad_refresh(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("720x480@refresh", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_res_bpp_refresh(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480-24@60", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_TRUE(test, mode.refresh_specified); + KUNIT_EXPECT_EQ(test, mode.refresh, 60); + + KUNIT_EXPECT_TRUE(test, mode.bpp_specified); + KUNIT_EXPECT_EQ(test, mode.bpp, 24); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_res_bpp_refresh_interlaced(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480-24@60i", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_TRUE(test, mode.refresh_specified); + KUNIT_EXPECT_EQ(test, mode.refresh, 60); + + KUNIT_EXPECT_TRUE(test, mode.bpp_specified); + KUNIT_EXPECT_EQ(test, mode.bpp, 24); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_TRUE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_res_bpp_refresh_margins(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480-24@60m", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_TRUE(test, mode.refresh_specified); + KUNIT_EXPECT_EQ(test, mode.refresh, 60); + + KUNIT_EXPECT_TRUE(test, mode.bpp_specified); + KUNIT_EXPECT_EQ(test, mode.bpp, 24); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_TRUE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_res_bpp_refresh_force_off(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480-24@60d", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_TRUE(test, mode.refresh_specified); + KUNIT_EXPECT_EQ(test, mode.refresh, 60); + + KUNIT_EXPECT_TRUE(test, mode.bpp_specified); + KUNIT_EXPECT_EQ(test, mode.bpp, 24); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_OFF); +} + +static void drm_cmdline_test_res_bpp_refresh_force_on_off(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("720x480-24@60de", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_res_bpp_refresh_force_on(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480-24@60e", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_TRUE(test, mode.refresh_specified); + KUNIT_EXPECT_EQ(test, mode.refresh, 60); + + KUNIT_EXPECT_TRUE(test, mode.bpp_specified); + KUNIT_EXPECT_EQ(test, mode.bpp, 24); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON); +} + +static void drm_cmdline_test_res_bpp_refresh_force_on_analog(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480-24@60D", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_TRUE(test, mode.refresh_specified); + KUNIT_EXPECT_EQ(test, mode.refresh, 60); + + KUNIT_EXPECT_TRUE(test, mode.bpp_specified); + KUNIT_EXPECT_EQ(test, mode.bpp, 24); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON); +} + +static void drm_cmdline_test_res_bpp_refresh_force_on_digital(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + static const struct drm_connector connector = { + .connector_type = DRM_MODE_CONNECTOR_DVII, + }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480-24@60D", + &connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_TRUE(test, mode.refresh_specified); + KUNIT_EXPECT_EQ(test, mode.refresh, 60); + + KUNIT_EXPECT_TRUE(test, mode.bpp_specified); + KUNIT_EXPECT_EQ(test, mode.bpp, 24); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON_DIGITAL); +} + +static void drm_cmdline_test_res_bpp_refresh_interlaced_margins_force_on(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480-24@60ime", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_TRUE(test, mode.refresh_specified); + KUNIT_EXPECT_EQ(test, mode.refresh, 60); + + KUNIT_EXPECT_TRUE(test, mode.bpp_specified); + KUNIT_EXPECT_EQ(test, mode.bpp, 24); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_TRUE(test, mode.interlace); + KUNIT_EXPECT_TRUE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON); +} + +static void drm_cmdline_test_res_margins_force_on(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480me", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_TRUE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON); +} + +static void drm_cmdline_test_res_vesa_margins(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480Mm", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_TRUE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_TRUE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_res_invalid_mode(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("720x480f", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_res_bpp_wrong_place_mode(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("720x480e-24", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_name(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("NTSC", + &no_connector, + &mode)); + KUNIT_EXPECT_STREQ(test, mode.name, "NTSC"); + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); +} + +static void drm_cmdline_test_name_bpp(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("NTSC-24", + &no_connector, + &mode)); + KUNIT_EXPECT_STREQ(test, mode.name, "NTSC"); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_TRUE(test, mode.bpp_specified); + KUNIT_EXPECT_EQ(test, mode.bpp, 24); +} + +static void drm_cmdline_test_name_bpp_refresh(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("NTSC-24@60", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_name_refresh(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("NTSC@60", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_name_refresh_wrong_mode(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("NTSC@60m", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_name_refresh_invalid_mode(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("NTSC@60f", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_name_option(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("NTSC,rotate=180", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_STREQ(test, mode.name, "NTSC"); + KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_180); +} + +static void drm_cmdline_test_name_bpp_option(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("NTSC-24,rotate=180", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_STREQ(test, mode.name, "NTSC"); + KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_180); + KUNIT_EXPECT_TRUE(test, mode.bpp_specified); + KUNIT_EXPECT_EQ(test, mode.bpp, 24); +} + +static void drm_cmdline_test_rotate_0(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480,rotate=0", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_0); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_rotate_90(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480,rotate=90", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_90); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_rotate_180(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480,rotate=180", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_180); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_rotate_270(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480,rotate=270", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_270); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_rotate_multiple(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("720x480,rotate=0,rotate=90", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_rotate_invalid_val(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("720x480,rotate=42", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_rotate_truncated(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("720x480,rotate=", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_hmirror(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480,reflect_x", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + KUNIT_EXPECT_EQ(test, mode.rotation_reflection, (DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_X)); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_vmirror(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480,reflect_y", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + KUNIT_EXPECT_EQ(test, mode.rotation_reflection, (DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y)); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_margin_options(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector( + "720x480,margin_right=14,margin_left=24,margin_bottom=36,margin_top=42", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + KUNIT_EXPECT_EQ(test, mode.tv_margins.right, 14); + KUNIT_EXPECT_EQ(test, mode.tv_margins.left, 24); + KUNIT_EXPECT_EQ(test, mode.tv_margins.bottom, 36); + KUNIT_EXPECT_EQ(test, mode.tv_margins.top, 42); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_multiple_options(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480,rotate=270,reflect_x", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + KUNIT_EXPECT_EQ(test, mode.rotation_reflection, (DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_X)); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_invalid_option(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_FALSE(test, drm_mode_parse_command_line_for_connector("720x480,test=42", + &no_connector, + &mode)); +} + +static void drm_cmdline_test_bpp_extra_and_option(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480-24e,rotate=180", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_180); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + + KUNIT_EXPECT_TRUE(test, mode.bpp_specified); + KUNIT_EXPECT_EQ(test, mode.bpp, 24); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON); +} + +static void drm_cmdline_test_extra_and_option(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("720x480e,rotate=180", + &no_connector, + &mode)); + KUNIT_EXPECT_TRUE(test, mode.specified); + KUNIT_EXPECT_EQ(test, mode.xres, 720); + KUNIT_EXPECT_EQ(test, mode.yres, 480); + KUNIT_EXPECT_EQ(test, mode.rotation_reflection, DRM_MODE_ROTATE_180); + + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON); +} + +static void drm_cmdline_test_freestanding_options(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector( + "margin_right=14,margin_left=24,margin_bottom=36,margin_top=42", + &no_connector, + &mode)); + KUNIT_EXPECT_FALSE(test, mode.specified); + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_EQ(test, mode.tv_margins.right, 14); + KUNIT_EXPECT_EQ(test, mode.tv_margins.left, 24); + KUNIT_EXPECT_EQ(test, mode.tv_margins.bottom, 36); + KUNIT_EXPECT_EQ(test, mode.tv_margins.top, 42); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static void drm_cmdline_test_freestanding_force_e_and_options(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector( + "e,margin_right=14,margin_left=24,margin_bottom=36,margin_top=42", + &no_connector, + &mode)); + KUNIT_EXPECT_FALSE(test, mode.specified); + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_EQ(test, mode.tv_margins.right, 14); + KUNIT_EXPECT_EQ(test, mode.tv_margins.left, 24); + KUNIT_EXPECT_EQ(test, mode.tv_margins.bottom, 36); + KUNIT_EXPECT_EQ(test, mode.tv_margins.top, 42); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_ON); +} + +static void drm_cmdline_test_panel_orientation(struct kunit *test) +{ + struct drm_cmdline_mode mode = { }; + + KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector("panel_orientation=upside_down", + &no_connector, + &mode)); + KUNIT_EXPECT_FALSE(test, mode.specified); + KUNIT_EXPECT_FALSE(test, mode.refresh_specified); + KUNIT_EXPECT_FALSE(test, mode.bpp_specified); + + KUNIT_EXPECT_EQ(test, mode.panel_orientation, DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP); + + KUNIT_EXPECT_FALSE(test, mode.rb); + KUNIT_EXPECT_FALSE(test, mode.cvt); + KUNIT_EXPECT_FALSE(test, mode.interlace); + KUNIT_EXPECT_FALSE(test, mode.margins); + KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED); +} + +static struct kunit_case drm_cmdline_parser_tests[] = { + KUNIT_CASE(drm_cmdline_test_force_d_only), + KUNIT_CASE(drm_cmdline_test_force_D_only_dvi), + KUNIT_CASE(drm_cmdline_test_force_D_only_hdmi), + KUNIT_CASE(drm_cmdline_test_force_D_only_not_digital), + KUNIT_CASE(drm_cmdline_test_force_e_only), + KUNIT_CASE(drm_cmdline_test_margin_only), + KUNIT_CASE(drm_cmdline_test_interlace_only), + KUNIT_CASE(drm_cmdline_test_res), + KUNIT_CASE(drm_cmdline_test_res_missing_x), + KUNIT_CASE(drm_cmdline_test_res_missing_y), + KUNIT_CASE(drm_cmdline_test_res_bad_y), + KUNIT_CASE(drm_cmdline_test_res_missing_y_bpp), + KUNIT_CASE(drm_cmdline_test_res_vesa), + KUNIT_CASE(drm_cmdline_test_res_vesa_rblank), + KUNIT_CASE(drm_cmdline_test_res_rblank), + KUNIT_CASE(drm_cmdline_test_res_bpp), + KUNIT_CASE(drm_cmdline_test_res_bad_bpp), + KUNIT_CASE(drm_cmdline_test_res_refresh), + KUNIT_CASE(drm_cmdline_test_res_bad_refresh), + KUNIT_CASE(drm_cmdline_test_res_bpp_refresh), + KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_interlaced), + KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_margins), + KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_force_off), + KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_force_on_off), + KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_force_on), + KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_force_on_analog), + KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_force_on_digital), + KUNIT_CASE(drm_cmdline_test_res_bpp_refresh_interlaced_margins_force_on), + KUNIT_CASE(drm_cmdline_test_res_margins_force_on), + KUNIT_CASE(drm_cmdline_test_res_vesa_margins), + KUNIT_CASE(drm_cmdline_test_res_invalid_mode), + KUNIT_CASE(drm_cmdline_test_res_bpp_wrong_place_mode), + KUNIT_CASE(drm_cmdline_test_name), + KUNIT_CASE(drm_cmdline_test_name_bpp), + KUNIT_CASE(drm_cmdline_test_name_refresh), + KUNIT_CASE(drm_cmdline_test_name_bpp_refresh), + KUNIT_CASE(drm_cmdline_test_name_refresh_wrong_mode), + KUNIT_CASE(drm_cmdline_test_name_refresh_invalid_mode), + KUNIT_CASE(drm_cmdline_test_name_option), + KUNIT_CASE(drm_cmdline_test_name_bpp_option), + KUNIT_CASE(drm_cmdline_test_rotate_0), + KUNIT_CASE(drm_cmdline_test_rotate_90), + KUNIT_CASE(drm_cmdline_test_rotate_180), + KUNIT_CASE(drm_cmdline_test_rotate_270), + KUNIT_CASE(drm_cmdline_test_rotate_multiple), + KUNIT_CASE(drm_cmdline_test_rotate_invalid_val), + KUNIT_CASE(drm_cmdline_test_rotate_truncated), + KUNIT_CASE(drm_cmdline_test_hmirror), + KUNIT_CASE(drm_cmdline_test_vmirror), + KUNIT_CASE(drm_cmdline_test_margin_options), + KUNIT_CASE(drm_cmdline_test_multiple_options), + KUNIT_CASE(drm_cmdline_test_invalid_option), + KUNIT_CASE(drm_cmdline_test_bpp_extra_and_option), + KUNIT_CASE(drm_cmdline_test_extra_and_option), + KUNIT_CASE(drm_cmdline_test_freestanding_options), + KUNIT_CASE(drm_cmdline_test_freestanding_force_e_and_options), + KUNIT_CASE(drm_cmdline_test_panel_orientation), + {} +}; + +static struct kunit_suite drm_cmdline_parser_test_suite = { + .name = "drm_cmdline_parser", + .test_cases = drm_cmdline_parser_tests +}; + +kunit_test_suite(drm_cmdline_parser_test_suite); + +MODULE_AUTHOR("Maxime Ripard maxime.ripard@bootlin.com"); +MODULE_LICENSE("GPL");
Considering the current adoption of the KUnit framework, convert the DRM rect selftest to the KUnit API.
Tested-by: David Gow davidgow@google.com Co-developed-by: Carlos Veras carlos.craveiro@usp.br Signed-off-by: Carlos Veras carlos.craveiro@usp.br Co-developed-by: Matheus Vieira matheus.vieira.g@usp.br Signed-off-by: Matheus Vieira matheus.vieira.g@usp.br Signed-off-by: Maíra Canal maira.canal@usp.br --- drivers/gpu/drm/selftests/Makefile | 2 +- .../gpu/drm/selftests/drm_modeset_selftests.h | 4 - .../drm/selftests/test-drm_modeset_common.h | 4 - drivers/gpu/drm/tests/Makefile | 3 +- .../test-drm_rect.c => tests/drm_rect_test.c} | 124 +++++++++--------- 5 files changed, 68 insertions(+), 69 deletions(-) rename drivers/gpu/drm/{selftests/test-drm_rect.c => tests/drm_rect_test.c} (53%)
diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index 8633bb9ea717..8a794914e328 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ test-drm_format.o test-drm_framebuffer.o \ - test-drm_dp_mst_helper.o test-drm_rect.o + test-drm_dp_mst_helper.o
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o \ test-drm_buddy.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h index 4787b3b70709..a3ca90307364 100644 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h @@ -6,10 +6,6 @@ * * Tests are executed in order by igt/drm_selftests_helper */ -selftest(drm_rect_clip_scaled_div_by_zero, igt_drm_rect_clip_scaled_div_by_zero) -selftest(drm_rect_clip_scaled_not_clipped, igt_drm_rect_clip_scaled_not_clipped) -selftest(drm_rect_clip_scaled_clipped, igt_drm_rect_clip_scaled_clipped) -selftest(drm_rect_clip_scaled_signed_vs_unsigned, igt_drm_rect_clip_scaled_signed_vs_unsigned) selftest(check_plane_state, igt_check_plane_state) selftest(check_drm_format_block_width, igt_check_drm_format_block_width) selftest(check_drm_format_block_height, igt_check_drm_format_block_height) diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h index c29354e59cec..42a10d7da51c 100644 --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h @@ -16,10 +16,6 @@
#define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
-int igt_drm_rect_clip_scaled_div_by_zero(void *ignored); -int igt_drm_rect_clip_scaled_not_clipped(void *ignored); -int igt_drm_rect_clip_scaled_clipped(void *ignored); -int igt_drm_rect_clip_scaled_signed_vs_unsigned(void *ignored); int igt_check_plane_state(void *ignored); int igt_check_drm_format_block_width(void *ignored); int igt_check_drm_format_block_height(void *ignored); diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index f9929ac10765..d413fbe6d710 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_DRM_KUNIT_TEST) += drm_damage_helper_test.o drm_cmdline_parser_test.o +obj-$(CONFIG_DRM_KUNIT_TEST) += drm_damage_helper_test.o drm_cmdline_parser_test.o \ + drm_rect_test.o diff --git a/drivers/gpu/drm/selftests/test-drm_rect.c b/drivers/gpu/drm/tests/drm_rect_test.c similarity index 53% rename from drivers/gpu/drm/selftests/test-drm_rect.c rename to drivers/gpu/drm/tests/drm_rect_test.c index 3a5ff38321f4..314dab502e7e 100644 --- a/drivers/gpu/drm/selftests/test-drm_rect.c +++ b/drivers/gpu/drm/tests/drm_rect_test.c @@ -3,15 +3,10 @@ * Test cases for the drm_rect functions */
-#define pr_fmt(fmt) "drm_rect: " fmt - -#include <linux/limits.h> - +#include <kunit/test.h> #include <drm/drm_rect.h>
-#include "test-drm_modeset_common.h" - -int igt_drm_rect_clip_scaled_div_by_zero(void *ignored) +static void igt_drm_rect_clip_scaled_div_by_zero(struct kunit *test) { struct drm_rect src, dst, clip; bool visible; @@ -24,20 +19,20 @@ int igt_drm_rect_clip_scaled_div_by_zero(void *ignored) drm_rect_init(&dst, 0, 0, 0, 0); drm_rect_init(&clip, 1, 1, 1, 1); visible = drm_rect_clip_scaled(&src, &dst, &clip); - FAIL(visible, "Destination not be visible\n"); - FAIL(drm_rect_visible(&src), "Source should not be visible\n"); + + KUNIT_EXPECT_FALSE_MSG(test, visible, "Destination not be visible\n"); + KUNIT_EXPECT_FALSE_MSG(test, drm_rect_visible(&src), "Source should not be visible\n");
drm_rect_init(&src, 0, 0, 0, 0); drm_rect_init(&dst, 3, 3, 0, 0); drm_rect_init(&clip, 1, 1, 1, 1); visible = drm_rect_clip_scaled(&src, &dst, &clip); - FAIL(visible, "Destination not be visible\n"); - FAIL(drm_rect_visible(&src), "Source should not be visible\n");
- return 0; + KUNIT_EXPECT_FALSE_MSG(test, visible, "Destination not be visible\n"); + KUNIT_EXPECT_FALSE_MSG(test, drm_rect_visible(&src), "Source should not be visible\n"); }
-int igt_drm_rect_clip_scaled_not_clipped(void *ignored) +static void igt_drm_rect_clip_scaled_not_clipped(struct kunit *test) { struct drm_rect src, dst, clip; bool visible; @@ -49,14 +44,14 @@ int igt_drm_rect_clip_scaled_not_clipped(void *ignored)
visible = drm_rect_clip_scaled(&src, &dst, &clip);
- FAIL(src.x1 != 0 || src.x2 != 1 << 16 || + KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 || src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n"); - FAIL(dst.x1 != 0 || dst.x2 != 1 || + KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 || dst.y1 != 0 || dst.y2 != 1, "Destination badly clipped\n"); - FAIL(!visible, "Destination should be visible\n"); - FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
/* 2:1 scaling */ drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); @@ -65,14 +60,14 @@ int igt_drm_rect_clip_scaled_not_clipped(void *ignored)
visible = drm_rect_clip_scaled(&src, &dst, &clip);
- FAIL(src.x1 != 0 || src.x2 != 2 << 16 || + KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 2 << 16 || src.y1 != 0 || src.y2 != 2 << 16, "Source badly clipped\n"); - FAIL(dst.x1 != 0 || dst.x2 != 1 || + KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 || dst.y1 != 0 || dst.y2 != 1, "Destination badly clipped\n"); - FAIL(!visible, "Destination should be visible\n"); - FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
/* 1:2 scaling */ drm_rect_init(&src, 0, 0, 1 << 16, 1 << 16); @@ -81,19 +76,17 @@ int igt_drm_rect_clip_scaled_not_clipped(void *ignored)
visible = drm_rect_clip_scaled(&src, &dst, &clip);
- FAIL(src.x1 != 0 || src.x2 != 1 << 16 || + KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 || src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n"); - FAIL(dst.x1 != 0 || dst.x2 != 2 || + KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 2 || dst.y1 != 0 || dst.y2 != 2, "Destination badly clipped\n"); - FAIL(!visible, "Destination should be visible\n"); - FAIL(!drm_rect_visible(&src), "Source should be visible\n"); - - return 0; + KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); }
-int igt_drm_rect_clip_scaled_clipped(void *ignored) +static void igt_drm_rect_clip_scaled_clipped(struct kunit *test) { struct drm_rect src, dst, clip; bool visible; @@ -105,14 +98,14 @@ int igt_drm_rect_clip_scaled_clipped(void *ignored)
visible = drm_rect_clip_scaled(&src, &dst, &clip);
- FAIL(src.x1 != 0 || src.x2 != 1 << 16 || + KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 || src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n"); - FAIL(dst.x1 != 0 || dst.x2 != 1 || + KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 || dst.y1 != 0 || dst.y2 != 1, "Destination badly clipped\n"); - FAIL(!visible, "Destination should be visible\n"); - FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
/* 1:1 scaling bottom/right clip */ drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); @@ -121,14 +114,14 @@ int igt_drm_rect_clip_scaled_clipped(void *ignored)
visible = drm_rect_clip_scaled(&src, &dst, &clip);
- FAIL(src.x1 != 1 << 16 || src.x2 != 2 << 16 || + KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 1 << 16 || src.x2 != 2 << 16 || src.y1 != 1 << 16 || src.y2 != 2 << 16, "Source badly clipped\n"); - FAIL(dst.x1 != 1 || dst.x2 != 2 || + KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 1 || dst.x2 != 2 || dst.y1 != 1 || dst.y2 != 2, "Destination badly clipped\n"); - FAIL(!visible, "Destination should be visible\n"); - FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
/* 2:1 scaling top/left clip */ drm_rect_init(&src, 0, 0, 4 << 16, 4 << 16); @@ -137,14 +130,14 @@ int igt_drm_rect_clip_scaled_clipped(void *ignored)
visible = drm_rect_clip_scaled(&src, &dst, &clip);
- FAIL(src.x1 != 0 || src.x2 != 2 << 16 || + KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 2 << 16 || src.y1 != 0 || src.y2 != 2 << 16, "Source badly clipped\n"); - FAIL(dst.x1 != 0 || dst.x2 != 1 || + KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 || dst.y1 != 0 || dst.y2 != 1, "Destination badly clipped\n"); - FAIL(!visible, "Destination should be visible\n"); - FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
/* 2:1 scaling bottom/right clip */ drm_rect_init(&src, 0, 0, 4 << 16, 4 << 16); @@ -153,14 +146,14 @@ int igt_drm_rect_clip_scaled_clipped(void *ignored)
visible = drm_rect_clip_scaled(&src, &dst, &clip);
- FAIL(src.x1 != 2 << 16 || src.x2 != 4 << 16 || + KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 2 << 16 || src.x2 != 4 << 16 || src.y1 != 2 << 16 || src.y2 != 4 << 16, "Source badly clipped\n"); - FAIL(dst.x1 != 1 || dst.x2 != 2 || + KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 1 || dst.x2 != 2 || dst.y1 != 1 || dst.y2 != 2, "Destination badly clipped\n"); - FAIL(!visible, "Destination should be visible\n"); - FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
/* 1:2 scaling top/left clip */ drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); @@ -169,14 +162,14 @@ int igt_drm_rect_clip_scaled_clipped(void *ignored)
visible = drm_rect_clip_scaled(&src, &dst, &clip);
- FAIL(src.x1 != 0 || src.x2 != 1 << 16 || + KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 || src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n"); - FAIL(dst.x1 != 0 || dst.x2 != 2 || + KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 2 || dst.y1 != 0 || dst.y2 != 2, "Destination badly clipped\n"); - FAIL(!visible, "Destination should be visible\n"); - FAIL(!drm_rect_visible(&src), "Source should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
/* 1:2 scaling bottom/right clip */ drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); @@ -185,19 +178,17 @@ int igt_drm_rect_clip_scaled_clipped(void *ignored)
visible = drm_rect_clip_scaled(&src, &dst, &clip);
- FAIL(src.x1 != 1 << 16 || src.x2 != 2 << 16 || + KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 1 << 16 || src.x2 != 2 << 16 || src.y1 != 1 << 16 || src.y2 != 2 << 16, "Source badly clipped\n"); - FAIL(dst.x1 != 2 || dst.x2 != 4 || + KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 2 || dst.x2 != 4 || dst.y1 != 2 || dst.y2 != 4, "Destination badly clipped\n"); - FAIL(!visible, "Destination should be visible\n"); - FAIL(!drm_rect_visible(&src), "Source should be visible\n"); - - return 0; + KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); + KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); }
-int igt_drm_rect_clip_scaled_signed_vs_unsigned(void *ignored) +static void igt_drm_rect_clip_scaled_signed_vs_unsigned(struct kunit *test) { struct drm_rect src, dst, clip; bool visible; @@ -216,8 +207,23 @@ int igt_drm_rect_clip_scaled_signed_vs_unsigned(void *ignored)
visible = drm_rect_clip_scaled(&src, &dst, &clip);
- FAIL(visible, "Destination should not be visible\n"); - FAIL(drm_rect_visible(&src), "Source should not be visible\n"); - - return 0; + KUNIT_EXPECT_FALSE_MSG(test, visible, "Destination should not be visible\n"); + KUNIT_EXPECT_FALSE_MSG(test, drm_rect_visible(&src), "Source should not be visible\n"); } + +static struct kunit_case drm_rect_tests[] = { + KUNIT_CASE(igt_drm_rect_clip_scaled_div_by_zero), + KUNIT_CASE(igt_drm_rect_clip_scaled_not_clipped), + KUNIT_CASE(igt_drm_rect_clip_scaled_clipped), + KUNIT_CASE(igt_drm_rect_clip_scaled_signed_vs_unsigned), + { } +}; + +static struct kunit_suite drm_rect_test_suite = { + .name = "drm_rect", + .test_cases = drm_rect_tests, +}; + +kunit_test_suite(drm_rect_test_suite); + +MODULE_LICENSE("GPL");
Considering the current adoption of the KUnit framework, convert the DRM format selftest to the KUnit API.
Tested-by: David Gow davidgow@google.com Signed-off-by: Maíra Canal maira.canal@usp.br --- drivers/gpu/drm/selftests/Makefile | 3 +- .../gpu/drm/selftests/drm_modeset_selftests.h | 3 - drivers/gpu/drm/selftests/test-drm_format.c | 280 ----------------- .../drm/selftests/test-drm_modeset_common.h | 3 - drivers/gpu/drm/tests/Makefile | 2 +- drivers/gpu/drm/tests/drm_format_test.c | 284 ++++++++++++++++++ 6 files changed, 286 insertions(+), 289 deletions(-) delete mode 100644 drivers/gpu/drm/selftests/test-drm_format.c create mode 100644 drivers/gpu/drm/tests/drm_format_test.c
diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index 8a794914e328..b7f252d886d0 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ - test-drm_format.o test-drm_framebuffer.o \ - test-drm_dp_mst_helper.o + test-drm_framebuffer.o test-drm_dp_mst_helper.o
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o \ test-drm_buddy.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h index a3ca90307364..63061ef55eff 100644 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h @@ -7,9 +7,6 @@ * Tests are executed in order by igt/drm_selftests_helper */ selftest(check_plane_state, igt_check_plane_state) -selftest(check_drm_format_block_width, igt_check_drm_format_block_width) -selftest(check_drm_format_block_height, igt_check_drm_format_block_height) -selftest(check_drm_format_min_pitch, igt_check_drm_format_min_pitch) selftest(check_drm_framebuffer_create, igt_check_drm_framebuffer_create) selftest(dp_mst_calc_pbn_mode, igt_dp_mst_calc_pbn_mode) selftest(dp_mst_sideband_msg_req_decode, igt_dp_mst_sideband_msg_req_decode) diff --git a/drivers/gpu/drm/selftests/test-drm_format.c b/drivers/gpu/drm/selftests/test-drm_format.c deleted file mode 100644 index c5e212afa27a..000000000000 --- a/drivers/gpu/drm/selftests/test-drm_format.c +++ /dev/null @@ -1,280 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Test cases for the drm_format functions - */ - -#define pr_fmt(fmt) "drm_format: " fmt - -#include <linux/errno.h> -#include <linux/kernel.h> - -#include <drm/drm_fourcc.h> - -#include "test-drm_modeset_common.h" - -int igt_check_drm_format_block_width(void *ignored) -{ - const struct drm_format_info *info = NULL; - - /* Test invalid arguments */ - FAIL_ON(drm_format_info_block_width(info, 0) != 0); - FAIL_ON(drm_format_info_block_width(info, -1) != 0); - FAIL_ON(drm_format_info_block_width(info, 1) != 0); - - /* Test 1 plane format */ - info = drm_format_info(DRM_FORMAT_XRGB4444); - FAIL_ON(!info); - FAIL_ON(drm_format_info_block_width(info, 0) != 1); - FAIL_ON(drm_format_info_block_width(info, 1) != 0); - FAIL_ON(drm_format_info_block_width(info, -1) != 0); - - /* Test 2 planes format */ - info = drm_format_info(DRM_FORMAT_NV12); - FAIL_ON(!info); - FAIL_ON(drm_format_info_block_width(info, 0) != 1); - FAIL_ON(drm_format_info_block_width(info, 1) != 1); - FAIL_ON(drm_format_info_block_width(info, 2) != 0); - FAIL_ON(drm_format_info_block_width(info, -1) != 0); - - /* Test 3 planes format */ - info = drm_format_info(DRM_FORMAT_YUV422); - FAIL_ON(!info); - FAIL_ON(drm_format_info_block_width(info, 0) != 1); - FAIL_ON(drm_format_info_block_width(info, 1) != 1); - FAIL_ON(drm_format_info_block_width(info, 2) != 1); - FAIL_ON(drm_format_info_block_width(info, 3) != 0); - FAIL_ON(drm_format_info_block_width(info, -1) != 0); - - /* Test a tiled format */ - info = drm_format_info(DRM_FORMAT_X0L0); - FAIL_ON(!info); - FAIL_ON(drm_format_info_block_width(info, 0) != 2); - FAIL_ON(drm_format_info_block_width(info, 1) != 0); - FAIL_ON(drm_format_info_block_width(info, -1) != 0); - - return 0; -} - -int igt_check_drm_format_block_height(void *ignored) -{ - const struct drm_format_info *info = NULL; - - /* Test invalid arguments */ - FAIL_ON(drm_format_info_block_height(info, 0) != 0); - FAIL_ON(drm_format_info_block_height(info, -1) != 0); - FAIL_ON(drm_format_info_block_height(info, 1) != 0); - - /* Test 1 plane format */ - info = drm_format_info(DRM_FORMAT_XRGB4444); - FAIL_ON(!info); - FAIL_ON(drm_format_info_block_height(info, 0) != 1); - FAIL_ON(drm_format_info_block_height(info, 1) != 0); - FAIL_ON(drm_format_info_block_height(info, -1) != 0); - - /* Test 2 planes format */ - info = drm_format_info(DRM_FORMAT_NV12); - FAIL_ON(!info); - FAIL_ON(drm_format_info_block_height(info, 0) != 1); - FAIL_ON(drm_format_info_block_height(info, 1) != 1); - FAIL_ON(drm_format_info_block_height(info, 2) != 0); - FAIL_ON(drm_format_info_block_height(info, -1) != 0); - - /* Test 3 planes format */ - info = drm_format_info(DRM_FORMAT_YUV422); - FAIL_ON(!info); - FAIL_ON(drm_format_info_block_height(info, 0) != 1); - FAIL_ON(drm_format_info_block_height(info, 1) != 1); - FAIL_ON(drm_format_info_block_height(info, 2) != 1); - FAIL_ON(drm_format_info_block_height(info, 3) != 0); - FAIL_ON(drm_format_info_block_height(info, -1) != 0); - - /* Test a tiled format */ - info = drm_format_info(DRM_FORMAT_X0L0); - FAIL_ON(!info); - FAIL_ON(drm_format_info_block_height(info, 0) != 2); - FAIL_ON(drm_format_info_block_height(info, 1) != 0); - FAIL_ON(drm_format_info_block_height(info, -1) != 0); - - return 0; -} - -int igt_check_drm_format_min_pitch(void *ignored) -{ - const struct drm_format_info *info = NULL; - - /* Test invalid arguments */ - FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0); - - /* Test 1 plane 8 bits per pixel format */ - info = drm_format_info(DRM_FORMAT_RGB332); - FAIL_ON(!info); - FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0); - - FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1); - FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2); - FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640); - FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024); - FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920); - FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096); - FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671); - FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) != - (uint64_t)UINT_MAX); - FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) != - (uint64_t)(UINT_MAX - 1)); - - /* Test 1 plane 16 bits per pixel format */ - info = drm_format_info(DRM_FORMAT_XRGB4444); - FAIL_ON(!info); - FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0); - - FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 2); - FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 4); - FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1280); - FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 2048); - FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 3840); - FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 8192); - FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 1342); - FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) != - (uint64_t)UINT_MAX * 2); - FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) != - (uint64_t)(UINT_MAX - 1) * 2); - - /* Test 1 plane 24 bits per pixel format */ - info = drm_format_info(DRM_FORMAT_RGB888); - FAIL_ON(!info); - FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0); - - FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 3); - FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 6); - FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1920); - FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 3072); - FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 5760); - FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 12288); - FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 2013); - FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) != - (uint64_t)UINT_MAX * 3); - FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) != - (uint64_t)(UINT_MAX - 1) * 3); - - /* Test 1 plane 32 bits per pixel format */ - info = drm_format_info(DRM_FORMAT_ABGR8888); - FAIL_ON(!info); - FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0); - - FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 4); - FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 8); - FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 2560); - FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 4096); - FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 7680); - FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 16384); - FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 2684); - FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) != - (uint64_t)UINT_MAX * 4); - FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) != - (uint64_t)(UINT_MAX - 1) * 4); - - /* Test 2 planes format */ - info = drm_format_info(DRM_FORMAT_NV12); - FAIL_ON(!info); - FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, 2, 0) != 0); - - FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1); - FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 2); - FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2); - FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 2); - FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640); - FAIL_ON(drm_format_info_min_pitch(info, 1, 320) != 640); - FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024); - FAIL_ON(drm_format_info_min_pitch(info, 1, 512) != 1024); - FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920); - FAIL_ON(drm_format_info_min_pitch(info, 1, 960) != 1920); - FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096); - FAIL_ON(drm_format_info_min_pitch(info, 1, 2048) != 4096); - FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671); - FAIL_ON(drm_format_info_min_pitch(info, 1, 336) != 672); - FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) != - (uint64_t)UINT_MAX); - FAIL_ON(drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1) != - (uint64_t)UINT_MAX + 1); - FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) != - (uint64_t)(UINT_MAX - 1)); - FAIL_ON(drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) / 2) != - (uint64_t)(UINT_MAX - 1)); - - /* Test 3 planes 8 bits per pixel format */ - info = drm_format_info(DRM_FORMAT_YUV422); - FAIL_ON(!info); - FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, 2, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, 3, 0) != 0); - - FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1); - FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 1); - FAIL_ON(drm_format_info_min_pitch(info, 2, 1) != 1); - FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2); - FAIL_ON(drm_format_info_min_pitch(info, 1, 2) != 2); - FAIL_ON(drm_format_info_min_pitch(info, 2, 2) != 2); - FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640); - FAIL_ON(drm_format_info_min_pitch(info, 1, 320) != 320); - FAIL_ON(drm_format_info_min_pitch(info, 2, 320) != 320); - FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024); - FAIL_ON(drm_format_info_min_pitch(info, 1, 512) != 512); - FAIL_ON(drm_format_info_min_pitch(info, 2, 512) != 512); - FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920); - FAIL_ON(drm_format_info_min_pitch(info, 1, 960) != 960); - FAIL_ON(drm_format_info_min_pitch(info, 2, 960) != 960); - FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096); - FAIL_ON(drm_format_info_min_pitch(info, 1, 2048) != 2048); - FAIL_ON(drm_format_info_min_pitch(info, 2, 2048) != 2048); - FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671); - FAIL_ON(drm_format_info_min_pitch(info, 1, 336) != 336); - FAIL_ON(drm_format_info_min_pitch(info, 2, 336) != 336); - FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) != - (uint64_t)UINT_MAX); - FAIL_ON(drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1) != - (uint64_t)UINT_MAX / 2 + 1); - FAIL_ON(drm_format_info_min_pitch(info, 2, UINT_MAX / 2 + 1) != - (uint64_t)UINT_MAX / 2 + 1); - FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1) / 2) != - (uint64_t)(UINT_MAX - 1) / 2); - FAIL_ON(drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) / 2) != - (uint64_t)(UINT_MAX - 1) / 2); - FAIL_ON(drm_format_info_min_pitch(info, 2, (UINT_MAX - 1) / 2) != - (uint64_t)(UINT_MAX - 1) / 2); - - /* Test tiled format */ - info = drm_format_info(DRM_FORMAT_X0L2); - FAIL_ON(!info); - FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0); - FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0); - - FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 2); - FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 4); - FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1280); - FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 2048); - FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 3840); - FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 8192); - FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 1342); - FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) != - (uint64_t)UINT_MAX * 2); - FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) != - (uint64_t)(UINT_MAX - 1) * 2); - - return 0; -} diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h index 42a10d7da51c..5709d967a5c4 100644 --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h @@ -17,9 +17,6 @@ #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
int igt_check_plane_state(void *ignored); -int igt_check_drm_format_block_width(void *ignored); -int igt_check_drm_format_block_height(void *ignored); -int igt_check_drm_format_min_pitch(void *ignored); int igt_check_drm_framebuffer_create(void *ignored); int igt_dp_mst_calc_pbn_mode(void *ignored); int igt_dp_mst_sideband_msg_req_decode(void *ignored); diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index d413fbe6d710..7a60289d2c6c 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_DRM_KUNIT_TEST) += drm_damage_helper_test.o drm_cmdline_parser_test.o \ - drm_rect_test.o + drm_rect_test.o drm_format_test.o diff --git a/drivers/gpu/drm/tests/drm_format_test.c b/drivers/gpu/drm/tests/drm_format_test.c new file mode 100644 index 000000000000..e94b2bc6de54 --- /dev/null +++ b/drivers/gpu/drm/tests/drm_format_test.c @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test cases for the drm_format functions + */ + +#include <kunit/test.h> +#include <drm/drm_fourcc.h> + +static void igt_check_drm_format_block_width(struct kunit *test) +{ + const struct drm_format_info *info = NULL; + + /* Test invalid arguments */ + KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, -1)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, 1)); + + /* Test 1 plane format */ + info = drm_format_info(DRM_FORMAT_XRGB4444); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_TRUE(test, drm_format_info_block_width(info, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, 1)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, -1)); + + /* Test 2 planes format */ + info = drm_format_info(DRM_FORMAT_NV12); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_TRUE(test, drm_format_info_block_width(info, 0)); + KUNIT_EXPECT_TRUE(test, drm_format_info_block_width(info, 1)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, 2)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, -1)); + + /* Test 3 planes format */ + info = drm_format_info(DRM_FORMAT_YUV422); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_TRUE(test, drm_format_info_block_width(info, 0)); + KUNIT_EXPECT_TRUE(test, drm_format_info_block_width(info, 1)); + KUNIT_EXPECT_TRUE(test, drm_format_info_block_width(info, 2)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, 3)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, -1)); + + /* Test a tiled format */ + info = drm_format_info(DRM_FORMAT_X0L0); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 0), 2); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, 1)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, -1)); +} + +static void igt_check_drm_format_block_height(struct kunit *test) +{ + const struct drm_format_info *info = NULL; + + /* Test invalid arguments */ + KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, -1)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, 1)); + + /* Test 1 plane format */ + info = drm_format_info(DRM_FORMAT_XRGB4444); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_TRUE(test, drm_format_info_block_height(info, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, -1)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, 1)); + + /* Test 2 planes format */ + info = drm_format_info(DRM_FORMAT_NV12); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_TRUE(test, drm_format_info_block_height(info, 0)); + KUNIT_EXPECT_TRUE(test, drm_format_info_block_height(info, 1)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, 2)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, -1)); + + /* Test 3 planes format */ + info = drm_format_info(DRM_FORMAT_YUV422); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_TRUE(test, drm_format_info_block_height(info, 0)); + KUNIT_EXPECT_TRUE(test, drm_format_info_block_height(info, 1)); + KUNIT_EXPECT_TRUE(test, drm_format_info_block_height(info, 2)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, 3)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, -1)); + + /* Test a tiled format */ + info = drm_format_info(DRM_FORMAT_X0L0); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_EQ(test, drm_format_info_block_height(info, 0), 2); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, 1)); + KUNIT_EXPECT_FALSE(test, drm_format_info_block_height(info, -1)); +} + +static void igt_check_drm_format_min_pitch(struct kunit *test) +{ + const struct drm_format_info *info = NULL; + + /* Test invalid arguments */ + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); + + /* Test 1 plane 8 bits per pixel format */ + info = drm_format_info(DRM_FORMAT_RGB332); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); + + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 1); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 2); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 640), 640); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1024), 1024); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1920), 1920); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 4096), 4096); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 671); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX), + (uint64_t)UINT_MAX); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)), + (uint64_t)(UINT_MAX - 1)); + + /* Test 1 plane 16 bits per pixel format */ + info = drm_format_info(DRM_FORMAT_XRGB4444); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); + + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 2); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 4); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 640), 1280); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1024), 2048); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1920), 3840); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 4096), 8192); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 1342); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX), + (uint64_t)UINT_MAX * 2); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)), + (uint64_t)(UINT_MAX - 1) * 2); + + /* Test 1 plane 24 bits per pixel format */ + info = drm_format_info(DRM_FORMAT_RGB888); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); + + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 3); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 6); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 640), 1920); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1024), 3072); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1920), 5760); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 4096), 12288); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 2013); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX), + (uint64_t)UINT_MAX * 3); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)), + (uint64_t)(UINT_MAX - 1) * 3); + + /* Test 1 plane 32 bits per pixel format */ + info = drm_format_info(DRM_FORMAT_ABGR8888); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); + + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 4); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 8); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 640), 2560); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1024), 4096); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1920), 7680); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 4096), 16384); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 2684); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX), + (uint64_t)UINT_MAX * 4); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)), + (uint64_t)(UINT_MAX - 1) * 4); + + /* Test 2 planes format */ + info = drm_format_info(DRM_FORMAT_NV12); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 2, 0)); + + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 1); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 1), 2); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 2); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 1), 2); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 640), 640); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 320), 640); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1024), 1024); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 512), 1024); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1920), 1920); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 960), 1920); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 4096), 4096); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 2048), 4096); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 671); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 336), 672); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX), + (uint64_t)UINT_MAX); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1), + (uint64_t)UINT_MAX + 1); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)), + (uint64_t)(UINT_MAX - 1)); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) / 2), + (uint64_t)(UINT_MAX - 1)); + + /* Test 3 planes 8 bits per pixel format */ + info = drm_format_info(DRM_FORMAT_YUV422); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 2, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 3, 0)); + + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 1); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 1), 1); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 1), 1); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 2); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 2), 2); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 2), 2); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 640), 640); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 320), 320); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 320), 320); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1024), 1024); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 512), 512); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 512), 512); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1920), 1920); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 960), 960); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 960), 960); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 4096), 4096); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 2048), 2048); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 2048), 2048); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 671); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 336), 336); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 336), 336); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX), + (uint64_t)UINT_MAX); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1), + (uint64_t)UINT_MAX / 2 + 1); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, UINT_MAX / 2 + 1), + (uint64_t)UINT_MAX / 2 + 1); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1) / 2), + (uint64_t)(UINT_MAX - 1) / 2); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) / 2), + (uint64_t)(UINT_MAX - 1) / 2); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, (UINT_MAX - 1) / 2), + (uint64_t)(UINT_MAX - 1) / 2); + + /* Test tiled format */ + info = drm_format_info(DRM_FORMAT_X0L2); + KUNIT_EXPECT_TRUE(test, info); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); + KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); + + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 2); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 4); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 640), 1280); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1024), 2048); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1920), 3840); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 4096), 8192); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 1342); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX), + (uint64_t)UINT_MAX * 2); + KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX - 1), + (uint64_t)(UINT_MAX - 1) * 2); +} + +static struct kunit_case drm_format_tests[] = { + KUNIT_CASE(igt_check_drm_format_block_width), + KUNIT_CASE(igt_check_drm_format_block_height), + KUNIT_CASE(igt_check_drm_format_min_pitch), + { } +}; + +static struct kunit_suite drm_format_test_suite = { + .name = "drm_format", + .test_cases = drm_format_tests, +}; + +kunit_test_suite(drm_format_test_suite); + +MODULE_LICENSE("GPL");
Hi "Maíra,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on drm/drm-next] [also build test WARNING on linus/master v5.19-rc3 next-20220622] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch]
url: https://github.com/intel-lab-lkp/linux/commits/Ma-ra-Canal/drm-selftest-Conv... base: git://anongit.freedesktop.org/drm/drm drm-next config: mips-allyesconfig (https://download.01.org/0day-ci/archive/20220622/202206221827.Qd1tjlFl-lkp@i...) compiler: mips-linux-gcc (GCC) 11.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/169d2ec9315db8eac8466f00e3f30a... git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Ma-ra-Canal/drm-selftest-Convert-to-KUnit/20220622-041357 git checkout 169d2ec9315db8eac8466f00e3f30a341e958ef2 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=mips SHELL=/bin/bash drivers/gpu/drm/tests/
If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot lkp@intel.com
All warnings (new ones prefixed by >>):
drivers/gpu/drm/tests/drm_format_test.c: In function 'igt_check_drm_format_min_pitch':
drivers/gpu/drm/tests/drm_format_test.c:268:1: warning: the frame size of 2576 bytes is larger than 2048 bytes [-Wframe-larger-than=]
268 | } | ^
vim +268 drivers/gpu/drm/tests/drm_format_test.c
90 91 static void igt_check_drm_format_min_pitch(struct kunit *test) 92 { 93 const struct drm_format_info *info = NULL; 94 95 /* Test invalid arguments */ 96 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); 97 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); 98 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); 99 100 /* Test 1 plane 8 bits per pixel format */ 101 info = drm_format_info(DRM_FORMAT_RGB332); 102 KUNIT_EXPECT_TRUE(test, info); 103 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); 104 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); 105 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); 106 107 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 1); 108 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 2); 109 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 640), 640); 110 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1024), 1024); 111 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1920), 1920); 112 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 4096), 4096); 113 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 671); 114 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX), 115 (uint64_t)UINT_MAX); 116 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)), 117 (uint64_t)(UINT_MAX - 1)); 118 119 /* Test 1 plane 16 bits per pixel format */ 120 info = drm_format_info(DRM_FORMAT_XRGB4444); 121 KUNIT_EXPECT_TRUE(test, info); 122 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); 123 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); 124 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); 125 126 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 2); 127 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 4); 128 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 640), 1280); 129 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1024), 2048); 130 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1920), 3840); 131 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 4096), 8192); 132 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 1342); 133 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX), 134 (uint64_t)UINT_MAX * 2); 135 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)), 136 (uint64_t)(UINT_MAX - 1) * 2); 137 138 /* Test 1 plane 24 bits per pixel format */ 139 info = drm_format_info(DRM_FORMAT_RGB888); 140 KUNIT_EXPECT_TRUE(test, info); 141 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); 142 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); 143 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); 144 145 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 3); 146 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 6); 147 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 640), 1920); 148 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1024), 3072); 149 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1920), 5760); 150 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 4096), 12288); 151 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 2013); 152 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX), 153 (uint64_t)UINT_MAX * 3); 154 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)), 155 (uint64_t)(UINT_MAX - 1) * 3); 156 157 /* Test 1 plane 32 bits per pixel format */ 158 info = drm_format_info(DRM_FORMAT_ABGR8888); 159 KUNIT_EXPECT_TRUE(test, info); 160 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); 161 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); 162 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); 163 164 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 4); 165 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 8); 166 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 640), 2560); 167 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1024), 4096); 168 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1920), 7680); 169 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 4096), 16384); 170 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 2684); 171 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX), 172 (uint64_t)UINT_MAX * 4); 173 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)), 174 (uint64_t)(UINT_MAX - 1) * 4); 175 176 /* Test 2 planes format */ 177 info = drm_format_info(DRM_FORMAT_NV12); 178 KUNIT_EXPECT_TRUE(test, info); 179 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); 180 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); 181 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); 182 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 2, 0)); 183 184 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 1); 185 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 1), 2); 186 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 2); 187 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 1), 2); 188 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 640), 640); 189 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 320), 640); 190 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1024), 1024); 191 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 512), 1024); 192 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1920), 1920); 193 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 960), 1920); 194 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 4096), 4096); 195 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 2048), 4096); 196 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 671); 197 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 336), 672); 198 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX), 199 (uint64_t)UINT_MAX); 200 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1), 201 (uint64_t)UINT_MAX + 1); 202 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)), 203 (uint64_t)(UINT_MAX - 1)); 204 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) / 2), 205 (uint64_t)(UINT_MAX - 1)); 206 207 /* Test 3 planes 8 bits per pixel format */ 208 info = drm_format_info(DRM_FORMAT_YUV422); 209 KUNIT_EXPECT_TRUE(test, info); 210 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); 211 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); 212 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 2, 0)); 213 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); 214 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 3, 0)); 215 216 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 1); 217 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 1), 1); 218 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 1), 1); 219 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 2); 220 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 2), 2); 221 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 2), 2); 222 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 640), 640); 223 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 320), 320); 224 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 320), 320); 225 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1024), 1024); 226 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 512), 512); 227 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 512), 512); 228 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1920), 1920); 229 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 960), 960); 230 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 960), 960); 231 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 4096), 4096); 232 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 2048), 2048); 233 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 2048), 2048); 234 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 671); 235 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, 336), 336); 236 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, 336), 336); 237 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX), 238 (uint64_t)UINT_MAX); 239 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1), 240 (uint64_t)UINT_MAX / 2 + 1); 241 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, UINT_MAX / 2 + 1), 242 (uint64_t)UINT_MAX / 2 + 1); 243 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, (UINT_MAX - 1) / 2), 244 (uint64_t)(UINT_MAX - 1) / 2); 245 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) / 2), 246 (uint64_t)(UINT_MAX - 1) / 2); 247 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 2, (UINT_MAX - 1) / 2), 248 (uint64_t)(UINT_MAX - 1) / 2); 249 250 /* Test tiled format */ 251 info = drm_format_info(DRM_FORMAT_X0L2); 252 KUNIT_EXPECT_TRUE(test, info); 253 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 0, 0)); 254 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, -1, 0)); 255 KUNIT_EXPECT_FALSE(test, drm_format_info_min_pitch(info, 1, 0)); 256 257 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1), 2); 258 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 2), 4); 259 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 640), 1280); 260 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1024), 2048); 261 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 1920), 3840); 262 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 4096), 8192); 263 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, 671), 1342); 264 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX), 265 (uint64_t)UINT_MAX * 2); 266 KUNIT_EXPECT_EQ(test, drm_format_info_min_pitch(info, 0, UINT_MAX - 1), 267 (uint64_t)(UINT_MAX - 1) * 2);
268 }
269
On Tue, Jun 21, 2022 at 1:10 PM Maíra Canal maira.canal@usp.br wrote:
Considering the current adoption of the KUnit framework, convert the DRM format selftest to the KUnit API.
Tested-by: David Gow davidgow@google.com Signed-off-by: Maíra Canal maira.canal@usp.br
Acked-by: Daniel Latypov dlatypov@google.com
Overall looks good from the KUnit side, just a few general suggestions below.
FYI, the warning email from kernel-test-robot is basically saying that the compiler is not optimizing away the temporary variables internally created in KUNIT_EXPECT_*. So having too many KUNIT_EXPECT_.* in a single function is the trigger. The main workaround you'd have is to split up the test into more test functions. (I don't know if that's actually worth doing)
+static void igt_check_drm_format_block_width(struct kunit *test) +{
const struct drm_format_info *info = NULL;
/* Test invalid arguments */
KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, 0));
KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, -1));
KUNIT_EXPECT_FALSE(test, drm_format_info_block_width(info, 1));
Hmm, I think one of these two would be clearer here: KUNIT_EXPECT_EQ(test, drm_format_info_block_width(info, 0), 0); KUNIT_EXPECT_EQ(test, 0, drm_format_info_block_width(info, 0));
I think this helps test readability (giving hints about the types) and gives better error messages, more on that below.
The problem with using the boolean expectations is that given int foo = 2; KUNIT_EXPECT_FALSE(test, foo); KUnit will only print out Expected foo to be false, but is true
Using EXPECT_EQ(foo, 0), we'd get Expected foo == 0, but foo == 2
Knowing exactly what the offending return value was can help debug test failures a bit faster.
/* Test 1 plane format */
info = drm_format_info(DRM_FORMAT_XRGB4444);
KUNIT_EXPECT_TRUE(test, info);
FYI, you can now instead write KUNIT_EXPECT_NOT_NULL(test, info); this new macro was merged into 5.19-rc1.
Considering the current adoption of the KUnit framework, convert the DRM plane helper selftest to the KUnit API.
Tested-by: David Gow davidgow@google.com Co-developed-by: Djakson C. G. Filho djakson.filho@gmail.com Signed-off-by: Djakson C. G. Filho djakson.filho@gmail.com Co-developed-by: Anderson Fraga aaafraga@gmail.com Signed-off-by: Anderson Fraga aaafraga@gmail.com Signed-off-by: Maíra Canal maira.canal@usp.br --- drivers/gpu/drm/selftests/Makefile | 4 +- .../gpu/drm/selftests/drm_modeset_selftests.h | 1 - .../drm/selftests/test-drm_modeset_common.h | 1 - drivers/gpu/drm/tests/Makefile | 2 +- .../drm_plane_helper_test.c} | 103 ++++++++++-------- 5 files changed, 60 insertions(+), 51 deletions(-) rename drivers/gpu/drm/{selftests/test-drm_plane_helper.c => tests/drm_plane_helper_test.c} (62%)
diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index b7f252d886d0..9e0ccb482841 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ - test-drm_framebuffer.o test-drm_dp_mst_helper.o +test-drm_modeset-y := test-drm_modeset_common.o test-drm_framebuffer.o \ + test-drm_dp_mst_helper.o
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o \ test-drm_buddy.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h index 63061ef55eff..22e467f6465a 100644 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h @@ -6,7 +6,6 @@ * * Tests are executed in order by igt/drm_selftests_helper */ -selftest(check_plane_state, igt_check_plane_state) selftest(check_drm_framebuffer_create, igt_check_drm_framebuffer_create) selftest(dp_mst_calc_pbn_mode, igt_dp_mst_calc_pbn_mode) selftest(dp_mst_sideband_msg_req_decode, igt_dp_mst_sideband_msg_req_decode) diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h index 5709d967a5c4..790f3cf31f0d 100644 --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h @@ -16,7 +16,6 @@
#define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
-int igt_check_plane_state(void *ignored); int igt_check_drm_framebuffer_create(void *ignored); int igt_dp_mst_calc_pbn_mode(void *ignored); int igt_dp_mst_sideband_msg_req_decode(void *ignored); diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index 7a60289d2c6c..0dfc8b806f85 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_DRM_KUNIT_TEST) += drm_damage_helper_test.o drm_cmdline_parser_test.o \ - drm_rect_test.o drm_format_test.o + drm_rect_test.o drm_format_test.o drm_plane_helper_test.o diff --git a/drivers/gpu/drm/selftests/test-drm_plane_helper.c b/drivers/gpu/drm/tests/drm_plane_helper_test.c similarity index 62% rename from drivers/gpu/drm/selftests/test-drm_plane_helper.c rename to drivers/gpu/drm/tests/drm_plane_helper_test.c index b61273e9c403..794e7ddf62f1 100644 --- a/drivers/gpu/drm/selftests/test-drm_plane_helper.c +++ b/drivers/gpu/drm/tests/drm_plane_helper_test.c @@ -3,14 +3,11 @@ * Test cases for the drm_plane_helper functions */
-#define pr_fmt(fmt) "drm_plane_helper: " fmt - +#include <kunit/test.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_plane_helper.h> #include <drm/drm_modes.h>
-#include "test-drm_modeset_common.h" - static void set_src(struct drm_plane_state *plane_state, unsigned src_x, unsigned src_y, unsigned src_w, unsigned src_h) @@ -73,7 +70,7 @@ static bool check_crtc_eq(struct drm_plane_state *plane_state, return true; }
-int igt_check_plane_state(void *ignored) +static void igt_check_plane_state(struct kunit *test) { int ret;
@@ -108,10 +105,10 @@ int igt_check_plane_state(void *ignored) DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, false, false); - FAIL(ret < 0, "Simple clipping check should pass\n"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0, 0, 1024 << 16, 768 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768)); + KUNIT_EXPECT_FALSE_MSG(test, ret, 0, "Simple clipping check should pass\n"); + KUNIT_EXPECT_TRUE(test, plane_state.visible); + KUNIT_EXPECT_TRUE(test, check_src_eq(&plane_state, 0, 0, 1024 << 16, 768 << 16)); + KUNIT_EXPECT_TRUE(test, check_crtc_eq(&plane_state, 0, 0, 1024, 768));
/* Rotated clipping + reflection, no scaling. */ plane_state.rotation = DRM_MODE_ROTATE_90 | DRM_MODE_REFLECT_X; @@ -119,10 +116,10 @@ int igt_check_plane_state(void *ignored) DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, false, false); - FAIL(ret < 0, "Rotated clipping check should pass\n"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0, 0, 768 << 16, 1024 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768)); + KUNIT_EXPECT_FALSE_MSG(test, ret, 0, "Rotated clipping check should pass\n"); + KUNIT_EXPECT_TRUE(test, plane_state.visible); + KUNIT_EXPECT_TRUE(test, check_src_eq(&plane_state, 0, 0, 768 << 16, 1024 << 16)); + KUNIT_EXPECT_TRUE(test, check_crtc_eq(&plane_state, 0, 0, 1024, 768)); plane_state.rotation = DRM_MODE_ROTATE_0;
/* Check whether positioning works correctly. */ @@ -132,16 +129,17 @@ int igt_check_plane_state(void *ignored) DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, false, false); - FAIL(!ret, "Should not be able to position on the crtc with can_position=false\n"); + KUNIT_EXPECT_TRUE_MSG(test, ret, + "Should not be able to position on the crtc with can_position=false\n");
ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, DRM_PLANE_HELPER_NO_SCALING, DRM_PLANE_HELPER_NO_SCALING, true, false); - FAIL(ret < 0, "Simple positioning should work\n"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0, 0, 1023 << 16, 767 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1023, 767)); + KUNIT_EXPECT_FALSE_MSG(test, ret, 0, "Simple positioning should work\n"); + KUNIT_EXPECT_TRUE(test, plane_state.visible); + KUNIT_EXPECT_TRUE(test, check_src_eq(&plane_state, 0, 0, 1023 << 16, 767 << 16)); + KUNIT_EXPECT_TRUE(test, check_crtc_eq(&plane_state, 0, 0, 1023, 767));
/* Simple scaling tests. */ set_src(&plane_state, 0, 0, 512 << 16, 384 << 16); @@ -150,28 +148,28 @@ int igt_check_plane_state(void *ignored) 0x8001, DRM_PLANE_HELPER_NO_SCALING, false, false); - FAIL(!ret, "Upscaling out of range should fail.\n"); + KUNIT_EXPECT_TRUE_MSG(test, ret, "Upscaling out of range should fail.\n"); ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, 0x8000, DRM_PLANE_HELPER_NO_SCALING, false, false); - FAIL(ret < 0, "Upscaling exactly 2x should work\n"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0, 0, 512 << 16, 384 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768)); + KUNIT_EXPECT_FALSE_MSG(test, ret, 0, "Upscaling exactly 2x should work\n"); + KUNIT_EXPECT_TRUE(test, plane_state.visible); + KUNIT_EXPECT_TRUE(test, check_src_eq(&plane_state, 0, 0, 512 << 16, 384 << 16)); + KUNIT_EXPECT_TRUE(test, check_crtc_eq(&plane_state, 0, 0, 1024, 768));
set_src(&plane_state, 0, 0, 2048 << 16, 1536 << 16); ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, DRM_PLANE_HELPER_NO_SCALING, 0x1ffff, false, false); - FAIL(!ret, "Downscaling out of range should fail.\n"); + KUNIT_EXPECT_TRUE_MSG(test, ret, "Downscaling out of range should fail.\n"); ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, DRM_PLANE_HELPER_NO_SCALING, 0x20000, false, false); - FAIL(ret < 0, "Should succeed with exact scaling limit\n"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0, 0, 2048 << 16, 1536 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768)); + KUNIT_EXPECT_FALSE_MSG(test, ret, 0, "Should succeed with exact scaling limit\n"); + KUNIT_EXPECT_TRUE(test, plane_state.visible); + KUNIT_EXPECT_TRUE(test, check_src_eq(&plane_state, 0, 0, 2048 << 16, 1536 << 16)); + KUNIT_EXPECT_TRUE(test, check_crtc_eq(&plane_state, 0, 0, 1024, 768));
/* Testing rounding errors. */ set_src(&plane_state, 0, 0, 0x40001, 0x40001); @@ -180,10 +178,10 @@ int igt_check_plane_state(void *ignored) DRM_PLANE_HELPER_NO_SCALING, 0x10001, true, false); - FAIL(ret < 0, "Should succeed by clipping to exact multiple"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0, 0, 2 << 16, 2 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 1022, 766, 2, 2)); + KUNIT_EXPECT_FALSE_MSG(test, ret, 0, "Should succeed by clipping to exact multiple"); + KUNIT_EXPECT_TRUE(test, plane_state.visible); + KUNIT_EXPECT_TRUE(test, check_src_eq(&plane_state, 0, 0, 2 << 16, 2 << 16)); + KUNIT_EXPECT_TRUE(test, check_crtc_eq(&plane_state, 1022, 766, 2, 2));
set_src(&plane_state, 0x20001, 0x20001, 0x4040001, 0x3040001); set_crtc(&plane_state, -2, -2, 1028, 772); @@ -191,10 +189,10 @@ int igt_check_plane_state(void *ignored) DRM_PLANE_HELPER_NO_SCALING, 0x10001, false, false); - FAIL(ret < 0, "Should succeed by clipping to exact multiple"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0x40002, 0x40002, 1024 << 16, 768 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768)); + KUNIT_EXPECT_FALSE_MSG(test, ret, 0, "Should succeed by clipping to exact multiple"); + KUNIT_EXPECT_TRUE(test, plane_state.visible); + KUNIT_EXPECT_TRUE(test, check_src_eq(&plane_state, 0x40002, 0x40002, 1024 << 16, 768 << 16)); + KUNIT_EXPECT_TRUE(test, check_crtc_eq(&plane_state, 0, 0, 1024, 768));
set_src(&plane_state, 0, 0, 0x3ffff, 0x3ffff); set_crtc(&plane_state, 1022, 766, 4, 4); @@ -202,11 +200,11 @@ int igt_check_plane_state(void *ignored) 0xffff, DRM_PLANE_HELPER_NO_SCALING, true, false); - FAIL(ret < 0, "Should succeed by clipping to exact multiple"); - FAIL_ON(!plane_state.visible); + KUNIT_EXPECT_FALSE_MSG(test, ret, 0, "Should succeed by clipping to exact multiple"); + KUNIT_EXPECT_TRUE(test, plane_state.visible); /* Should not be rounded to 0x20001, which would be upscaling. */ - FAIL_ON(!check_src_eq(&plane_state, 0, 0, 2 << 16, 2 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 1022, 766, 2, 2)); + KUNIT_EXPECT_TRUE(test, check_src_eq(&plane_state, 0, 0, 2 << 16, 2 << 16)); + KUNIT_EXPECT_TRUE(test, check_crtc_eq(&plane_state, 1022, 766, 2, 2));
set_src(&plane_state, 0x1ffff, 0x1ffff, 0x403ffff, 0x303ffff); set_crtc(&plane_state, -2, -2, 1028, 772); @@ -214,10 +212,23 @@ int igt_check_plane_state(void *ignored) 0xffff, DRM_PLANE_HELPER_NO_SCALING, false, false); - FAIL(ret < 0, "Should succeed by clipping to exact multiple"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0x3fffe, 0x3fffe, 1024 << 16, 768 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768)); - - return 0; + KUNIT_EXPECT_FALSE_MSG(test, ret, 0, "Should succeed by clipping to exact multiple"); + KUNIT_EXPECT_TRUE(test, plane_state.visible); + KUNIT_EXPECT_TRUE(test, check_src_eq(&plane_state, 0x3fffe, 0x3fffe, + 1024 << 16, 768 << 16)); + KUNIT_EXPECT_TRUE(test, check_crtc_eq(&plane_state, 0, 0, 1024, 768)); } + +static struct kunit_case drm_plane_helper_test[] = { + KUNIT_CASE(igt_check_plane_state), + {} +}; + +static struct kunit_suite drm_plane_helper_test_suite = { + .name = "drm_plane_helper", + .test_cases = drm_plane_helper_test, +}; + +kunit_test_suite(drm_plane_helper_test_suite); + +MODULE_LICENSE("GPL");
Considering the current adoption of the KUnit framework, convert the DRM DP MST helper selftest to the KUnit API.
Tested-by: David Gow davidgow@google.com Co-developed-by: Rubens Gomes Neto rubens.gomes.neto@usp.br Signed-off-by: Rubens Gomes Neto rubens.gomes.neto@usp.br Signed-off-by: Maíra Canal maira.canal@usp.br --- drivers/gpu/drm/selftests/Makefile | 3 +- .../gpu/drm/selftests/drm_modeset_selftests.h | 2 - .../drm/selftests/test-drm_modeset_common.h | 2 - drivers/gpu/drm/tests/Makefile | 3 +- .../drm_dp_mst_helper_test.c} | 84 ++++++++++--------- 5 files changed, 49 insertions(+), 45 deletions(-) rename drivers/gpu/drm/{selftests/test-drm_dp_mst_helper.c => tests/drm_dp_mst_helper_test.c} (73%)
diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index 9e0ccb482841..1539f55db9a7 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -test-drm_modeset-y := test-drm_modeset_common.o test-drm_framebuffer.o \ - test-drm_dp_mst_helper.o +test-drm_modeset-y := test-drm_modeset_common.o test-drm_framebuffer.o
obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o \ test-drm_buddy.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h index 22e467f6465a..40a29b8cf386 100644 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h @@ -7,5 +7,3 @@ * Tests are executed in order by igt/drm_selftests_helper */ selftest(check_drm_framebuffer_create, igt_check_drm_framebuffer_create) -selftest(dp_mst_calc_pbn_mode, igt_dp_mst_calc_pbn_mode) -selftest(dp_mst_sideband_msg_req_decode, igt_dp_mst_sideband_msg_req_decode) diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h index 790f3cf31f0d..3feb2fea1a6b 100644 --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h @@ -17,7 +17,5 @@ #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
int igt_check_drm_framebuffer_create(void *ignored); -int igt_dp_mst_calc_pbn_mode(void *ignored); -int igt_dp_mst_sideband_msg_req_decode(void *ignored);
#endif diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index 0dfc8b806f85..40c003df2625 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_DRM_KUNIT_TEST) += drm_damage_helper_test.o drm_cmdline_parser_test.o \ - drm_rect_test.o drm_format_test.o drm_plane_helper_test.o + drm_rect_test.o drm_format_test.o drm_plane_helper_test.o \ + drm_dp_mst_helper_test.o diff --git a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c b/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c similarity index 73% rename from drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c rename to drivers/gpu/drm/tests/drm_dp_mst_helper_test.c index 967c52150b67..be846be84fe9 100644 --- a/drivers/gpu/drm/selftests/test-drm_dp_mst_helper.c +++ b/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c @@ -5,15 +5,15 @@
#define PREFIX_STR "[drm_dp_mst_helper]"
+#include <kunit/test.h> #include <linux/random.h>
#include <drm/display/drm_dp_mst_helper.h> #include <drm/drm_print.h>
#include "../display/drm_dp_mst_topology_internal.h" -#include "test-drm_modeset_common.h"
-int igt_dp_mst_calc_pbn_mode(void *ignored) +static void igt_dp_mst_calc_pbn_mode(struct kunit *test) { int pbn, i; const struct { @@ -33,13 +33,11 @@ int igt_dp_mst_calc_pbn_mode(void *ignored) pbn = drm_dp_calc_pbn_mode(test_params[i].rate, test_params[i].bpp, test_params[i].dsc); - FAIL(pbn != test_params[i].expected, + KUNIT_EXPECT_EQ_MSG(test, pbn, test_params[i].expected, "Expected PBN %d for clock %d bpp %d, got %d\n", test_params[i].expected, test_params[i].rate, test_params[i].bpp, pbn); } - - return 0; }
static bool @@ -176,66 +174,64 @@ sideband_msg_req_encode_decode(struct drm_dp_sideband_msg_req_body *in) return result; }
-int igt_dp_mst_sideband_msg_req_decode(void *unused) +static void igt_dp_mst_sideband_msg_req_decode(struct kunit *test) { struct drm_dp_sideband_msg_req_body in = { 0 }; u8 data[] = { 0xff, 0x0, 0xdd }; int i;
-#define DO_TEST() FAIL_ON(!sideband_msg_req_encode_decode(&in)) - in.req_type = DP_ENUM_PATH_RESOURCES; in.u.port_num.port_number = 5; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
in.req_type = DP_POWER_UP_PHY; in.u.port_num.port_number = 5; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
in.req_type = DP_POWER_DOWN_PHY; in.u.port_num.port_number = 5; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
in.req_type = DP_ALLOCATE_PAYLOAD; in.u.allocate_payload.number_sdp_streams = 3; for (i = 0; i < in.u.allocate_payload.number_sdp_streams; i++) in.u.allocate_payload.sdp_stream_sink[i] = i + 1; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.allocate_payload.port_number = 0xf; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.allocate_payload.vcpi = 0x7f; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.allocate_payload.pbn = U16_MAX; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
in.req_type = DP_QUERY_PAYLOAD; in.u.query_payload.port_number = 0xf; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.query_payload.vcpi = 0x7f; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
in.req_type = DP_REMOTE_DPCD_READ; in.u.dpcd_read.port_number = 0xf; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.dpcd_read.dpcd_address = 0xfedcb; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.dpcd_read.num_bytes = U8_MAX; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
in.req_type = DP_REMOTE_DPCD_WRITE; in.u.dpcd_write.port_number = 0xf; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.dpcd_write.dpcd_address = 0xfedcb; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.dpcd_write.num_bytes = ARRAY_SIZE(data); in.u.dpcd_write.bytes = data; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
in.req_type = DP_REMOTE_I2C_READ; in.u.i2c_read.port_number = 0xf; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.i2c_read.read_i2c_device_id = 0x7f; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.i2c_read.num_transactions = 3; in.u.i2c_read.num_bytes_read = ARRAY_SIZE(data) * 3; for (i = 0; i < in.u.i2c_read.num_transactions; i++) { @@ -244,32 +240,44 @@ int igt_dp_mst_sideband_msg_req_decode(void *unused) in.u.i2c_read.transactions[i].i2c_dev_id = 0x7f & ~i; in.u.i2c_read.transactions[i].i2c_transaction_delay = 0xf & ~i; } - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
in.req_type = DP_REMOTE_I2C_WRITE; in.u.i2c_write.port_number = 0xf; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.i2c_write.write_i2c_device_id = 0x7f; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.i2c_write.num_bytes = ARRAY_SIZE(data); in.u.i2c_write.bytes = data; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in));
in.req_type = DP_QUERY_STREAM_ENC_STATUS; in.u.enc_status.stream_id = 1; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); get_random_bytes(in.u.enc_status.client_id, sizeof(in.u.enc_status.client_id)); - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.enc_status.stream_event = 3; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.enc_status.valid_stream_event = 0; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.enc_status.stream_behavior = 3; - DO_TEST(); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); in.u.enc_status.valid_stream_behavior = 1; - DO_TEST(); - -#undef DO_TEST - return 0; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); } + +static struct kunit_case drm_dp_mst_helper_tests[] = { + KUNIT_CASE(igt_dp_mst_calc_pbn_mode), + KUNIT_CASE(igt_dp_mst_sideband_msg_req_decode), + { } +}; + +static struct kunit_suite drm_dp_mst_helper_test_suite = { + .name = "drm_dp_mst_helper", + .test_cases = drm_dp_mst_helper_tests, +}; + +kunit_test_suite(drm_dp_mst_helper_test_suite); + +MODULE_LICENSE("GPL");
Considering the current adoption of the KUnit framework, convert the DRM framebuffer selftest to the KUnit API.
Tested-by: David Gow davidgow@google.com Signed-off-by: Maíra Canal maira.canal@usp.br --- drivers/gpu/drm/selftests/Makefile | 5 +-- .../gpu/drm/selftests/drm_modeset_selftests.h | 9 ------ .../drm/selftests/test-drm_modeset_common.c | 32 ------------------- .../drm/selftests/test-drm_modeset_common.h | 21 ------------ drivers/gpu/drm/tests/Makefile | 2 +- .../drm_framebuffer_test.c} | 25 ++++++++++----- 6 files changed, 19 insertions(+), 75 deletions(-) delete mode 100644 drivers/gpu/drm/selftests/drm_modeset_selftests.h delete mode 100644 drivers/gpu/drm/selftests/test-drm_modeset_common.c delete mode 100644 drivers/gpu/drm/selftests/test-drm_modeset_common.h rename drivers/gpu/drm/{selftests/test-drm_framebuffer.c => tests/drm_framebuffer_test.c} (96%)
diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index 1539f55db9a7..f7db628b60cb 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,5 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -test-drm_modeset-y := test-drm_modeset_common.o test-drm_framebuffer.o - -obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o \ - test-drm_buddy.o +obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_buddy.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h deleted file mode 100644 index 40a29b8cf386..000000000000 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* List each unit test as selftest(name, function) - * - * The name is used as both an enum and expanded as igt__name to create - * a module parameter. It must be unique and legal for a C identifier. - * - * Tests are executed in order by igt/drm_selftests_helper - */ -selftest(check_drm_framebuffer_create, igt_check_drm_framebuffer_create) diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.c b/drivers/gpu/drm/selftests/test-drm_modeset_common.c deleted file mode 100644 index 2a7f93774006..000000000000 --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.c +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Common file for modeset selftests. - */ - -#include <linux/module.h> - -#include "test-drm_modeset_common.h" - -#define TESTS "drm_modeset_selftests.h" -#include "drm_selftest.h" - -#include "drm_selftest.c" - -static int __init test_drm_modeset_init(void) -{ - int err; - - err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL); - - return err > 0 ? 0 : err; -} - -static void __exit test_drm_modeset_exit(void) -{ -} - -module_init(test_drm_modeset_init); -module_exit(test_drm_modeset_exit); - -MODULE_AUTHOR("Intel Corporation"); -MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h deleted file mode 100644 index 3feb2fea1a6b..000000000000 --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -#ifndef __TEST_DRM_MODESET_COMMON_H__ -#define __TEST_DRM_MODESET_COMMON_H__ - -#include <linux/errno.h> -#include <linux/printk.h> - -#define FAIL(test, msg, ...) \ - do { \ - if (test) { \ - pr_err("%s/%u: " msg, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - return -EINVAL; \ - } \ - } while (0) - -#define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n") - -int igt_check_drm_framebuffer_create(void *ignored); - -#endif diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index 40c003df2625..d181da7e3e6b 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -2,4 +2,4 @@
obj-$(CONFIG_DRM_KUNIT_TEST) += drm_damage_helper_test.o drm_cmdline_parser_test.o \ drm_rect_test.o drm_format_test.o drm_plane_helper_test.o \ - drm_dp_mst_helper_test.o + drm_dp_mst_helper_test.o drm_framebuffer_test.o diff --git a/drivers/gpu/drm/selftests/test-drm_framebuffer.c b/drivers/gpu/drm/tests/drm_framebuffer_test.c similarity index 96% rename from drivers/gpu/drm/selftests/test-drm_framebuffer.c rename to drivers/gpu/drm/tests/drm_framebuffer_test.c index f6d66285c5fc..a1b57703cd5a 100644 --- a/drivers/gpu/drm/selftests/test-drm_framebuffer.c +++ b/drivers/gpu/drm/tests/drm_framebuffer_test.c @@ -3,8 +3,7 @@ * Test cases for the drm_framebuffer functions */
-#include <linux/kernel.h> - +#include <kunit/test.h> #include <drm/drm_device.h> #include <drm/drm_mode.h> #include <drm/drm_fourcc.h> @@ -12,8 +11,6 @@
#include "../drm_crtc_internal.h"
-#include "test-drm_modeset_common.h" - #define MIN_WIDTH 4 #define MAX_WIDTH 4096 #define MIN_HEIGHT 4 @@ -336,15 +333,27 @@ static int execute_drm_mode_fb_cmd2(struct drm_mode_fb_cmd2 *r) return buffer_created; }
-int igt_check_drm_framebuffer_create(void *ignored) +static void igt_check_drm_framebuffer_create(struct kunit *test) { int i = 0;
for (i = 0; i < ARRAY_SIZE(createbuffer_tests); i++) { - FAIL(createbuffer_tests[i].buffer_created != + KUNIT_EXPECT_EQ_MSG(test, createbuffer_tests[i].buffer_created, execute_drm_mode_fb_cmd2(&createbuffer_tests[i].cmd), "Test %d: "%s" failed\n", i, createbuffer_tests[i].name); } - - return 0; } + +static struct kunit_case drm_framebuffer_tests[] = { + KUNIT_CASE(igt_check_drm_framebuffer_create), + { } +}; + +static struct kunit_suite drm_framebuffer_test_suite = { + .name = "drm_framebuffer", + .test_cases = drm_framebuffer_tests, +}; + +kunit_test_suite(drm_framebuffer_test_suite); + +MODULE_LICENSE("GPL");
Considering the current adoption of the KUnit framework, convert the DRM buddy selftest to the KUnit API.
Tested-by: David Gow davidgow@google.com Signed-off-by: Maíra Canal maira.canal@usp.br --- drivers/gpu/drm/selftests/Makefile | 2 +- .../gpu/drm/selftests/drm_buddy_selftests.h | 15 - drivers/gpu/drm/selftests/test-drm_buddy.c | 994 ------------------ drivers/gpu/drm/tests/Makefile | 2 +- drivers/gpu/drm/tests/drm_buddy_test.c | 748 +++++++++++++ 5 files changed, 750 insertions(+), 1011 deletions(-) delete mode 100644 drivers/gpu/drm/selftests/drm_buddy_selftests.h delete mode 100644 drivers/gpu/drm/selftests/test-drm_buddy.c create mode 100644 drivers/gpu/drm/tests/drm_buddy_test.c
diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index f7db628b60cb..a4ebecb8146b 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_buddy.o +obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o diff --git a/drivers/gpu/drm/selftests/drm_buddy_selftests.h b/drivers/gpu/drm/selftests/drm_buddy_selftests.h deleted file mode 100644 index 455b756c4ae5..000000000000 --- a/drivers/gpu/drm/selftests/drm_buddy_selftests.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* List each unit test as selftest(name, function) - * - * The name is used as both an enum and expanded as igt__name to create - * a module parameter. It must be unique and legal for a C identifier. - * - * Tests are executed in order by igt/drm_buddy - */ -selftest(sanitycheck, igt_sanitycheck) /* keep first (selfcheck for igt) */ -selftest(buddy_alloc_limit, igt_buddy_alloc_limit) -selftest(buddy_alloc_range, igt_buddy_alloc_range) -selftest(buddy_alloc_optimistic, igt_buddy_alloc_optimistic) -selftest(buddy_alloc_pessimistic, igt_buddy_alloc_pessimistic) -selftest(buddy_alloc_smoke, igt_buddy_alloc_smoke) -selftest(buddy_alloc_pathological, igt_buddy_alloc_pathological) diff --git a/drivers/gpu/drm/selftests/test-drm_buddy.c b/drivers/gpu/drm/selftests/test-drm_buddy.c deleted file mode 100644 index aca0c491040f..000000000000 --- a/drivers/gpu/drm/selftests/test-drm_buddy.c +++ /dev/null @@ -1,994 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright © 2019 Intel Corporation - */ - -#define pr_fmt(fmt) "drm_buddy: " fmt - -#include <linux/module.h> -#include <linux/prime_numbers.h> -#include <linux/sched/signal.h> - -#include <drm/drm_buddy.h> - -#include "../lib/drm_random.h" - -#define TESTS "drm_buddy_selftests.h" -#include "drm_selftest.h" - -#define IGT_TIMEOUT(name__) \ - unsigned long name__ = jiffies + MAX_SCHEDULE_TIMEOUT - -static unsigned int random_seed; - -static inline u64 get_size(int order, u64 chunk_size) -{ - return (1 << order) * chunk_size; -} - -__printf(2, 3) -static bool __igt_timeout(unsigned long timeout, const char *fmt, ...) -{ - va_list va; - - if (!signal_pending(current)) { - cond_resched(); - if (time_before(jiffies, timeout)) - return false; - } - - if (fmt) { - va_start(va, fmt); - vprintk(fmt, va); - va_end(va); - } - - return true; -} - -static inline const char *yesno(bool v) -{ - return v ? "yes" : "no"; -} - -static void __igt_dump_block(struct drm_buddy *mm, - struct drm_buddy_block *block, - bool buddy) -{ - pr_err("block info: header=%llx, state=%u, order=%d, offset=%llx size=%llx root=%s buddy=%s\n", - block->header, - drm_buddy_block_state(block), - drm_buddy_block_order(block), - drm_buddy_block_offset(block), - drm_buddy_block_size(mm, block), - yesno(!block->parent), - yesno(buddy)); -} - -static void igt_dump_block(struct drm_buddy *mm, - struct drm_buddy_block *block) -{ - struct drm_buddy_block *buddy; - - __igt_dump_block(mm, block, false); - - buddy = drm_get_buddy(block); - if (buddy) - __igt_dump_block(mm, buddy, true); -} - -static int igt_check_block(struct drm_buddy *mm, - struct drm_buddy_block *block) -{ - struct drm_buddy_block *buddy; - unsigned int block_state; - u64 block_size; - u64 offset; - int err = 0; - - block_state = drm_buddy_block_state(block); - - if (block_state != DRM_BUDDY_ALLOCATED && - block_state != DRM_BUDDY_FREE && - block_state != DRM_BUDDY_SPLIT) { - pr_err("block state mismatch\n"); - err = -EINVAL; - } - - block_size = drm_buddy_block_size(mm, block); - offset = drm_buddy_block_offset(block); - - if (block_size < mm->chunk_size) { - pr_err("block size smaller than min size\n"); - err = -EINVAL; - } - - if (!is_power_of_2(block_size)) { - pr_err("block size not power of two\n"); - err = -EINVAL; - } - - if (!IS_ALIGNED(block_size, mm->chunk_size)) { - pr_err("block size not aligned to min size\n"); - err = -EINVAL; - } - - if (!IS_ALIGNED(offset, mm->chunk_size)) { - pr_err("block offset not aligned to min size\n"); - err = -EINVAL; - } - - if (!IS_ALIGNED(offset, block_size)) { - pr_err("block offset not aligned to block size\n"); - err = -EINVAL; - } - - buddy = drm_get_buddy(block); - - if (!buddy && block->parent) { - pr_err("buddy has gone fishing\n"); - err = -EINVAL; - } - - if (buddy) { - if (drm_buddy_block_offset(buddy) != (offset ^ block_size)) { - pr_err("buddy has wrong offset\n"); - err = -EINVAL; - } - - if (drm_buddy_block_size(mm, buddy) != block_size) { - pr_err("buddy size mismatch\n"); - err = -EINVAL; - } - - if (drm_buddy_block_state(buddy) == block_state && - block_state == DRM_BUDDY_FREE) { - pr_err("block and its buddy are free\n"); - err = -EINVAL; - } - } - - return err; -} - -static int igt_check_blocks(struct drm_buddy *mm, - struct list_head *blocks, - u64 expected_size, - bool is_contiguous) -{ - struct drm_buddy_block *block; - struct drm_buddy_block *prev; - u64 total; - int err = 0; - - block = NULL; - prev = NULL; - total = 0; - - list_for_each_entry(block, blocks, link) { - err = igt_check_block(mm, block); - - if (!drm_buddy_block_is_allocated(block)) { - pr_err("block not allocated\n"), - err = -EINVAL; - } - - if (is_contiguous && prev) { - u64 prev_block_size; - u64 prev_offset; - u64 offset; - - prev_offset = drm_buddy_block_offset(prev); - prev_block_size = drm_buddy_block_size(mm, prev); - offset = drm_buddy_block_offset(block); - - if (offset != (prev_offset + prev_block_size)) { - pr_err("block offset mismatch\n"); - err = -EINVAL; - } - } - - if (err) - break; - - total += drm_buddy_block_size(mm, block); - prev = block; - } - - if (!err) { - if (total != expected_size) { - pr_err("size mismatch, expected=%llx, found=%llx\n", - expected_size, total); - err = -EINVAL; - } - return err; - } - - if (prev) { - pr_err("prev block, dump:\n"); - igt_dump_block(mm, prev); - } - - pr_err("bad block, dump:\n"); - igt_dump_block(mm, block); - - return err; -} - -static int igt_check_mm(struct drm_buddy *mm) -{ - struct drm_buddy_block *root; - struct drm_buddy_block *prev; - unsigned int i; - u64 total; - int err = 0; - - if (!mm->n_roots) { - pr_err("n_roots is zero\n"); - return -EINVAL; - } - - if (mm->n_roots != hweight64(mm->size)) { - pr_err("n_roots mismatch, n_roots=%u, expected=%lu\n", - mm->n_roots, hweight64(mm->size)); - return -EINVAL; - } - - root = NULL; - prev = NULL; - total = 0; - - for (i = 0; i < mm->n_roots; ++i) { - struct drm_buddy_block *block; - unsigned int order; - - root = mm->roots[i]; - if (!root) { - pr_err("root(%u) is NULL\n", i); - err = -EINVAL; - break; - } - - err = igt_check_block(mm, root); - - if (!drm_buddy_block_is_free(root)) { - pr_err("root not free\n"); - err = -EINVAL; - } - - order = drm_buddy_block_order(root); - - if (!i) { - if (order != mm->max_order) { - pr_err("max order root missing\n"); - err = -EINVAL; - } - } - - if (prev) { - u64 prev_block_size; - u64 prev_offset; - u64 offset; - - prev_offset = drm_buddy_block_offset(prev); - prev_block_size = drm_buddy_block_size(mm, prev); - offset = drm_buddy_block_offset(root); - - if (offset != (prev_offset + prev_block_size)) { - pr_err("root offset mismatch\n"); - err = -EINVAL; - } - } - - block = list_first_entry_or_null(&mm->free_list[order], - struct drm_buddy_block, - link); - if (block != root) { - pr_err("root mismatch at order=%u\n", order); - err = -EINVAL; - } - - if (err) - break; - - prev = root; - total += drm_buddy_block_size(mm, root); - } - - if (!err) { - if (total != mm->size) { - pr_err("expected mm size=%llx, found=%llx\n", mm->size, - total); - err = -EINVAL; - } - return err; - } - - if (prev) { - pr_err("prev root(%u), dump:\n", i - 1); - igt_dump_block(mm, prev); - } - - if (root) { - pr_err("bad root(%u), dump:\n", i); - igt_dump_block(mm, root); - } - - return err; -} - -static void igt_mm_config(u64 *size, u64 *chunk_size) -{ - DRM_RND_STATE(prng, random_seed); - u32 s, ms; - - /* Nothing fancy, just try to get an interesting bit pattern */ - - prandom_seed_state(&prng, random_seed); - - /* Let size be a random number of pages up to 8 GB (2M pages) */ - s = 1 + drm_prandom_u32_max_state((BIT(33 - 12)) - 1, &prng); - /* Let the chunk size be a random power of 2 less than size */ - ms = BIT(drm_prandom_u32_max_state(ilog2(s), &prng)); - /* Round size down to the chunk size */ - s &= -ms; - - /* Convert from pages to bytes */ - *chunk_size = (u64)ms << 12; - *size = (u64)s << 12; -} - -static int igt_buddy_alloc_pathological(void *arg) -{ - u64 mm_size, size, min_page_size, start = 0; - struct drm_buddy_block *block; - const int max_order = 3; - unsigned long flags = 0; - int order, top, err; - struct drm_buddy mm; - LIST_HEAD(blocks); - LIST_HEAD(holes); - LIST_HEAD(tmp); - - /* - * Create a pot-sized mm, then allocate one of each possible - * order within. This should leave the mm with exactly one - * page left. Free the largest block, then whittle down again. - * Eventually we will have a fully 50% fragmented mm. - */ - - mm_size = PAGE_SIZE << max_order; - err = drm_buddy_init(&mm, mm_size, PAGE_SIZE); - if (err) { - pr_err("buddy_init failed(%d)\n", err); - return err; - } - BUG_ON(mm.max_order != max_order); - - for (top = max_order; top; top--) { - /* Make room by freeing the largest allocated block */ - block = list_first_entry_or_null(&blocks, typeof(*block), link); - if (block) { - list_del(&block->link); - drm_buddy_free_block(&mm, block); - } - - for (order = top; order--; ) { - size = min_page_size = get_size(order, PAGE_SIZE); - err = drm_buddy_alloc_blocks(&mm, start, mm_size, size, - min_page_size, &tmp, flags); - if (err) { - pr_info("buddy_alloc hit -ENOMEM with order=%d, top=%d\n", - order, top); - goto err; - } - - block = list_first_entry_or_null(&tmp, - struct drm_buddy_block, - link); - if (!block) { - pr_err("alloc_blocks has no blocks\n"); - err = -EINVAL; - goto err; - } - - list_move_tail(&block->link, &blocks); - } - - /* There should be one final page for this sub-allocation */ - size = min_page_size = get_size(0, PAGE_SIZE); - err = drm_buddy_alloc_blocks(&mm, start, mm_size, size, min_page_size, &tmp, flags); - if (err) { - pr_info("buddy_alloc hit -ENOMEM for hole\n"); - goto err; - } - - block = list_first_entry_or_null(&tmp, - struct drm_buddy_block, - link); - if (!block) { - pr_err("alloc_blocks has no blocks\n"); - err = -EINVAL; - goto err; - } - - list_move_tail(&block->link, &holes); - - size = min_page_size = get_size(top, PAGE_SIZE); - err = drm_buddy_alloc_blocks(&mm, start, mm_size, size, min_page_size, &tmp, flags); - if (!err) { - pr_info("buddy_alloc unexpectedly succeeded at top-order %d/%d, it should be full!", - top, max_order); - block = list_first_entry_or_null(&tmp, - struct drm_buddy_block, - link); - if (!block) { - pr_err("alloc_blocks has no blocks\n"); - err = -EINVAL; - goto err; - } - - list_move_tail(&block->link, &blocks); - err = -EINVAL; - goto err; - } - } - - drm_buddy_free_list(&mm, &holes); - - /* Nothing larger than blocks of chunk_size now available */ - for (order = 1; order <= max_order; order++) { - size = min_page_size = get_size(order, PAGE_SIZE); - err = drm_buddy_alloc_blocks(&mm, start, mm_size, size, min_page_size, &tmp, flags); - if (!err) { - pr_info("buddy_alloc unexpectedly succeeded at order %d, it should be full!", - order); - block = list_first_entry_or_null(&tmp, - struct drm_buddy_block, - link); - if (!block) { - pr_err("alloc_blocks has no blocks\n"); - err = -EINVAL; - goto err; - } - - list_move_tail(&block->link, &blocks); - err = -EINVAL; - goto err; - } - } - - if (err) - err = 0; - -err: - list_splice_tail(&holes, &blocks); - drm_buddy_free_list(&mm, &blocks); - drm_buddy_fini(&mm); - return err; -} - -static int igt_buddy_alloc_smoke(void *arg) -{ - u64 mm_size, min_page_size, chunk_size, start = 0; - unsigned long flags = 0; - struct drm_buddy mm; - int *order; - int err, i; - - DRM_RND_STATE(prng, random_seed); - IGT_TIMEOUT(end_time); - - igt_mm_config(&mm_size, &chunk_size); - - err = drm_buddy_init(&mm, mm_size, chunk_size); - if (err) { - pr_err("buddy_init failed(%d)\n", err); - return err; - } - - order = drm_random_order(mm.max_order + 1, &prng); - if (!order) { - err = -ENOMEM; - goto out_fini; - } - - for (i = 0; i <= mm.max_order; ++i) { - struct drm_buddy_block *block; - int max_order = order[i]; - bool timeout = false; - LIST_HEAD(blocks); - u64 total, size; - LIST_HEAD(tmp); - int order; - - err = igt_check_mm(&mm); - if (err) { - pr_err("pre-mm check failed, abort\n"); - break; - } - - order = max_order; - total = 0; - - do { -retry: - size = min_page_size = get_size(order, chunk_size); - err = drm_buddy_alloc_blocks(&mm, start, mm_size, size, - min_page_size, &tmp, flags); - if (err) { - if (err == -ENOMEM) { - pr_info("buddy_alloc hit -ENOMEM with order=%d\n", - order); - } else { - if (order--) { - err = 0; - goto retry; - } - - pr_err("buddy_alloc with order=%d failed(%d)\n", - order, err); - } - - break; - } - - block = list_first_entry_or_null(&tmp, - struct drm_buddy_block, - link); - if (!block) { - pr_err("alloc_blocks has no blocks\n"); - err = -EINVAL; - break; - } - - list_move_tail(&block->link, &blocks); - - if (drm_buddy_block_order(block) != order) { - pr_err("buddy_alloc order mismatch\n"); - err = -EINVAL; - break; - } - - total += drm_buddy_block_size(&mm, block); - - if (__igt_timeout(end_time, NULL)) { - timeout = true; - break; - } - } while (total < mm.size); - - if (!err) - err = igt_check_blocks(&mm, &blocks, total, false); - - drm_buddy_free_list(&mm, &blocks); - - if (!err) { - err = igt_check_mm(&mm); - if (err) - pr_err("post-mm check failed\n"); - } - - if (err || timeout) - break; - - cond_resched(); - } - - if (err == -ENOMEM) - err = 0; - - kfree(order); -out_fini: - drm_buddy_fini(&mm); - - return err; -} - -static int igt_buddy_alloc_pessimistic(void *arg) -{ - u64 mm_size, size, min_page_size, start = 0; - struct drm_buddy_block *block, *bn; - const unsigned int max_order = 16; - unsigned long flags = 0; - struct drm_buddy mm; - unsigned int order; - LIST_HEAD(blocks); - LIST_HEAD(tmp); - int err; - - /* - * Create a pot-sized mm, then allocate one of each possible - * order within. This should leave the mm with exactly one - * page left. - */ - - mm_size = PAGE_SIZE << max_order; - err = drm_buddy_init(&mm, mm_size, PAGE_SIZE); - if (err) { - pr_err("buddy_init failed(%d)\n", err); - return err; - } - BUG_ON(mm.max_order != max_order); - - for (order = 0; order < max_order; order++) { - size = min_page_size = get_size(order, PAGE_SIZE); - err = drm_buddy_alloc_blocks(&mm, start, mm_size, size, min_page_size, &tmp, flags); - if (err) { - pr_info("buddy_alloc hit -ENOMEM with order=%d\n", - order); - goto err; - } - - block = list_first_entry_or_null(&tmp, - struct drm_buddy_block, - link); - if (!block) { - pr_err("alloc_blocks has no blocks\n"); - err = -EINVAL; - goto err; - } - - list_move_tail(&block->link, &blocks); - } - - /* And now the last remaining block available */ - size = min_page_size = get_size(0, PAGE_SIZE); - err = drm_buddy_alloc_blocks(&mm, start, mm_size, size, min_page_size, &tmp, flags); - if (err) { - pr_info("buddy_alloc hit -ENOMEM on final alloc\n"); - goto err; - } - - block = list_first_entry_or_null(&tmp, - struct drm_buddy_block, - link); - if (!block) { - pr_err("alloc_blocks has no blocks\n"); - err = -EINVAL; - goto err; - } - - list_move_tail(&block->link, &blocks); - - /* Should be completely full! */ - for (order = max_order; order--; ) { - size = min_page_size = get_size(order, PAGE_SIZE); - err = drm_buddy_alloc_blocks(&mm, start, mm_size, size, min_page_size, &tmp, flags); - if (!err) { - pr_info("buddy_alloc unexpectedly succeeded at order %d, it should be full!", - order); - block = list_first_entry_or_null(&tmp, - struct drm_buddy_block, - link); - if (!block) { - pr_err("alloc_blocks has no blocks\n"); - err = -EINVAL; - goto err; - } - - list_move_tail(&block->link, &blocks); - err = -EINVAL; - goto err; - } - } - - block = list_last_entry(&blocks, typeof(*block), link); - list_del(&block->link); - drm_buddy_free_block(&mm, block); - - /* As we free in increasing size, we make available larger blocks */ - order = 1; - list_for_each_entry_safe(block, bn, &blocks, link) { - list_del(&block->link); - drm_buddy_free_block(&mm, block); - - size = min_page_size = get_size(order, PAGE_SIZE); - err = drm_buddy_alloc_blocks(&mm, start, mm_size, size, min_page_size, &tmp, flags); - if (err) { - pr_info("buddy_alloc (realloc) hit -ENOMEM with order=%d\n", - order); - goto err; - } - - block = list_first_entry_or_null(&tmp, - struct drm_buddy_block, - link); - if (!block) { - pr_err("alloc_blocks has no blocks\n"); - err = -EINVAL; - goto err; - } - - list_del(&block->link); - drm_buddy_free_block(&mm, block); - order++; - } - - /* To confirm, now the whole mm should be available */ - size = min_page_size = get_size(max_order, PAGE_SIZE); - err = drm_buddy_alloc_blocks(&mm, start, mm_size, size, min_page_size, &tmp, flags); - if (err) { - pr_info("buddy_alloc (realloc) hit -ENOMEM with order=%d\n", - max_order); - goto err; - } - - block = list_first_entry_or_null(&tmp, - struct drm_buddy_block, - link); - if (!block) { - pr_err("alloc_blocks has no blocks\n"); - err = -EINVAL; - goto err; - } - - list_del(&block->link); - drm_buddy_free_block(&mm, block); - -err: - drm_buddy_free_list(&mm, &blocks); - drm_buddy_fini(&mm); - return err; -} - -static int igt_buddy_alloc_optimistic(void *arg) -{ - u64 mm_size, size, min_page_size, start = 0; - struct drm_buddy_block *block; - unsigned long flags = 0; - const int max_order = 16; - struct drm_buddy mm; - LIST_HEAD(blocks); - LIST_HEAD(tmp); - int order, err; - - /* - * Create a mm with one block of each order available, and - * try to allocate them all. - */ - - mm_size = PAGE_SIZE * ((1 << (max_order + 1)) - 1); - err = drm_buddy_init(&mm, - mm_size, - PAGE_SIZE); - if (err) { - pr_err("buddy_init failed(%d)\n", err); - return err; - } - - BUG_ON(mm.max_order != max_order); - - for (order = 0; order <= max_order; order++) { - size = min_page_size = get_size(order, PAGE_SIZE); - err = drm_buddy_alloc_blocks(&mm, start, mm_size, size, min_page_size, &tmp, flags); - if (err) { - pr_info("buddy_alloc hit -ENOMEM with order=%d\n", - order); - goto err; - } - - block = list_first_entry_or_null(&tmp, - struct drm_buddy_block, - link); - if (!block) { - pr_err("alloc_blocks has no blocks\n"); - err = -EINVAL; - goto err; - } - - list_move_tail(&block->link, &blocks); - } - - /* Should be completely full! */ - size = min_page_size = get_size(0, PAGE_SIZE); - err = drm_buddy_alloc_blocks(&mm, start, mm_size, size, min_page_size, &tmp, flags); - if (!err) { - pr_info("buddy_alloc unexpectedly succeeded, it should be full!"); - block = list_first_entry_or_null(&tmp, - struct drm_buddy_block, - link); - if (!block) { - pr_err("alloc_blocks has no blocks\n"); - err = -EINVAL; - goto err; - } - - list_move_tail(&block->link, &blocks); - err = -EINVAL; - goto err; - } else { - err = 0; - } - -err: - drm_buddy_free_list(&mm, &blocks); - drm_buddy_fini(&mm); - return err; -} - -static int igt_buddy_alloc_range(void *arg) -{ - unsigned long flags = DRM_BUDDY_RANGE_ALLOCATION; - u64 offset, size, rem, chunk_size, end; - unsigned long page_num; - struct drm_buddy mm; - LIST_HEAD(blocks); - int err; - - igt_mm_config(&size, &chunk_size); - - err = drm_buddy_init(&mm, size, chunk_size); - if (err) { - pr_err("buddy_init failed(%d)\n", err); - return err; - } - - err = igt_check_mm(&mm); - if (err) { - pr_err("pre-mm check failed, abort, abort, abort!\n"); - goto err_fini; - } - - rem = mm.size; - offset = 0; - - for_each_prime_number_from(page_num, 1, ULONG_MAX - 1) { - struct drm_buddy_block *block; - LIST_HEAD(tmp); - - size = min(page_num * mm.chunk_size, rem); - end = offset + size; - - err = drm_buddy_alloc_blocks(&mm, offset, end, size, mm.chunk_size, &tmp, flags); - if (err) { - if (err == -ENOMEM) { - pr_info("alloc_range hit -ENOMEM with size=%llx\n", - size); - } else { - pr_err("alloc_range with offset=%llx, size=%llx failed(%d)\n", - offset, size, err); - } - - break; - } - - block = list_first_entry_or_null(&tmp, - struct drm_buddy_block, - link); - if (!block) { - pr_err("alloc_range has no blocks\n"); - err = -EINVAL; - break; - } - - if (drm_buddy_block_offset(block) != offset) { - pr_err("alloc_range start offset mismatch, found=%llx, expected=%llx\n", - drm_buddy_block_offset(block), offset); - err = -EINVAL; - } - - if (!err) - err = igt_check_blocks(&mm, &tmp, size, true); - - list_splice_tail(&tmp, &blocks); - - if (err) - break; - - offset += size; - - rem -= size; - if (!rem) - break; - - cond_resched(); - } - - if (err == -ENOMEM) - err = 0; - - drm_buddy_free_list(&mm, &blocks); - - if (!err) { - err = igt_check_mm(&mm); - if (err) - pr_err("post-mm check failed\n"); - } - -err_fini: - drm_buddy_fini(&mm); - - return err; -} - -static int igt_buddy_alloc_limit(void *arg) -{ - u64 size = U64_MAX, start = 0; - struct drm_buddy_block *block; - unsigned long flags = 0; - LIST_HEAD(allocated); - struct drm_buddy mm; - int err; - - err = drm_buddy_init(&mm, size, PAGE_SIZE); - if (err) - return err; - - if (mm.max_order != DRM_BUDDY_MAX_ORDER) { - pr_err("mm.max_order(%d) != %d\n", - mm.max_order, DRM_BUDDY_MAX_ORDER); - err = -EINVAL; - goto out_fini; - } - - size = mm.chunk_size << mm.max_order; - err = drm_buddy_alloc_blocks(&mm, start, size, size, - PAGE_SIZE, &allocated, flags); - - if (unlikely(err)) - goto out_free; - - block = list_first_entry_or_null(&allocated, - struct drm_buddy_block, - link); - - if (!block) { - err = -EINVAL; - goto out_fini; - } - - if (drm_buddy_block_order(block) != mm.max_order) { - pr_err("block order(%d) != %d\n", - drm_buddy_block_order(block), mm.max_order); - err = -EINVAL; - goto out_free; - } - - if (drm_buddy_block_size(&mm, block) != - BIT_ULL(mm.max_order) * PAGE_SIZE) { - pr_err("block size(%llu) != %llu\n", - drm_buddy_block_size(&mm, block), - BIT_ULL(mm.max_order) * PAGE_SIZE); - err = -EINVAL; - goto out_free; - } - -out_free: - drm_buddy_free_list(&mm, &allocated); -out_fini: - drm_buddy_fini(&mm); - return err; -} - -static int igt_sanitycheck(void *ignored) -{ - pr_info("%s - ok!\n", __func__); - return 0; -} - -#include "drm_selftest.c" - -static int __init test_drm_buddy_init(void) -{ - int err; - - while (!random_seed) - random_seed = get_random_int(); - - pr_info("Testing DRM buddy manager (struct drm_buddy), with random_seed=0x%x\n", - random_seed); - err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL); - - return err > 0 ? 0 : err; -} - -static void __exit test_drm_buddy_exit(void) -{ -} - -module_init(test_drm_buddy_init); -module_exit(test_drm_buddy_exit); - -MODULE_AUTHOR("Intel Corporation"); -MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index d181da7e3e6b..15a3efb2cf8e 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -2,4 +2,4 @@
obj-$(CONFIG_DRM_KUNIT_TEST) += drm_damage_helper_test.o drm_cmdline_parser_test.o \ drm_rect_test.o drm_format_test.o drm_plane_helper_test.o \ - drm_dp_mst_helper_test.o drm_framebuffer_test.o + drm_dp_mst_helper_test.o drm_framebuffer_test.o drm_buddy_test.o diff --git a/drivers/gpu/drm/tests/drm_buddy_test.c b/drivers/gpu/drm/tests/drm_buddy_test.c new file mode 100644 index 000000000000..7f273a70d6ff --- /dev/null +++ b/drivers/gpu/drm/tests/drm_buddy_test.c @@ -0,0 +1,748 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2019 Intel Corporation + */ + +#include <kunit/test.h> +#include <linux/prime_numbers.h> +#include <linux/sched/signal.h> + +#include <drm/drm_buddy.h> + +#include "../lib/drm_random.h" + +#define IGT_TIMEOUT(name__) \ + unsigned long name__ = jiffies + MAX_SCHEDULE_TIMEOUT + +static unsigned int random_seed; + +static inline u64 get_size(int order, u64 chunk_size) +{ + return (1 << order) * chunk_size; +} + +__printf(2, 3) +static bool __igt_timeout(unsigned long timeout, const char *fmt, ...) +{ + va_list va; + + if (!signal_pending(current)) { + cond_resched(); + if (time_before(jiffies, timeout)) + return false; + } + + if (fmt) { + va_start(va, fmt); + vprintk(fmt, va); + va_end(va); + } + + return true; +} + +static void __igt_dump_block(struct kunit *test, struct drm_buddy *mm, + struct drm_buddy_block *block, bool buddy) +{ + kunit_err(test, "block info: header=%llx, state=%u, order=%d, offset=%llx size=%llx root=%d buddy=%d\n", + block->header, drm_buddy_block_state(block), + drm_buddy_block_order(block), drm_buddy_block_offset(block), + drm_buddy_block_size(mm, block), !block->parent, buddy); +} + +static void igt_dump_block(struct kunit *test, struct drm_buddy *mm, + struct drm_buddy_block *block) +{ + struct drm_buddy_block *buddy; + + __igt_dump_block(test, mm, block, false); + + buddy = drm_get_buddy(block); + if (buddy) + __igt_dump_block(test, mm, buddy, true); +} + +static int igt_check_block(struct kunit *test, struct drm_buddy *mm, + struct drm_buddy_block *block) +{ + struct drm_buddy_block *buddy; + unsigned int block_state; + u64 block_size; + u64 offset; + int err = 0; + + block_state = drm_buddy_block_state(block); + + if (block_state != DRM_BUDDY_ALLOCATED && + block_state != DRM_BUDDY_FREE && block_state != DRM_BUDDY_SPLIT) { + kunit_err(test, "block state mismatch\n"); + err = -EINVAL; + } + + block_size = drm_buddy_block_size(mm, block); + offset = drm_buddy_block_offset(block); + + if (block_size < mm->chunk_size) { + kunit_err(test, "block size smaller than min size\n"); + err = -EINVAL; + } + + if (!is_power_of_2(block_size)) { + kunit_err(test, "block size not power of two\n"); + err = -EINVAL; + } + + if (!IS_ALIGNED(block_size, mm->chunk_size)) { + kunit_err(test, "block size not aligned to min size\n"); + err = -EINVAL; + } + + if (!IS_ALIGNED(offset, mm->chunk_size)) { + kunit_err(test, "block offset not aligned to min size\n"); + err = -EINVAL; + } + + if (!IS_ALIGNED(offset, block_size)) { + kunit_err(test, "block offset not aligned to block size\n"); + err = -EINVAL; + } + + buddy = drm_get_buddy(block); + + if (!buddy && block->parent) { + kunit_err(test, "buddy has gone fishing\n"); + err = -EINVAL; + } + + if (buddy) { + if (drm_buddy_block_offset(buddy) != (offset ^ block_size)) { + kunit_err(test, "buddy has wrong offset\n"); + err = -EINVAL; + } + + if (drm_buddy_block_size(mm, buddy) != block_size) { + kunit_err(test, "buddy size mismatch\n"); + err = -EINVAL; + } + + if (drm_buddy_block_state(buddy) == block_state && + block_state == DRM_BUDDY_FREE) { + kunit_err(test, "block and its buddy are free\n"); + err = -EINVAL; + } + } + + return err; +} + +static int igt_check_blocks(struct kunit *test, struct drm_buddy *mm, + struct list_head *blocks, u64 expected_size, bool is_contiguous) +{ + struct drm_buddy_block *block; + struct drm_buddy_block *prev; + u64 total; + int err = 0; + + block = NULL; + prev = NULL; + total = 0; + + list_for_each_entry(block, blocks, link) { + err = igt_check_block(test, mm, block); + + if (!drm_buddy_block_is_allocated(block)) { + kunit_err(test, "block not allocated\n"); + err = -EINVAL; + } + + if (is_contiguous && prev) { + u64 prev_block_size; + u64 prev_offset; + u64 offset; + + prev_offset = drm_buddy_block_offset(prev); + prev_block_size = drm_buddy_block_size(mm, prev); + offset = drm_buddy_block_offset(block); + + if (offset != (prev_offset + prev_block_size)) { + kunit_err(test, "block offset mismatch\n"); + err = -EINVAL; + } + } + + if (err) + break; + + total += drm_buddy_block_size(mm, block); + prev = block; + } + + if (!err) { + if (total != expected_size) { + kunit_err(test, "size mismatch, expected=%llx, found=%llx\n", + expected_size, total); + err = -EINVAL; + } + return err; + } + + if (prev) { + kunit_err(test, "prev block, dump:\n"); + igt_dump_block(test, mm, prev); + } + + kunit_err(test, "bad block, dump:\n"); + igt_dump_block(test, mm, block); + + return err; +} + +static int igt_check_mm(struct kunit *test, struct drm_buddy *mm) +{ + struct drm_buddy_block *root; + struct drm_buddy_block *prev; + unsigned int i; + u64 total; + int err = 0; + + if (!mm->n_roots) { + kunit_err(test, "n_roots is zero\n"); + return -EINVAL; + } + + if (mm->n_roots != hweight64(mm->size)) { + kunit_err(test, "n_roots mismatch, n_roots=%u, expected=%lu\n", + mm->n_roots, hweight64(mm->size)); + return -EINVAL; + } + + root = NULL; + prev = NULL; + total = 0; + + for (i = 0; i < mm->n_roots; ++i) { + struct drm_buddy_block *block; + unsigned int order; + + root = mm->roots[i]; + if (!root) { + kunit_err(test, "root(%u) is NULL\n", i); + err = -EINVAL; + break; + } + + err = igt_check_block(test, mm, root); + + if (!drm_buddy_block_is_free(root)) { + kunit_err(test, "root not free\n"); + err = -EINVAL; + } + + order = drm_buddy_block_order(root); + + if (!i) { + if (order != mm->max_order) { + kunit_err(test, "max order root missing\n"); + err = -EINVAL; + } + } + + if (prev) { + u64 prev_block_size; + u64 prev_offset; + u64 offset; + + prev_offset = drm_buddy_block_offset(prev); + prev_block_size = drm_buddy_block_size(mm, prev); + offset = drm_buddy_block_offset(root); + + if (offset != (prev_offset + prev_block_size)) { + kunit_err(test, "root offset mismatch\n"); + err = -EINVAL; + } + } + + block = list_first_entry_or_null(&mm->free_list[order], + struct drm_buddy_block, link); + if (block != root) { + kunit_err(test, "root mismatch at order=%u\n", order); + err = -EINVAL; + } + + if (err) + break; + + prev = root; + total += drm_buddy_block_size(mm, root); + } + + if (!err) { + if (total != mm->size) { + kunit_err(test, "expected mm size=%llx, found=%llx\n", + mm->size, total); + err = -EINVAL; + } + return err; + } + + if (prev) { + kunit_err(test, "prev root(%u), dump:\n", i - 1); + igt_dump_block(test, mm, prev); + } + + if (root) { + kunit_err(test, "bad root(%u), dump:\n", i); + igt_dump_block(test, mm, root); + } + + return err; +} + +static void igt_mm_config(u64 *size, u64 *chunk_size) +{ + DRM_RND_STATE(prng, random_seed); + u32 s, ms; + + /* Nothing fancy, just try to get an interesting bit pattern */ + + prandom_seed_state(&prng, random_seed); + + /* Let size be a random number of pages up to 8 GB (2M pages) */ + s = 1 + drm_prandom_u32_max_state((BIT(33 - 12)) - 1, &prng); + /* Let the chunk size be a random power of 2 less than size */ + ms = BIT(drm_prandom_u32_max_state(ilog2(s), &prng)); + /* Round size down to the chunk size */ + s &= -ms; + + /* Convert from pages to bytes */ + *chunk_size = (u64)ms << 12; + *size = (u64)s << 12; +} + +static void igt_buddy_alloc_pathological(struct kunit *test) +{ + u64 mm_size, size, start = 0; + struct drm_buddy_block *block; + const int max_order = 3; + unsigned long flags = 0; + int order, top; + struct drm_buddy mm; + LIST_HEAD(blocks); + LIST_HEAD(holes); + LIST_HEAD(tmp); + + /* + * Create a pot-sized mm, then allocate one of each possible + * order within. This should leave the mm with exactly one + * page left. Free the largest block, then whittle down again. + * Eventually we will have a fully 50% fragmented mm. + */ + + mm_size = PAGE_SIZE << max_order; + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, PAGE_SIZE), + "buddy_init failed\n"); + + KUNIT_EXPECT_EQ(test, mm.max_order, max_order); + + for (top = max_order; top; top--) { + /* Make room by freeing the largest allocated block */ + block = list_first_entry_or_null(&blocks, typeof(*block), link); + if (block) { + list_del(&block->link); + drm_buddy_free_block(&mm, block); + } + + for (order = top; order--;) { + size = get_size(order, PAGE_SIZE); + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, start, + mm_size, size, size, &tmp, flags), + "buddy_alloc hit -ENOMEM with order=%d, top=%d\n", + order, top); + + block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link); + KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n"); + + list_move_tail(&block->link, &blocks); + } + + /* There should be one final page for this sub-allocation */ + size = get_size(0, PAGE_SIZE); + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size, + size, size, &tmp, flags), + "buddy_alloc hit -ENOMEM for hole\n"); + + block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link); + KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n"); + + list_move_tail(&block->link, &holes); + + size = get_size(top, PAGE_SIZE); + KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size, + size, size, &tmp, flags), + "buddy_alloc unexpectedly succeeded at top-order %d/%d, it should be full!", + top, max_order); + } + + drm_buddy_free_list(&mm, &holes); + + /* Nothing larger than blocks of chunk_size now available */ + for (order = 1; order <= max_order; order++) { + size = get_size(order, PAGE_SIZE); + KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size, + size, size, &tmp, flags), + "buddy_alloc unexpectedly succeeded at order %d, it should be full!", + order); + } + + list_splice_tail(&holes, &blocks); + drm_buddy_free_list(&mm, &blocks); + drm_buddy_fini(&mm); +} + +static void igt_buddy_alloc_smoke(struct kunit *test) +{ + u64 mm_size, chunk_size, start = 0; + unsigned long flags = 0; + struct drm_buddy mm; + int *order; + int i; + + DRM_RND_STATE(prng, random_seed); + IGT_TIMEOUT(end_time); + + igt_mm_config(&mm_size, &chunk_size); + + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, chunk_size), + "buddy_init failed\n"); + + order = drm_random_order(mm.max_order + 1, &prng); + KUNIT_ASSERT_TRUE(test, order); + + for (i = 0; i <= mm.max_order; ++i) { + struct drm_buddy_block *block; + int max_order = order[i]; + bool timeout = false; + LIST_HEAD(blocks); + u64 total, size; + LIST_HEAD(tmp); + int order, err; + + KUNIT_ASSERT_FALSE_MSG(test, igt_check_mm(test, &mm), + "pre-mm check failed, abort\n"); + + order = max_order; + total = 0; + + do { +retry: + size = get_size(order, chunk_size); + err = drm_buddy_alloc_blocks(&mm, start, mm_size, size, size, &tmp, flags); + if (err) { + if (err == -ENOMEM) { + KUNIT_FAIL(test, "buddy_alloc hit -ENOMEM with order=%d\n", + order); + } else { + if (order--) { + err = 0; + goto retry; + } + + KUNIT_FAIL(test, "buddy_alloc with order=%d failed\n", order); + } + + break; + } + + block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link); + KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n"); + + list_move_tail(&block->link, &blocks); + KUNIT_EXPECT_EQ_MSG(test, drm_buddy_block_order(block), order, + "buddy_alloc order mismatch\n"); + + total += drm_buddy_block_size(&mm, block); + + if (__igt_timeout(end_time, NULL)) { + timeout = true; + break; + } + } while (total < mm.size); + + if (!err) + err = igt_check_blocks(test, &mm, &blocks, total, false); + + drm_buddy_free_list(&mm, &blocks); + + if (!err) { + KUNIT_EXPECT_FALSE_MSG(test, igt_check_mm(test, &mm), + "post-mm check failed\n"); + } + + if (err || timeout) + break; + + cond_resched(); + } + + kfree(order); + drm_buddy_fini(&mm); +} + +static void igt_buddy_alloc_pessimistic(struct kunit *test) +{ + u64 mm_size, size, start = 0; + struct drm_buddy_block *block, *bn; + const unsigned int max_order = 16; + unsigned long flags = 0; + struct drm_buddy mm; + unsigned int order; + LIST_HEAD(blocks); + LIST_HEAD(tmp); + + /* + * Create a pot-sized mm, then allocate one of each possible + * order within. This should leave the mm with exactly one + * page left. + */ + + mm_size = PAGE_SIZE << max_order; + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, PAGE_SIZE), + "buddy_init failed\n"); + + KUNIT_EXPECT_EQ(test, mm.max_order, max_order); + + for (order = 0; order < max_order; order++) { + size = get_size(order, PAGE_SIZE); + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size, + size, size, &tmp, flags), + "buddy_alloc hit -ENOMEM with order=%d\n", order); + + block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link); + KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n"); + + list_move_tail(&block->link, &blocks); + } + + /* And now the last remaining block available */ + size = get_size(0, PAGE_SIZE); + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size, + size, size, &tmp, flags), + "buddy_alloc hit -ENOMEM on final alloc\n"); + + block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link); + KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n"); + + list_move_tail(&block->link, &blocks); + + /* Should be completely full! */ + for (order = max_order; order--;) { + size = get_size(order, PAGE_SIZE); + KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size, + size, size, &tmp, flags), + "buddy_alloc unexpectedly succeeded, it should be full!"); + } + + block = list_last_entry(&blocks, typeof(*block), link); + list_del(&block->link); + drm_buddy_free_block(&mm, block); + + /* As we free in increasing size, we make available larger blocks */ + order = 1; + list_for_each_entry_safe(block, bn, &blocks, link) { + list_del(&block->link); + drm_buddy_free_block(&mm, block); + + size = get_size(order, PAGE_SIZE); + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size, + size, size, &tmp, flags), + "buddy_alloc hit -ENOMEM with order=%d\n", order); + + block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link); + KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n"); + + list_del(&block->link); + drm_buddy_free_block(&mm, block); + order++; + } + + /* To confirm, now the whole mm should be available */ + size = get_size(max_order, PAGE_SIZE); + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size, + size, size, &tmp, flags), + "buddy_alloc (realloc) hit -ENOMEM with order=%d\n", max_order); + + block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link); + KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n"); + + list_del(&block->link); + drm_buddy_free_block(&mm, block); + drm_buddy_free_list(&mm, &blocks); + drm_buddy_fini(&mm); +} + +static void igt_buddy_alloc_optimistic(struct kunit *test) +{ + u64 mm_size, size, start = 0; + struct drm_buddy_block *block; + unsigned long flags = 0; + const int max_order = 16; + struct drm_buddy mm; + LIST_HEAD(blocks); + LIST_HEAD(tmp); + int order; + + /* + * Create a mm with one block of each order available, and + * try to allocate them all. + */ + + mm_size = PAGE_SIZE * ((1 << (max_order + 1)) - 1); + + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, PAGE_SIZE), + "buddy_init failed\n"); + + KUNIT_EXPECT_EQ(test, mm.max_order, max_order); + + for (order = 0; order <= max_order; order++) { + size = get_size(order, PAGE_SIZE); + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size, + size, size, &tmp, flags), + "buddy_alloc hit -ENOMEM with order=%d\n", order); + + block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link); + KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_blocks has no blocks\n"); + + list_move_tail(&block->link, &blocks); + } + + /* Should be completely full! */ + size = get_size(0, PAGE_SIZE); + KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, start, mm_size, + size, size, &tmp, flags), + "buddy_alloc unexpectedly succeeded, it should be full!"); + + drm_buddy_free_list(&mm, &blocks); + drm_buddy_fini(&mm); +} + +static void igt_buddy_alloc_range(struct kunit *test) +{ + unsigned long flags = DRM_BUDDY_RANGE_ALLOCATION; + u64 offset, size, rem, chunk_size, end; + unsigned long page_num; + struct drm_buddy mm; + LIST_HEAD(blocks); + + igt_mm_config(&size, &chunk_size); + + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, size, chunk_size), + "buddy_init failed"); + + KUNIT_ASSERT_FALSE_MSG(test, igt_check_mm(test, &mm), + "pre-mm check failed, abort!"); + + rem = mm.size; + offset = 0; + + for_each_prime_number_from(page_num, 1, ULONG_MAX - 1) { + struct drm_buddy_block *block; + LIST_HEAD(tmp); + + size = min(page_num * mm.chunk_size, rem); + end = offset + size; + + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, offset, end, + size, mm.chunk_size, &tmp, flags), + "alloc_range with offset=%llx, size=%llx failed\n", + offset, size); + + block = list_first_entry_or_null(&tmp, struct drm_buddy_block, link); + KUNIT_ASSERT_TRUE_MSG(test, block, "alloc_range has no blocks\n"); + + KUNIT_ASSERT_EQ_MSG(test, drm_buddy_block_offset(block), offset, + "alloc_range start offset mismatch, found=%llx, expected=%llx\n", + drm_buddy_block_offset(block), offset); + + KUNIT_ASSERT_FALSE(test, igt_check_blocks(test, &mm, &tmp, size, true)); + + list_splice_tail(&tmp, &blocks); + + offset += size; + + rem -= size; + if (!rem) + break; + + cond_resched(); + } + + drm_buddy_free_list(&mm, &blocks); + + KUNIT_EXPECT_FALSE_MSG(test, igt_check_mm(test, &mm), "post-mm check failed\n"); + + drm_buddy_fini(&mm); +} + +static void igt_buddy_alloc_limit(struct kunit *test) +{ + u64 size = U64_MAX, start = 0; + struct drm_buddy_block *block; + unsigned long flags = 0; + LIST_HEAD(allocated); + struct drm_buddy mm; + + KUNIT_EXPECT_FALSE(test, drm_buddy_init(&mm, size, PAGE_SIZE)); + + KUNIT_EXPECT_EQ_MSG(test, mm.max_order, DRM_BUDDY_MAX_ORDER, + "mm.max_order(%d) != %d\n", mm.max_order, + DRM_BUDDY_MAX_ORDER); + + size = mm.chunk_size << mm.max_order; + KUNIT_EXPECT_FALSE(test, drm_buddy_alloc_blocks(&mm, start, size, size, + PAGE_SIZE, &allocated, flags)); + + block = list_first_entry_or_null(&allocated, struct drm_buddy_block, link); + KUNIT_EXPECT_TRUE(test, block); + + KUNIT_EXPECT_EQ_MSG(test, drm_buddy_block_order(block), mm.max_order, + "block order(%d) != %d\n", + drm_buddy_block_order(block), mm.max_order); + + KUNIT_EXPECT_EQ_MSG(test, drm_buddy_block_size(&mm, block), + BIT_ULL(mm.max_order) * PAGE_SIZE, + "block size(%llu) != %llu\n", + drm_buddy_block_size(&mm, block), + BIT_ULL(mm.max_order) * PAGE_SIZE); + + drm_buddy_free_list(&mm, &allocated); + drm_buddy_fini(&mm); +} + +static int drm_buddy_init_test(struct kunit *test) +{ + while (!random_seed) + random_seed = get_random_int(); + + return 0; +} + +static struct kunit_case drm_buddy_tests[] = { + KUNIT_CASE(igt_buddy_alloc_limit), + KUNIT_CASE(igt_buddy_alloc_range), + KUNIT_CASE(igt_buddy_alloc_optimistic), + KUNIT_CASE(igt_buddy_alloc_pessimistic), + KUNIT_CASE(igt_buddy_alloc_smoke), + KUNIT_CASE(igt_buddy_alloc_pathological), + {} +}; + +static struct kunit_suite drm_buddy_test_suite = { + .name = "drm_buddy", + .init = drm_buddy_init_test, + .test_cases = drm_buddy_tests, +}; + +kunit_test_suite(drm_buddy_test_suite); + +MODULE_AUTHOR("Intel Corporation"); +MODULE_LICENSE("GPL");
From: Arthur Grillo arthur.grillo@usp.br
Considering the current adoption of the KUnit framework, convert the DRM mm selftest to the KUnit API.
Tested-by: David Gow davidgow@google.com Signed-off-by: Arthur Grillo arthur.grillo@usp.br Signed-off-by: Maíra Canal maira.canal@usp.br --- Documentation/gpu/todo.rst | 11 - drivers/gpu/drm/Kconfig | 20 - drivers/gpu/drm/Makefile | 1 - drivers/gpu/drm/selftests/Makefile | 2 - drivers/gpu/drm/selftests/drm_mm_selftests.h | 28 - drivers/gpu/drm/selftests/drm_selftest.c | 109 -- drivers/gpu/drm/selftests/drm_selftest.h | 41 - drivers/gpu/drm/tests/Makefile | 3 +- .../test-drm_mm.c => tests/drm_mm_test.c} | 1135 +++++++---------- 9 files changed, 452 insertions(+), 898 deletions(-) delete mode 100644 drivers/gpu/drm/selftests/Makefile delete mode 100644 drivers/gpu/drm/selftests/drm_mm_selftests.h delete mode 100644 drivers/gpu/drm/selftests/drm_selftest.c delete mode 100644 drivers/gpu/drm/selftests/drm_selftest.h rename drivers/gpu/drm/{selftests/test-drm_mm.c => tests/drm_mm_test.c} (58%)
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 513b20ccef1e..10bfb50908d1 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -617,17 +617,6 @@ Contact: Javier Martinez Canillas javierm@redhat.com
Level: Intermediate
-Convert Kernel Selftests (kselftest) to KUnit tests when appropriate --------------------------------------------------------------------- - -Many of the `Kselftest https://www.kernel.org/doc/html/latest/dev-tools/kselftest.html`_ -tests in DRM could be converted to Kunit tests instead, since that framework -is more suitable for unit testing. - -Contact: Javier Martinez Canillas javierm@redhat.com - -Level: Starter - Enable trinity for DRM ----------------------
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index f49639bcdbff..a0c7cb5f0c3f 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -50,26 +50,6 @@ config DRM_DEBUG_MM
If in doubt, say "N".
-config DRM_DEBUG_SELFTEST - tristate "kselftests for DRM" - depends on DRM - depends on DEBUG_KERNEL - select PRIME_NUMBERS - select DRM_DISPLAY_DP_HELPER - select DRM_DISPLAY_HELPER - select DRM_LIB_RANDOM - select DRM_KMS_HELPER - select DRM_BUDDY - select DRM_EXPORT_FOR_TESTS if m - default n - help - This option provides kernel modules that can be used to run - various selftests on parts of the DRM api. This option is not - useful for distributions or general kernels, but only for kernel - developers working on DRM and associated drivers. - - If in doubt, say "N". - config DRM_KUNIT_TEST tristate "KUnit tests for DRM" if !KUNIT_ALL_TESTS depends on DRM && KUNIT diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index ebc82c5fa65f..36dcbf4cf6db 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -75,7 +75,6 @@ obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o # Drivers and the rest #
-obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/ obj-$(CONFIG_DRM_KUNIT_TEST) += tests/
obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile deleted file mode 100644 index a4ebecb8146b..000000000000 --- a/drivers/gpu/drm/selftests/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h b/drivers/gpu/drm/selftests/drm_mm_selftests.h deleted file mode 100644 index 8c87c964176b..000000000000 --- a/drivers/gpu/drm/selftests/drm_mm_selftests.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* List each unit test as selftest(name, function) - * - * The name is used as both an enum and expanded as igt__name to create - * a module parameter. It must be unique and legal for a C identifier. - * - * Tests are executed in order by igt/drm_mm - */ -selftest(sanitycheck, igt_sanitycheck) /* keep first (selfcheck for igt) */ -selftest(init, igt_init) -selftest(debug, igt_debug) -selftest(reserve, igt_reserve) -selftest(insert, igt_insert) -selftest(replace, igt_replace) -selftest(insert_range, igt_insert_range) -selftest(align, igt_align) -selftest(frag, igt_frag) -selftest(align32, igt_align32) -selftest(align64, igt_align64) -selftest(evict, igt_evict) -selftest(evict_range, igt_evict_range) -selftest(bottomup, igt_bottomup) -selftest(lowest, igt_lowest) -selftest(topdown, igt_topdown) -selftest(highest, igt_highest) -selftest(color, igt_color) -selftest(color_evict, igt_color_evict) -selftest(color_evict_range, igt_color_evict_range) diff --git a/drivers/gpu/drm/selftests/drm_selftest.c b/drivers/gpu/drm/selftests/drm_selftest.c deleted file mode 100644 index e29ed9faef5b..000000000000 --- a/drivers/gpu/drm/selftests/drm_selftest.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright © 2016 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include <linux/compiler.h> - -#define selftest(name, func) __idx_##name, -enum { -#include TESTS -}; -#undef selftest - -#define selftest(n, f) [__idx_##n] = { .name = #n, .func = f }, -static struct drm_selftest { - bool enabled; - const char *name; - int (*func)(void *); -} selftests[] = { -#include TESTS -}; -#undef selftest - -/* Embed the line number into the parameter name so that we can order tests */ -#define param(n) __PASTE(igt__, __PASTE(__PASTE(__LINE__, __), n)) -#define selftest_0(n, func, id) \ -module_param_named(id, selftests[__idx_##n].enabled, bool, 0400); -#define selftest(n, func) selftest_0(n, func, param(n)) -#include TESTS -#undef selftest - -static void set_default_test_all(struct drm_selftest *st, unsigned long count) -{ - unsigned long i; - - for (i = 0; i < count; i++) - if (st[i].enabled) - return; - - for (i = 0; i < count; i++) - st[i].enabled = true; -} - -static int run_selftests(struct drm_selftest *st, - unsigned long count, - void *data) -{ - int err = 0; - - set_default_test_all(st, count); - - /* Tests are listed in natural order in drm_*_selftests.h */ - for (; count--; st++) { - if (!st->enabled) - continue; - - pr_debug("drm: Running %s\n", st->name); - err = st->func(data); - if (err) - break; - } - - if (WARN(err > 0 || err == -ENOTTY, - "%s returned %d, conflicting with selftest's magic values!\n", - st->name, err)) - err = -1; - - rcu_barrier(); - return err; -} - -static int __maybe_unused -__drm_subtests(const char *caller, - const struct drm_subtest *st, - int count, - void *data) -{ - int err; - - for (; count--; st++) { - pr_debug("Running %s/%s\n", caller, st->name); - err = st->func(data); - if (err) { - pr_err("%s: %s failed with error %d\n", - caller, st->name, err); - return err; - } - } - - return 0; -} diff --git a/drivers/gpu/drm/selftests/drm_selftest.h b/drivers/gpu/drm/selftests/drm_selftest.h deleted file mode 100644 index c784ec02ff53..000000000000 --- a/drivers/gpu/drm/selftests/drm_selftest.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright © 2016 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef __DRM_SELFTEST_H__ -#define __DRM_SELFTEST_H__ - -struct drm_subtest { - int (*func)(void *data); - const char *name; -}; - -static int __drm_subtests(const char *caller, - const struct drm_subtest *st, - int count, - void *data); -#define drm_subtests(T, data) \ - __drm_subtests(__func__, T, ARRAY_SIZE(T), data) - -#define SUBTEST(x) { x, #x } - -#endif /* __DRM_SELFTEST_H__ */ diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index 15a3efb2cf8e..9f7306bc3ae5 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -2,4 +2,5 @@
obj-$(CONFIG_DRM_KUNIT_TEST) += drm_damage_helper_test.o drm_cmdline_parser_test.o \ drm_rect_test.o drm_format_test.o drm_plane_helper_test.o \ - drm_dp_mst_helper_test.o drm_framebuffer_test.o drm_buddy_test.o + drm_dp_mst_helper_test.o drm_framebuffer_test.o drm_buddy_test.o \ + drm_mm_test.o diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c b/drivers/gpu/drm/tests/drm_mm_test.c similarity index 58% rename from drivers/gpu/drm/selftests/test-drm_mm.c rename to drivers/gpu/drm/tests/drm_mm_test.c index b768b53c4aee..89a088a063af 100644 --- a/drivers/gpu/drm/selftests/test-drm_mm.c +++ b/drivers/gpu/drm/tests/drm_mm_test.c @@ -3,9 +3,7 @@ * Test cases for the drm_mm range manager */
-#define pr_fmt(fmt) "drm_mm: " fmt - -#include <linux/module.h> +#include <kunit/test.h> #include <linux/prime_numbers.h> #include <linux/slab.h> #include <linux/random.h> @@ -16,9 +14,6 @@
#include "../lib/drm_random.h"
-#define TESTS "drm_mm_selftests.h" -#include "drm_selftest.h" - static unsigned int random_seed; static unsigned int max_iterations = 8192; static unsigned int max_prime = 128; @@ -45,13 +40,7 @@ static const struct insert_mode { {} };
-static int igt_sanitycheck(void *ignored) -{ - pr_info("%s - ok!\n", __func__); - return 0; -} - -static bool assert_no_holes(const struct drm_mm *mm) +static bool assert_no_holes(struct kunit *test, const struct drm_mm *mm) { struct drm_mm_node *hole; u64 hole_start, __always_unused hole_end; @@ -61,13 +50,14 @@ static bool assert_no_holes(const struct drm_mm *mm) drm_mm_for_each_hole(hole, mm, hole_start, hole_end) count++; if (count) { - pr_err("Expected to find no holes (after reserve), found %lu instead\n", count); + KUNIT_FAIL(test, + "Expected to find no holes (after reserve), found %lu instead\n", count); return false; }
drm_mm_for_each_node(hole, mm) { if (drm_mm_hole_follows(hole)) { - pr_err("Hole follows node, expected none!\n"); + KUNIT_FAIL(test, "Hole follows node, expected none!\n"); return false; } } @@ -75,7 +65,7 @@ static bool assert_no_holes(const struct drm_mm *mm) return true; }
-static bool assert_one_hole(const struct drm_mm *mm, u64 start, u64 end) +static bool assert_one_hole(struct kunit *test, const struct drm_mm *mm, u64 start, u64 end) { struct drm_mm_node *hole; u64 hole_start, hole_end; @@ -89,62 +79,62 @@ static bool assert_one_hole(const struct drm_mm *mm, u64 start, u64 end) drm_mm_for_each_hole(hole, mm, hole_start, hole_end) { if (start != hole_start || end != hole_end) { if (ok) - pr_err("empty mm has incorrect hole, found (%llx, %llx), expect (%llx, %llx)\n", - hole_start, hole_end, - start, end); + KUNIT_FAIL(test, + "empty mm has incorrect hole, found (%llx, %llx), expect (%llx, %llx)\n", + hole_start, hole_end, start, end); ok = false; } count++; } if (count != 1) { - pr_err("Expected to find one hole, found %lu instead\n", count); + KUNIT_FAIL(test, "Expected to find one hole, found %lu instead\n", count); ok = false; }
return ok; }
-static bool assert_continuous(const struct drm_mm *mm, u64 size) +static bool assert_continuous(struct kunit *test, const struct drm_mm *mm, u64 size) { struct drm_mm_node *node, *check, *found; unsigned long n; u64 addr;
- if (!assert_no_holes(mm)) + if (!assert_no_holes(test, mm)) return false;
n = 0; addr = 0; drm_mm_for_each_node(node, mm) { if (node->start != addr) { - pr_err("node[%ld] list out of order, expected %llx found %llx\n", + KUNIT_FAIL(test, "node[%ld] list out of order, expected %llx found %llx\n", n, addr, node->start); return false; }
if (node->size != size) { - pr_err("node[%ld].size incorrect, expected %llx, found %llx\n", + KUNIT_FAIL(test, "node[%ld].size incorrect, expected %llx, found %llx\n", n, size, node->size); return false; }
if (drm_mm_hole_follows(node)) { - pr_err("node[%ld] is followed by a hole!\n", n); + KUNIT_FAIL(test, "node[%ld] is followed by a hole!\n", n); return false; }
found = NULL; drm_mm_for_each_node_in_range(check, mm, addr, addr + size) { if (node != check) { - pr_err("lookup return wrong node, expected start %llx, found %llx\n", - node->start, check->start); + KUNIT_FAIL(test, + "lookup return wrong node, expected start %llx, found %llx\n", + node->start, check->start); return false; } found = check; } if (!found) { - pr_err("lookup failed for node %llx + %llx\n", - addr, size); + KUNIT_FAIL(test, "lookup failed for node %llx + %llx\n", addr, size); return false; }
@@ -166,30 +156,31 @@ static u64 misalignment(struct drm_mm_node *node, u64 alignment) return rem; }
-static bool assert_node(struct drm_mm_node *node, struct drm_mm *mm, +static bool assert_node(struct kunit *test, struct drm_mm_node *node, struct drm_mm *mm, u64 size, u64 alignment, unsigned long color) { bool ok = true;
if (!drm_mm_node_allocated(node) || node->mm != mm) { - pr_err("node not allocated\n"); + KUNIT_FAIL(test, "node not allocated\n"); ok = false; }
if (node->size != size) { - pr_err("node has wrong size, found %llu, expected %llu\n", + KUNIT_FAIL(test, "node has wrong size, found %llu, expected %llu\n", node->size, size); ok = false; }
if (misalignment(node, alignment)) { - pr_err("node is misaligned, start %llx rem %llu, expected alignment %llu\n", - node->start, misalignment(node, alignment), alignment); + KUNIT_FAIL(test, + "node is misaligned, start %llx rem %llu, expected alignment %llu\n", + node->start, misalignment(node, alignment), alignment); ok = false; }
if (node->color != color) { - pr_err("node has wrong color, found %lu, expected %lu\n", + KUNIT_FAIL(test, "node has wrong color, found %lu, expected %lu\n", node->color, color); ok = false; } @@ -197,76 +188,64 @@ static bool assert_node(struct drm_mm_node *node, struct drm_mm *mm, return ok; }
-#define show_mm(mm) do { \ - struct drm_printer __p = drm_debug_printer(__func__); \ - drm_mm_print((mm), &__p); } while (0) - -static int igt_init(void *ignored) +static void igt_mm_init(struct kunit *test) { const unsigned int size = 4096; struct drm_mm mm; struct drm_mm_node tmp; - int ret = -EINVAL;
/* Start with some simple checks on initialising the struct drm_mm */ memset(&mm, 0, sizeof(mm)); - if (drm_mm_initialized(&mm)) { - pr_err("zeroed mm claims to be initialized\n"); - return ret; - } + KUNIT_ASSERT_FALSE_MSG(test, drm_mm_initialized(&mm), + "zeroed mm claims to be initialized\n");
memset(&mm, 0xff, sizeof(mm)); drm_mm_init(&mm, 0, size); if (!drm_mm_initialized(&mm)) { - pr_err("mm claims not to be initialized\n"); + KUNIT_FAIL(test, "mm claims not to be initialized\n"); goto out; }
if (!drm_mm_clean(&mm)) { - pr_err("mm not empty on creation\n"); + KUNIT_FAIL(test, "mm not empty on creation\n"); goto out; }
/* After creation, it should all be one massive hole */ - if (!assert_one_hole(&mm, 0, size)) { - ret = -EINVAL; + if (!assert_one_hole(test, &mm, 0, size)) { + KUNIT_FAIL(test, ""); goto out; }
memset(&tmp, 0, sizeof(tmp)); tmp.start = 0; tmp.size = size; - ret = drm_mm_reserve_node(&mm, &tmp); - if (ret) { - pr_err("failed to reserve whole drm_mm\n"); + if (drm_mm_reserve_node(&mm, &tmp)) { + KUNIT_FAIL(test, "failed to reserve whole drm_mm\n"); goto out; }
/* After filling the range entirely, there should be no holes */ - if (!assert_no_holes(&mm)) { - ret = -EINVAL; + if (!assert_no_holes(test, &mm)) { + KUNIT_FAIL(test, ""); goto out; }
/* And then after emptying it again, the massive hole should be back */ drm_mm_remove_node(&tmp); - if (!assert_one_hole(&mm, 0, size)) { - ret = -EINVAL; + if (!assert_one_hole(test, &mm, 0, size)) { + KUNIT_FAIL(test, ""); goto out; }
out: - if (ret) - show_mm(&mm); drm_mm_takedown(&mm); - return ret; }
-static int igt_debug(void *ignored) +static void igt_mm_debug(struct kunit *test) { struct drm_mm mm; struct drm_mm_node nodes[2]; - int ret;
/* Create a small drm_mm with a couple of nodes and a few holes, and * check that the debug iterator doesn't explode over a trivial drm_mm. @@ -277,24 +256,16 @@ static int igt_debug(void *ignored) memset(nodes, 0, sizeof(nodes)); nodes[0].start = 512; nodes[0].size = 1024; - ret = drm_mm_reserve_node(&mm, &nodes[0]); - if (ret) { - pr_err("failed to reserve node[0] {start=%lld, size=%lld)\n", - nodes[0].start, nodes[0].size); - return ret; - } + KUNIT_ASSERT_FALSE_MSG(test, drm_mm_reserve_node(&mm, &nodes[0]), + "failed to reserve node[0] {start=%lld, size=%lld)\n", + nodes[0].start, nodes[0].size);
nodes[1].size = 1024; nodes[1].start = 4096 - 512 - nodes[1].size; - ret = drm_mm_reserve_node(&mm, &nodes[1]); - if (ret) { - pr_err("failed to reserve node[1] {start=%lld, size=%lld)\n", - nodes[1].start, nodes[1].size); - return ret; - } + KUNIT_ASSERT_FALSE_MSG(test, drm_mm_reserve_node(&mm, &nodes[1]), + "failed to reserve node[0] {start=%lld, size=%lld)\n", + nodes[0].start, nodes[0].size);
- show_mm(&mm); - return 0; }
static struct drm_mm_node *set_node(struct drm_mm_node *node, @@ -305,7 +276,7 @@ static struct drm_mm_node *set_node(struct drm_mm_node *node, return node; }
-static bool expect_reserve_fail(struct drm_mm *mm, struct drm_mm_node *node) +static bool expect_reserve_fail(struct kunit *test, struct drm_mm *mm, struct drm_mm_node *node) { int err;
@@ -314,17 +285,18 @@ static bool expect_reserve_fail(struct drm_mm *mm, struct drm_mm_node *node) return true;
if (!err) { - pr_err("impossible reserve succeeded, node %llu + %llu\n", - node->start, node->size); + KUNIT_FAIL(test, "impossible reserve succeeded, node %llu + %llu\n", + node->start, node->size); drm_mm_remove_node(node); } else { - pr_err("impossible reserve failed with wrong error %d [expected %d], node %llu + %llu\n", + KUNIT_FAIL(test, + "impossible reserve failed with wrong error %d [expected %d], node %llu + %llu\n", err, -ENOSPC, node->start, node->size); } return false; }
-static bool check_reserve_boundaries(struct drm_mm *mm, +static bool check_reserve_boundaries(struct kunit *test, struct drm_mm *mm, unsigned int count, u64 size) { @@ -356,11 +328,9 @@ static bool check_reserve_boundaries(struct drm_mm *mm, int n;
for (n = 0; n < ARRAY_SIZE(boundaries); n++) { - if (!expect_reserve_fail(mm, - set_node(&tmp, - boundaries[n].start, + if (!expect_reserve_fail(test, mm, set_node(&tmp, boundaries[n].start, boundaries[n].size))) { - pr_err("boundary[%d:%s] failed, count=%u, size=%lld\n", + KUNIT_FAIL(test, "boundary[%d:%s] failed, count=%u, size=%lld\n", n, boundaries[n].name, count, size); return false; } @@ -369,7 +339,7 @@ static bool check_reserve_boundaries(struct drm_mm *mm, return true; }
-static int __igt_reserve(unsigned int count, u64 size) +static int __igt_reserve(struct kunit *test, unsigned int count, u64 size) { DRM_RND_STATE(prng, random_seed); struct drm_mm mm; @@ -377,7 +347,7 @@ static int __igt_reserve(unsigned int count, u64 size) unsigned int *order, n, m, o = 0; int ret, err;
- /* For exercising drm_mm_reserve_node(), we want to check that + /* For exercising drm_mm_reserve_node(struct kunit *test, ), we want to check that * reservations outside of the drm_mm range are rejected, and to * overlapping and otherwise already occupied ranges. Afterwards, * the tree and nodes should be intact. @@ -392,13 +362,12 @@ static int __igt_reserve(unsigned int count, u64 size) goto err;
nodes = vzalloc(array_size(count, sizeof(*nodes))); - if (!nodes) - goto err_order; + KUNIT_ASSERT_TRUE(test, nodes);
ret = -EINVAL; drm_mm_init(&mm, 0, count * size);
- if (!check_reserve_boundaries(&mm, count, size)) + if (!check_reserve_boundaries(test, &mm, count, size)) goto out;
for (n = 0; n < count; n++) { @@ -407,57 +376,53 @@ static int __igt_reserve(unsigned int count, u64 size)
err = drm_mm_reserve_node(&mm, &nodes[n]); if (err) { - pr_err("reserve failed, step %d, start %llu\n", + KUNIT_FAIL(test, "reserve failed, step %d, start %llu\n", n, nodes[n].start); ret = err; goto out; }
if (!drm_mm_node_allocated(&nodes[n])) { - pr_err("reserved node not allocated! step %d, start %llu\n", + KUNIT_FAIL(test, "reserved node not allocated! step %d, start %llu\n", n, nodes[n].start); goto out; }
- if (!expect_reserve_fail(&mm, &nodes[n])) + if (!expect_reserve_fail(test, &mm, &nodes[n])) goto out; }
/* After random insertion the nodes should be in order */ - if (!assert_continuous(&mm, size)) + if (!assert_continuous(test, &mm, size)) goto out;
/* Repeated use should then fail */ drm_random_reorder(order, count, &prng); for (n = 0; n < count; n++) { - if (!expect_reserve_fail(&mm, - set_node(&tmp, order[n] * size, 1))) + if (!expect_reserve_fail(test, &mm, set_node(&tmp, order[n] * size, 1))) goto out;
/* Remove and reinsert should work */ drm_mm_remove_node(&nodes[order[n]]); err = drm_mm_reserve_node(&mm, &nodes[order[n]]); if (err) { - pr_err("reserve failed, step %d, start %llu\n", + KUNIT_FAIL(test, "reserve failed, step %d, start %llu\n", n, nodes[n].start); ret = err; goto out; } }
- if (!assert_continuous(&mm, size)) + if (!assert_continuous(test, &mm, size)) goto out;
/* Overlapping use should then fail */ for (n = 0; n < count; n++) { - if (!expect_reserve_fail(&mm, set_node(&tmp, 0, size*count))) + if (!expect_reserve_fail(test, &mm, set_node(&tmp, 0, size*count))) goto out; } for (n = 0; n < count; n++) { - if (!expect_reserve_fail(&mm, - set_node(&tmp, - size * n, - size * (count - n)))) + if (!expect_reserve_fail(test, &mm, set_node(&tmp, size * n, size * (count - n)))) goto out; }
@@ -472,7 +437,7 @@ static int __igt_reserve(unsigned int count, u64 size) node = &nodes[order[(o + m) % count]]; err = drm_mm_reserve_node(&mm, node); if (err) { - pr_err("reserve failed, step %d/%d, start %llu\n", + KUNIT_FAIL(test, "reserve failed, step %d/%d, start %llu\n", m, n, node->start); ret = err; goto out; @@ -481,7 +446,7 @@ static int __igt_reserve(unsigned int count, u64 size)
o += n;
- if (!assert_continuous(&mm, size)) + if (!assert_continuous(test, &mm, size)) goto out; }
@@ -491,41 +456,29 @@ static int __igt_reserve(unsigned int count, u64 size) drm_mm_remove_node(node); drm_mm_takedown(&mm); vfree(nodes); -err_order: kfree(order); err: return ret; }
-static int igt_reserve(void *ignored) +static void igt_mm_reserve(struct kunit *test) { const unsigned int count = min_t(unsigned int, BIT(10), max_iterations); - int n, ret; + int n;
for_each_prime_number_from(n, 1, 54) { u64 size = BIT_ULL(n);
- ret = __igt_reserve(count, size - 1); - if (ret) - return ret; - - ret = __igt_reserve(count, size); - if (ret) - return ret; - - ret = __igt_reserve(count, size + 1); - if (ret) - return ret; + KUNIT_ASSERT_FALSE(test, __igt_reserve(test, count, size - 1)); + KUNIT_ASSERT_FALSE(test, __igt_reserve(test, count, size)); + KUNIT_ASSERT_FALSE(test, __igt_reserve(test, count, size + 1));
cond_resched(); } - - return 0; }
-static bool expect_insert(struct drm_mm *mm, struct drm_mm_node *node, - u64 size, u64 alignment, unsigned long color, - const struct insert_mode *mode) +static bool expect_insert(struct kunit *test, struct drm_mm *mm, struct drm_mm_node *node, + u64 size, u64 alignment, unsigned long color, const struct insert_mode *mode) { int err;
@@ -533,12 +486,13 @@ static bool expect_insert(struct drm_mm *mm, struct drm_mm_node *node, size, alignment, color, mode->mode); if (err) { - pr_err("insert (size=%llu, alignment=%llu, color=%lu, mode=%s) failed with err=%d\n", - size, alignment, color, mode->name, err); + KUNIT_FAIL(test, + "insert (size=%llu, alignment=%llu, color=%lu, mode=%s) failed with err=%d\n", + size, alignment, color, mode->name, err); return false; }
- if (!assert_node(node, mm, size, alignment, color)) { + if (!assert_node(test, node, mm, size, alignment, color)) { drm_mm_remove_node(node); return false; } @@ -546,7 +500,7 @@ static bool expect_insert(struct drm_mm *mm, struct drm_mm_node *node, return true; }
-static bool expect_insert_fail(struct drm_mm *mm, u64 size) +static bool expect_insert_fail(struct kunit *test, struct drm_mm *mm, u64 size) { struct drm_mm_node tmp = {}; int err; @@ -556,17 +510,18 @@ static bool expect_insert_fail(struct drm_mm *mm, u64 size) return true;
if (!err) { - pr_err("impossible insert succeeded, node %llu + %llu\n", + KUNIT_FAIL(test, "impossible insert succeeded, node %llu + %llu\n", tmp.start, tmp.size); drm_mm_remove_node(&tmp); } else { - pr_err("impossible insert failed with wrong error %d [expected %d], size %llu\n", - err, -ENOSPC, size); + KUNIT_FAIL(test, + "impossible insert failed with wrong error %d [expected %d], size %llu\n", + err, -ENOSPC, size); } return false; }
-static int __igt_insert(unsigned int count, u64 size, bool replace) +static int __igt_insert(struct kunit *test, unsigned int count, u64 size, bool replace) { DRM_RND_STATE(prng, random_seed); const struct insert_mode *mode; @@ -582,8 +537,7 @@ static int __igt_insert(unsigned int count, u64 size, bool replace)
ret = -ENOMEM; nodes = vmalloc(array_size(count, sizeof(*nodes))); - if (!nodes) - goto err; + KUNIT_ASSERT_TRUE(test, nodes);
order = drm_random_order(count, &prng); if (!order) @@ -598,8 +552,8 @@ static int __igt_insert(unsigned int count, u64 size, bool replace)
node = replace ? &tmp : &nodes[n]; memset(node, 0, sizeof(*node)); - if (!expect_insert(&mm, node, size, 0, n, mode)) { - pr_err("%s insert failed, size %llu step %d\n", + if (!expect_insert(test, &mm, node, size, 0, n, mode)) { + KUNIT_FAIL(test, "%s insert failed, size %llu step %d\n", mode->name, size, n); goto out; } @@ -607,32 +561,34 @@ static int __igt_insert(unsigned int count, u64 size, bool replace) if (replace) { drm_mm_replace_node(&tmp, &nodes[n]); if (drm_mm_node_allocated(&tmp)) { - pr_err("replaced old-node still allocated! step %d\n", - n); + KUNIT_FAIL(test, + "replaced old-node still allocated! step %d\n", + n); goto out; }
- if (!assert_node(&nodes[n], &mm, size, 0, n)) { - pr_err("replaced node did not inherit parameters, size %llu step %d\n", - size, n); + if (!assert_node(test, &nodes[n], &mm, size, 0, n)) { + KUNIT_FAIL(test, + "replaced node did not inherit parameters, size %llu step %d\n", + size, n); goto out; }
if (tmp.start != nodes[n].start) { - pr_err("replaced node mismatch location expected [%llx + %llx], found [%llx + %llx]\n", - tmp.start, size, - nodes[n].start, nodes[n].size); + KUNIT_FAIL(test, + "replaced node mismatch location expected [%llx + %llx], found [%llx + %llx]\n", + tmp.start, size, nodes[n].start, nodes[n].size); goto out; } } }
/* After random insertion the nodes should be in order */ - if (!assert_continuous(&mm, size)) + if (!assert_continuous(test, &mm, size)) goto out;
/* Repeated use should then fail */ - if (!expect_insert_fail(&mm, size)) + if (!expect_insert_fail(test, &mm, size)) goto out;
/* Remove one and reinsert, as the only hole it should refill itself */ @@ -640,19 +596,20 @@ static int __igt_insert(unsigned int count, u64 size, bool replace) u64 addr = nodes[n].start;
drm_mm_remove_node(&nodes[n]); - if (!expect_insert(&mm, &nodes[n], size, 0, n, mode)) { - pr_err("%s reinsert failed, size %llu step %d\n", + if (!expect_insert(test, &mm, &nodes[n], size, 0, n, mode)) { + KUNIT_FAIL(test, "%s reinsert failed, size %llu step %d\n", mode->name, size, n); goto out; }
if (nodes[n].start != addr) { - pr_err("%s reinsert node moved, step %d, expected %llx, found %llx\n", - mode->name, n, addr, nodes[n].start); + KUNIT_FAIL(test, + "%s reinsert node moved, step %d, expected %llx, found %llx\n", + mode->name, n, addr, nodes[n].start); goto out; }
- if (!assert_continuous(&mm, size)) + if (!assert_continuous(test, &mm, size)) goto out; }
@@ -665,19 +622,20 @@ static int __igt_insert(unsigned int count, u64 size, bool replace)
for (m = 0; m < n; m++) { node = &nodes[order[(o + m) % count]]; - if (!expect_insert(&mm, node, size, 0, n, mode)) { - pr_err("%s multiple reinsert failed, size %llu step %d\n", - mode->name, size, n); + if (!expect_insert(test, &mm, node, size, 0, n, mode)) { + KUNIT_FAIL(test, + "%s multiple reinsert failed, size %llu step %d\n", + mode->name, size, n); goto out; } }
o += n;
- if (!assert_continuous(&mm, size)) + if (!assert_continuous(test, &mm, size)) goto out;
- if (!expect_insert_fail(&mm, size)) + if (!expect_insert_fail(test, &mm, size)) goto out; }
@@ -696,42 +654,30 @@ static int __igt_insert(unsigned int count, u64 size, bool replace) kfree(order); err_nodes: vfree(nodes); -err: return ret; }
-static int igt_insert(void *ignored) +static void igt_mm_insert(struct kunit *test) { const unsigned int count = min_t(unsigned int, BIT(10), max_iterations); unsigned int n; - int ret;
for_each_prime_number_from(n, 1, 54) { u64 size = BIT_ULL(n);
- ret = __igt_insert(count, size - 1, false); - if (ret) - return ret; - - ret = __igt_insert(count, size, false); - if (ret) - return ret; - - ret = __igt_insert(count, size + 1, false); - if (ret) - return ret; + KUNIT_ASSERT_FALSE(test, __igt_insert(test, count, size - 1, false)); + KUNIT_ASSERT_FALSE(test, __igt_insert(test, count, size, false)); + KUNIT_ASSERT_FALSE(test, __igt_insert(test, count, size + 1, false));
cond_resched(); }
- return 0; }
-static int igt_replace(void *ignored) +static void igt_mm_replace(struct kunit *test) { const unsigned int count = min_t(unsigned int, BIT(10), max_iterations); unsigned int n; - int ret;
/* Reuse igt_insert to exercise replacement by inserting a dummy node, * then replacing it with the intended node. We want to check that @@ -742,28 +688,17 @@ static int igt_replace(void *ignored) for_each_prime_number_from(n, 1, 54) { u64 size = BIT_ULL(n);
- ret = __igt_insert(count, size - 1, true); - if (ret) - return ret; - - ret = __igt_insert(count, size, true); - if (ret) - return ret; - - ret = __igt_insert(count, size + 1, true); - if (ret) - return ret; + KUNIT_ASSERT_FALSE(test, __igt_insert(test, count, size - 1, true)); + KUNIT_ASSERT_FALSE(test, __igt_insert(test, count, size, true)); + KUNIT_ASSERT_FALSE(test, __igt_insert(test, count, size + 1, true));
cond_resched(); } - - return 0; }
-static bool expect_insert_in_range(struct drm_mm *mm, struct drm_mm_node *node, +static bool expect_insert_in_range(struct kunit *test, struct drm_mm *mm, struct drm_mm_node *node, u64 size, u64 alignment, unsigned long color, - u64 range_start, u64 range_end, - const struct insert_mode *mode) + u64 range_start, u64 range_end, const struct insert_mode *mode) { int err;
@@ -772,13 +707,14 @@ static bool expect_insert_in_range(struct drm_mm *mm, struct drm_mm_node *node, range_start, range_end, mode->mode); if (err) { - pr_err("insert (size=%llu, alignment=%llu, color=%lu, mode=%s) nto range [%llx, %llx] failed with err=%d\n", - size, alignment, color, mode->name, - range_start, range_end, err); + KUNIT_FAIL(test, + "insert (size=%llu, alignment=%llu, color=%lu, mode=%s) nto range [%llx, %llx] failed with err=%d\n", + size, alignment, color, mode->name, + range_start, range_end, err); return false; }
- if (!assert_node(node, mm, size, alignment, color)) { + if (!assert_node(test, node, mm, size, alignment, color)) { drm_mm_remove_node(node); return false; } @@ -786,67 +722,63 @@ static bool expect_insert_in_range(struct drm_mm *mm, struct drm_mm_node *node, return true; }
-static bool expect_insert_in_range_fail(struct drm_mm *mm, - u64 size, - u64 range_start, - u64 range_end) +static bool expect_insert_in_range_fail(struct kunit *test, struct drm_mm *mm, + u64 size, u64 range_start, u64 range_end) { struct drm_mm_node tmp = {}; int err;
- err = drm_mm_insert_node_in_range(mm, &tmp, - size, 0, 0, - range_start, range_end, + err = drm_mm_insert_node_in_range(mm, &tmp, size, 0, 0, range_start, range_end, 0); if (likely(err == -ENOSPC)) return true;
if (!err) { - pr_err("impossible insert succeeded, node %llx + %llu, range [%llx, %llx]\n", - tmp.start, tmp.size, range_start, range_end); + KUNIT_FAIL(test, + "impossible insert succeeded, node %llx + %llu, range [%llx, %llx]\n", + tmp.start, tmp.size, range_start, range_end); drm_mm_remove_node(&tmp); } else { - pr_err("impossible insert failed with wrong error %d [expected %d], size %llu, range [%llx, %llx]\n", - err, -ENOSPC, size, range_start, range_end); + KUNIT_FAIL(test, + "impossible insert failed with wrong error %d [expected %d], size %llu, range [%llx, %llx]\n", + err, -ENOSPC, size, range_start, range_end); }
return false; }
-static bool assert_contiguous_in_range(struct drm_mm *mm, - u64 size, - u64 start, - u64 end) +static bool assert_contiguous_in_range(struct kunit *test, struct drm_mm *mm, + u64 size, u64 start, u64 end) { struct drm_mm_node *node; unsigned int n;
- if (!expect_insert_in_range_fail(mm, size, start, end)) + if (!expect_insert_in_range_fail(test, mm, size, start, end)) return false;
n = div64_u64(start + size - 1, size); drm_mm_for_each_node(node, mm) { if (node->start < start || node->start + node->size > end) { - pr_err("node %d out of range, address [%llx + %llu], range [%llx, %llx]\n", - n, node->start, node->start + node->size, start, end); + KUNIT_FAIL(test, + "node %d out of range, address [%llx + %llu], range [%llx, %llx]\n", + n, node->start, node->start + node->size, start, end); return false; }
if (node->start != n * size) { - pr_err("node %d out of order, expected start %llx, found %llx\n", + KUNIT_FAIL(test, "node %d out of order, expected start %llx, found %llx\n", n, n * size, node->start); return false; }
if (node->size != size) { - pr_err("node %d has wrong size, expected size %llx, found %llx\n", + KUNIT_FAIL(test, "node %d has wrong size, expected size %llx, found %llx\n", n, size, node->size); return false; }
- if (drm_mm_hole_follows(node) && - drm_mm_hole_node_end(node) < end) { - pr_err("node %d is followed by a hole!\n", n); + if (drm_mm_hole_follows(node) && drm_mm_hole_node_end(node) < end) { + KUNIT_FAIL(test, "node %d is followed by a hole!\n", n); return false; }
@@ -856,7 +788,7 @@ static bool assert_contiguous_in_range(struct drm_mm *mm, if (start > 0) { node = __drm_mm_interval_first(mm, 0, start - 1); if (drm_mm_node_allocated(node)) { - pr_err("node before start: node=%llx+%llu, start=%llx\n", + KUNIT_FAIL(test, "node before start: node=%llx+%llu, start=%llx\n", node->start, node->size, start); return false; } @@ -865,7 +797,7 @@ static bool assert_contiguous_in_range(struct drm_mm *mm, if (end < U64_MAX) { node = __drm_mm_interval_first(mm, end, U64_MAX); if (drm_mm_node_allocated(node)) { - pr_err("node after end: node=%llx+%llu, end=%llx\n", + KUNIT_FAIL(test, "node after end: node=%llx+%llu, end=%llx\n", node->start, node->size, end); return false; } @@ -874,7 +806,7 @@ static bool assert_contiguous_in_range(struct drm_mm *mm, return true; }
-static int __igt_insert_range(unsigned int count, u64 size, u64 start, u64 end) +static int __igt_insert_range(struct kunit *test, unsigned int count, u64 size, u64 start, u64 end) { const struct insert_mode *mode; struct drm_mm mm; @@ -886,14 +818,13 @@ static int __igt_insert_range(unsigned int count, u64 size, u64 start, u64 end) DRM_MM_BUG_ON(!size); DRM_MM_BUG_ON(end <= start);
- /* Very similar to __igt_insert(), but now instead of populating the + /* Very similar to __igt_insert(struct kunit *test, ), but now instead of populating the * full range of the drm_mm, we try to fill a small portion of it. */
ret = -ENOMEM; nodes = vzalloc(array_size(count, sizeof(*nodes))); - if (!nodes) - goto err; + KUNIT_ASSERT_TRUE(test, nodes);
ret = -EINVAL; drm_mm_init(&mm, 0, count * size); @@ -903,20 +834,19 @@ static int __igt_insert_range(unsigned int count, u64 size, u64 start, u64 end)
for (mode = insert_modes; mode->name; mode++) { for (n = start_n; n <= end_n; n++) { - if (!expect_insert_in_range(&mm, &nodes[n], - size, size, n, - start, end, mode)) { - pr_err("%s insert failed, size %llu, step %d [%d, %d], range [%llx, %llx]\n", - mode->name, size, n, - start_n, end_n, - start, end); + if (!expect_insert_in_range(test, &mm, &nodes[n], size, size, n, + start, end, mode)) { + KUNIT_FAIL(test, + "%s insert failed, size %llu, step %d [%d, %d], range [%llx, %llx]\n", + mode->name, size, n, start_n, end_n, start, end); goto out; } }
- if (!assert_contiguous_in_range(&mm, size, start, end)) { - pr_err("%s: range [%llx, %llx] not full after initialisation, size=%llu\n", - mode->name, start, end, size); + if (!assert_contiguous_in_range(test, &mm, size, start, end)) { + KUNIT_FAIL(test, + "%s: range [%llx, %llx] not full after initialisation, size=%llu\n", + mode->name, start, end, size); goto out; }
@@ -925,23 +855,24 @@ static int __igt_insert_range(unsigned int count, u64 size, u64 start, u64 end) u64 addr = nodes[n].start;
drm_mm_remove_node(&nodes[n]); - if (!expect_insert_in_range(&mm, &nodes[n], - size, size, n, + if (!expect_insert_in_range(test, &mm, &nodes[n], size, size, n, start, end, mode)) { - pr_err("%s reinsert failed, step %d\n", mode->name, n); + KUNIT_FAIL(test, "%s reinsert failed, step %d\n", mode->name, n); goto out; }
if (nodes[n].start != addr) { - pr_err("%s reinsert node moved, step %d, expected %llx, found %llx\n", - mode->name, n, addr, nodes[n].start); + KUNIT_FAIL(test, + "%s reinsert node moved, step %d, expected %llx, found %llx\n", + mode->name, n, addr, nodes[n].start); goto out; } }
- if (!assert_contiguous_in_range(&mm, size, start, end)) { - pr_err("%s: range [%llx, %llx] not full after reinsertion, size=%llu\n", - mode->name, start, end, size); + if (!assert_contiguous_in_range(test, &mm, size, start, end)) { + KUNIT_FAIL(test, + "%s: range [%llx, %llx] not full after reinsertion, size=%llu\n", + mode->name, start, end, size); goto out; }
@@ -958,11 +889,10 @@ static int __igt_insert_range(unsigned int count, u64 size, u64 start, u64 end) drm_mm_remove_node(node); drm_mm_takedown(&mm); vfree(nodes); -err: return ret; }
-static int insert_outside_range(void) +static int insert_outside_range(struct kunit *test) { struct drm_mm mm; const unsigned int start = 1024; @@ -971,81 +901,57 @@ static int insert_outside_range(void)
drm_mm_init(&mm, start, size);
- if (!expect_insert_in_range_fail(&mm, 1, 0, start)) + if (!expect_insert_in_range_fail(test, &mm, 1, 0, start)) return -EINVAL;
- if (!expect_insert_in_range_fail(&mm, size, + if (!expect_insert_in_range_fail(test, &mm, size, start - size/2, start + (size+1)/2)) return -EINVAL;
- if (!expect_insert_in_range_fail(&mm, size, + if (!expect_insert_in_range_fail(test, &mm, size, end - (size+1)/2, end + size/2)) return -EINVAL;
- if (!expect_insert_in_range_fail(&mm, 1, end, end + size)) + if (!expect_insert_in_range_fail(test, &mm, 1, end, end + size)) return -EINVAL;
drm_mm_takedown(&mm); return 0; }
-static int igt_insert_range(void *ignored) +static void igt_mm_insert_range(struct kunit *test) { const unsigned int count = min_t(unsigned int, BIT(13), max_iterations); unsigned int n; - int ret;
/* Check that requests outside the bounds of drm_mm are rejected. */ - ret = insert_outside_range(); - if (ret) - return ret; + KUNIT_ASSERT_FALSE(test, insert_outside_range(test));
for_each_prime_number_from(n, 1, 50) { const u64 size = BIT_ULL(n); const u64 max = count * size;
- ret = __igt_insert_range(count, size, 0, max); - if (ret) - return ret; - - ret = __igt_insert_range(count, size, 1, max); - if (ret) - return ret; - - ret = __igt_insert_range(count, size, 0, max - 1); - if (ret) - return ret; - - ret = __igt_insert_range(count, size, 0, max/2); - if (ret) - return ret; - - ret = __igt_insert_range(count, size, max/2, max); - if (ret) - return ret; - - ret = __igt_insert_range(count, size, max/4+1, 3*max/4-1); - if (ret) - return ret; + KUNIT_ASSERT_FALSE(test, __igt_insert_range(test, count, size, 0, max)); + KUNIT_ASSERT_FALSE(test, __igt_insert_range(test, count, size, 1, max)); + KUNIT_ASSERT_FALSE(test, __igt_insert_range(test, count, size, 0, max - 1)); + KUNIT_ASSERT_FALSE(test, __igt_insert_range(test, count, size, 0, max/2)); + KUNIT_ASSERT_FALSE(test, __igt_insert_range(test, count, size, max/2, max/2)); + KUNIT_ASSERT_FALSE(test, __igt_insert_range(test, count, size, max/4+1, 3*max/4-1));
cond_resched(); } - - return 0; }
-static int prepare_igt_frag(struct drm_mm *mm, - struct drm_mm_node *nodes, - unsigned int num_insert, +static int prepare_igt_frag(struct kunit *test, struct drm_mm *mm, + struct drm_mm_node *nodes, unsigned int num_insert, const struct insert_mode *mode) { unsigned int size = 4096; unsigned int i;
for (i = 0; i < num_insert; i++) { - if (!expect_insert(mm, &nodes[i], size, 0, i, - mode) != 0) { - pr_err("%s insert failed\n", mode->name); + if (!expect_insert(test, mm, &nodes[i], size, 0, i, mode) != 0) { + KUNIT_FAIL(test, "%s insert failed\n", mode->name); return -EINVAL; } } @@ -1060,9 +966,8 @@ static int prepare_igt_frag(struct drm_mm *mm,
}
-static u64 get_insert_time(struct drm_mm *mm, - unsigned int num_insert, - struct drm_mm_node *nodes, +static u64 get_insert_time(struct kunit *test, struct drm_mm *mm, + unsigned int num_insert, struct drm_mm_node *nodes, const struct insert_mode *mode) { unsigned int size = 8192; @@ -1071,8 +976,8 @@ static u64 get_insert_time(struct drm_mm *mm,
start = ktime_get(); for (i = 0; i < num_insert; i++) { - if (!expect_insert(mm, &nodes[i], size, 0, i, mode) != 0) { - pr_err("%s insert failed\n", mode->name); + if (!expect_insert(test, mm, &nodes[i], size, 0, i, mode) != 0) { + KUNIT_FAIL(test, "%s insert failed\n", mode->name); return 0; } } @@ -1080,27 +985,25 @@ static u64 get_insert_time(struct drm_mm *mm, return ktime_to_ns(ktime_sub(ktime_get(), start)); }
-static int igt_frag(void *ignored) +static void igt_mm_frag(struct kunit *test) { struct drm_mm mm; const struct insert_mode *mode; struct drm_mm_node *nodes, *node, *next; unsigned int insert_size = 10000; unsigned int scale_factor = 4; - int ret = -EINVAL;
/* We need 4 * insert_size nodes to hold intermediate allocated * drm_mm nodes. - * 1 times for prepare_igt_frag() - * 1 times for get_insert_time() - * 2 times for get_insert_time() + * 1 times for prepare_igt_frag(struct kunit *test, ) + * 1 times for get_insert_time(struct kunit *test, ) + * 2 times for get_insert_time(struct kunit *test, ) */ nodes = vzalloc(array_size(insert_size * 4, sizeof(*nodes))); - if (!nodes) - return -ENOMEM; + KUNIT_ASSERT_TRUE(test, nodes);
/* For BOTTOMUP and TOPDOWN, we first fragment the - * address space using prepare_igt_frag() and then try to verify + * address space using prepare_igt_frag(struct kunit *test, ) and then try to verify * that that insertions scale quadratically from 10k to 20k insertions */ drm_mm_init(&mm, 1, U64_MAX - 2); @@ -1111,28 +1014,25 @@ static int igt_frag(void *ignored) mode->mode != DRM_MM_INSERT_HIGH) continue;
- ret = prepare_igt_frag(&mm, nodes, insert_size, mode); - if (ret) + if (prepare_igt_frag(test, &mm, nodes, insert_size, mode)) goto err;
- insert_time1 = get_insert_time(&mm, insert_size, + insert_time1 = get_insert_time(test, &mm, insert_size, nodes + insert_size, mode); if (insert_time1 == 0) goto err;
- insert_time2 = get_insert_time(&mm, (insert_size * 2), + insert_time2 = get_insert_time(test, &mm, (insert_size * 2), nodes + insert_size * 2, mode); if (insert_time2 == 0) goto err;
- pr_info("%s fragmented insert of %u and %u insertions took %llu and %llu nsecs\n", - mode->name, insert_size, insert_size * 2, - insert_time1, insert_time2); + kunit_info(test, "%s fragmented insert of %u and %u insertions took %llu and %llu nsecs\n", + mode->name, insert_size, insert_size * 2, insert_time1, insert_time2);
if (insert_time2 > (scale_factor * insert_time1)) { - pr_err("%s fragmented insert took %llu nsecs more\n", - mode->name, - insert_time2 - (scale_factor * insert_time1)); + KUNIT_FAIL(test, "%s fragmented insert took %llu nsecs more\n", + mode->name, insert_time2 - (scale_factor * insert_time1)); goto err; }
@@ -1140,24 +1040,20 @@ static int igt_frag(void *ignored) drm_mm_remove_node(node); }
- ret = 0; err: drm_mm_for_each_node_safe(node, next, &mm) drm_mm_remove_node(node); drm_mm_takedown(&mm); vfree(nodes); - - return ret; }
-static int igt_align(void *ignored) +static void igt_mm_align(struct kunit *test) { const struct insert_mode *mode; const unsigned int max_count = min(8192u, max_prime); struct drm_mm mm; struct drm_mm_node *nodes, *node, *next; unsigned int prime; - int ret = -EINVAL;
/* For each of the possible insertion modes, we pick a few * arbitrary alignments and check that the inserted node @@ -1165,8 +1061,7 @@ static int igt_align(void *ignored) */
nodes = vzalloc(array_size(max_count, sizeof(*nodes))); - if (!nodes) - goto err; + KUNIT_ASSERT_TRUE(test, nodes);
drm_mm_init(&mm, 1, U64_MAX - 2);
@@ -1176,10 +1071,8 @@ static int igt_align(void *ignored) for_each_prime_number_from(prime, 1, max_count) { u64 size = next_prime_number(prime);
- if (!expect_insert(&mm, &nodes[i], - size, prime, i, - mode)) { - pr_err("%s insert failed with alignment=%d", + if (!expect_insert(test, &mm, &nodes[i], size, prime, i, mode)) { + KUNIT_FAIL(test, "%s insert failed with alignment=%d", mode->name, prime); goto out; } @@ -1194,22 +1087,18 @@ static int igt_align(void *ignored) cond_resched(); }
- ret = 0; out: drm_mm_for_each_node_safe(node, next, &mm) drm_mm_remove_node(node); drm_mm_takedown(&mm); vfree(nodes); -err: - return ret; }
-static int igt_align_pot(int max) +static void igt_align_pot(struct kunit *test, int max) { struct drm_mm mm; struct drm_mm_node *node, *next; int bit; - int ret = -EINVAL;
/* Check that we can align to the full u64 address space */
@@ -1220,51 +1109,45 @@ static int igt_align_pot(int max)
node = kzalloc(sizeof(*node), GFP_KERNEL); if (!node) { - ret = -ENOMEM; + KUNIT_FAIL(test, "failed to allocate node"); goto out; }
align = BIT_ULL(bit); size = BIT_ULL(bit-1) + 1; - if (!expect_insert(&mm, node, - size, align, bit, - &insert_modes[0])) { - pr_err("insert failed with alignment=%llx [%d]", - align, bit); + if (!expect_insert(test, &mm, node, size, align, bit, &insert_modes[0])) { + KUNIT_FAIL(test, "insert failed with alignment=%llx [%d]", align, bit); goto out; }
cond_resched(); }
- ret = 0; out: drm_mm_for_each_node_safe(node, next, &mm) { drm_mm_remove_node(node); kfree(node); } drm_mm_takedown(&mm); - return ret; }
-static int igt_align32(void *ignored) +static void igt_mm_align32(struct kunit *test) { - return igt_align_pot(32); + igt_align_pot(test, 32); }
-static int igt_align64(void *ignored) +static void igt_mm_align64(struct kunit *test) { - return igt_align_pot(64); + igt_align_pot(test, 64); }
-static void show_scan(const struct drm_mm_scan *scan) +static void show_scan(struct kunit *test, const struct drm_mm_scan *scan) { - pr_info("scan: hit [%llx, %llx], size=%lld, align=%lld, color=%ld\n", - scan->hit_start, scan->hit_end, - scan->size, scan->alignment, scan->color); + kunit_info(test, "scan: hit [%llx, %llx], size=%lld, align=%lld, color=%ld\n", + scan->hit_start, scan->hit_end, scan->size, scan->alignment, scan->color); }
-static void show_holes(const struct drm_mm *mm, int count) +static void show_holes(struct kunit *test, const struct drm_mm *mm, int count) { u64 hole_start, hole_end; struct drm_mm_node *hole; @@ -1274,19 +1157,15 @@ static void show_holes(const struct drm_mm *mm, int count) const char *node1 = NULL, *node2 = NULL;
if (drm_mm_node_allocated(hole)) - node1 = kasprintf(GFP_KERNEL, - "[%llx + %lld, color=%ld], ", + node1 = kasprintf(GFP_KERNEL, "[%llx + %lld, color=%ld], ", hole->start, hole->size, hole->color);
if (drm_mm_node_allocated(next)) - node2 = kasprintf(GFP_KERNEL, - ", [%llx + %lld, color=%ld]", + node2 = kasprintf(GFP_KERNEL, ", [%llx + %lld, color=%ld]", next->start, next->size, next->color);
- pr_info("%sHole [%llx - %llx, size %lld]%s\n", - node1, - hole_start, hole_end, hole_end - hole_start, - node2); + kunit_info(test, "%sHole [%llx - %llx, size %lld]%s\n", node1, + hole_start, hole_end, hole_end - hole_start, node2);
kfree(node2); kfree(node1); @@ -1301,12 +1180,9 @@ struct evict_node { struct list_head link; };
-static bool evict_nodes(struct drm_mm_scan *scan, - struct evict_node *nodes, - unsigned int *order, - unsigned int count, - bool use_color, - struct list_head *evict_list) +static bool evict_nodes(struct kunit *test, struct drm_mm_scan *scan, + struct evict_node *nodes, unsigned int *order, unsigned int count, + bool use_color, struct list_head *evict_list) { struct evict_node *e, *en; unsigned int i; @@ -1322,8 +1198,9 @@ static bool evict_nodes(struct drm_mm_scan *scan, list_del(&e->link); } if (list_empty(evict_list)) { - pr_err("Failed to find eviction: size=%lld [avail=%d], align=%lld (color=%lu)\n", - scan->size, count, scan->alignment, scan->color); + KUNIT_FAIL(test, + "Failed to find eviction: size=%lld [avail=%d], align=%lld (color=%lu)\n", + scan->size, count, scan->alignment, scan->color); return false; }
@@ -1340,7 +1217,8 @@ static bool evict_nodes(struct drm_mm_scan *scan, } } else { if (drm_mm_scan_color_evict(scan)) { - pr_err("drm_mm_scan_color_evict unexpectedly reported overlapping nodes!\n"); + KUNIT_FAIL(test, + "drm_mm_scan_color_evict unexpectedly reported overlapping nodes!\n"); return false; } } @@ -1348,9 +1226,8 @@ static bool evict_nodes(struct drm_mm_scan *scan, return true; }
-static bool evict_nothing(struct drm_mm *mm, - unsigned int total_size, - struct evict_node *nodes) +static bool evict_nothing(struct kunit *test, struct drm_mm *mm, + unsigned int total_size, struct evict_node *nodes) { struct drm_mm_scan scan; LIST_HEAD(evict_list); @@ -1371,7 +1248,7 @@ static bool evict_nothing(struct drm_mm *mm, e = &nodes[n];
if (!drm_mm_node_allocated(&e->node)) { - pr_err("node[%d] no longer allocated!\n", n); + KUNIT_FAIL(test, "node[%d] no longer allocated!\n", n); return false; }
@@ -1387,17 +1264,16 @@ static bool evict_nothing(struct drm_mm *mm, e = &nodes[n];
if (!e->link.next) { - pr_err("node[%d] no longer connected!\n", n); + KUNIT_FAIL(test, "node[%d] no longer connected!\n", n); return false; } }
- return assert_continuous(mm, nodes[0].node.size); + return assert_continuous(test, mm, nodes[0].node.size); }
-static bool evict_everything(struct drm_mm *mm, - unsigned int total_size, - struct evict_node *nodes) +static bool evict_everything(struct kunit *test, struct drm_mm *mm, + unsigned int total_size, struct evict_node *nodes) { struct drm_mm_scan scan; LIST_HEAD(evict_list); @@ -1417,7 +1293,7 @@ static bool evict_everything(struct drm_mm *mm, list_for_each_entry(e, &evict_list, link) { if (!drm_mm_scan_remove_block(&scan, &e->node)) { if (!err) { - pr_err("Node %lld not marked for eviction!\n", + KUNIT_FAIL(test, "Node %lld not marked for eviction!\n", e->node.start); err = -EINVAL; } @@ -1429,29 +1305,25 @@ static bool evict_everything(struct drm_mm *mm, list_for_each_entry(e, &evict_list, link) drm_mm_remove_node(&e->node);
- if (!assert_one_hole(mm, 0, total_size)) + if (!assert_one_hole(test, mm, 0, total_size)) return false;
list_for_each_entry(e, &evict_list, link) { err = drm_mm_reserve_node(mm, &e->node); if (err) { - pr_err("Failed to reinsert node after eviction: start=%llx\n", + KUNIT_FAIL(test, "Failed to reinsert node after eviction: start=%llx\n", e->node.start); return false; } }
- return assert_continuous(mm, nodes[0].node.size); + return assert_continuous(test, mm, nodes[0].node.size); }
-static int evict_something(struct drm_mm *mm, - u64 range_start, u64 range_end, - struct evict_node *nodes, - unsigned int *order, - unsigned int count, - unsigned int size, - unsigned int alignment, - const struct insert_mode *mode) +static int evict_something(struct kunit *test, struct drm_mm *mm, + u64 range_start, u64 range_end, struct evict_node *nodes, + unsigned int *order, unsigned int count, unsigned int size, + unsigned int alignment, const struct insert_mode *mode) { struct drm_mm_scan scan; LIST_HEAD(evict_list); @@ -1459,38 +1331,35 @@ static int evict_something(struct drm_mm *mm, struct drm_mm_node tmp; int err;
- drm_mm_scan_init_with_range(&scan, mm, - size, alignment, 0, - range_start, range_end, - mode->mode); - if (!evict_nodes(&scan, - nodes, order, count, false, - &evict_list)) + drm_mm_scan_init_with_range(&scan, mm, size, alignment, 0, range_start, + range_end, mode->mode); + if (!evict_nodes(test, &scan, nodes, order, count, false, &evict_list)) return -EINVAL;
memset(&tmp, 0, sizeof(tmp)); err = drm_mm_insert_node_generic(mm, &tmp, size, alignment, 0, DRM_MM_INSERT_EVICT); if (err) { - pr_err("Failed to insert into eviction hole: size=%d, align=%d\n", + KUNIT_FAIL(test, "Failed to insert into eviction hole: size=%d, align=%d\n", size, alignment); - show_scan(&scan); - show_holes(mm, 3); + show_scan(test, &scan); + show_holes(test, mm, 3); return err; }
if (tmp.start < range_start || tmp.start + tmp.size > range_end) { - pr_err("Inserted [address=%llu + %llu] did not fit into the request range [%llu, %llu]\n", - tmp.start, tmp.size, range_start, range_end); + KUNIT_FAIL(test, + "Inserted [address=%llu + %llu] did not fit into the request range [%llu, %llu]\n", + tmp.start, tmp.size, range_start, range_end); err = -EINVAL; }
- if (!assert_node(&tmp, mm, size, alignment, 0) || + if (!assert_node(test, &tmp, mm, size, alignment, 0) || drm_mm_hole_follows(&tmp)) { - pr_err("Inserted did not fill the eviction hole: size=%lld [%d], align=%d [rem=%lld], start=%llx, hole-follows?=%d\n", - tmp.size, size, - alignment, misalignment(&tmp, alignment), - tmp.start, drm_mm_hole_follows(&tmp)); + KUNIT_FAIL(test, + "Inserted did not fill the eviction hole: size=%lld [%d], align=%d [rem=%lld], start=%llx, hole-follows?=%d\n", + tmp.size, size, alignment, misalignment(&tmp, alignment), + tmp.start, drm_mm_hole_follows(&tmp)); err = -EINVAL; }
@@ -1501,21 +1370,21 @@ static int evict_something(struct drm_mm *mm, list_for_each_entry(e, &evict_list, link) { err = drm_mm_reserve_node(mm, &e->node); if (err) { - pr_err("Failed to reinsert node after eviction: start=%llx\n", + KUNIT_FAIL(test, "Failed to reinsert node after eviction: start=%llx\n", e->node.start); return err; } }
- if (!assert_continuous(mm, nodes[0].node.size)) { - pr_err("range is no longer continuous\n"); + if (!assert_continuous(test, mm, nodes[0].node.size)) { + KUNIT_FAIL(test, "range is no longer continuous\n"); return -EINVAL; }
return 0; }
-static int igt_evict(void *ignored) +static void igt_mm_evict(struct kunit *test) { DRM_RND_STATE(prng, random_seed); const unsigned int size = 8192; @@ -1524,7 +1393,6 @@ static int igt_evict(void *ignored) struct evict_node *nodes; struct drm_mm_node *node, *next; unsigned int *order, n; - int ret, err;
/* Here we populate a full drm_mm and then try and insert a new node * by evicting other nodes in a random order. The drm_mm_scan should @@ -1533,61 +1401,48 @@ static int igt_evict(void *ignored) * sizes to try and stress the hole finder. */
- ret = -ENOMEM; nodes = vzalloc(array_size(size, sizeof(*nodes))); - if (!nodes) - goto err; + KUNIT_ASSERT_TRUE(test, nodes);
order = drm_random_order(size, &prng); if (!order) goto err_nodes;
- ret = -EINVAL; drm_mm_init(&mm, 0, size); for (n = 0; n < size; n++) { - err = drm_mm_insert_node(&mm, &nodes[n].node, 1); - if (err) { - pr_err("insert failed, step %d\n", n); - ret = err; + if (drm_mm_insert_node(&mm, &nodes[n].node, 1)) { + KUNIT_FAIL(test, "insert failed, step %d\n", n); goto out; } }
/* First check that using the scanner doesn't break the mm */ - if (!evict_nothing(&mm, size, nodes)) { - pr_err("evict_nothing() failed\n"); + if (!evict_nothing(test, &mm, size, nodes)) { + KUNIT_FAIL(test, "evict_nothing() failed\n"); goto out; } - if (!evict_everything(&mm, size, nodes)) { - pr_err("evict_everything() failed\n"); + if (!evict_everything(test, &mm, size, nodes)) { + KUNIT_FAIL(test, "evict_everything() failed\n"); goto out; }
for (mode = evict_modes; mode->name; mode++) { for (n = 1; n <= size; n <<= 1) { drm_random_reorder(order, size, &prng); - err = evict_something(&mm, 0, U64_MAX, - nodes, order, size, - n, 1, - mode); - if (err) { - pr_err("%s evict_something(size=%u) failed\n", + if (evict_something(test, &mm, 0, U64_MAX, nodes, order, size, n, 1, mode)) { + KUNIT_FAIL(test, "%s evict_something(size=%u) failed\n", mode->name, n); - ret = err; goto out; } }
for (n = 1; n < size; n <<= 1) { drm_random_reorder(order, size, &prng); - err = evict_something(&mm, 0, U64_MAX, - nodes, order, size, - size/2, n, - mode); - if (err) { - pr_err("%s evict_something(size=%u, alignment=%u) failed\n", - mode->name, size/2, n); - ret = err; + if (evict_something(test, &mm, 0, U64_MAX, nodes, order, size, + size/2, n, mode)) { + KUNIT_FAIL(test, + "%s evict_something(size=%u, alignment=%u) failed\n", + mode->name, size/2, n); goto out; } } @@ -1598,14 +1453,10 @@ static int igt_evict(void *ignored) DRM_MM_BUG_ON(!nsize);
drm_random_reorder(order, size, &prng); - err = evict_something(&mm, 0, U64_MAX, - nodes, order, size, - nsize, n, - mode); - if (err) { - pr_err("%s evict_something(size=%u, alignment=%u) failed\n", - mode->name, nsize, n); - ret = err; + if (evict_something(test, &mm, 0, U64_MAX, nodes, order, size, + nsize, n, mode)) { + KUNIT_FAIL(test, "%s evict_something(size=%u, alignment=%u) failed\n", + mode->name, nsize, n); goto out; } } @@ -1613,7 +1464,6 @@ static int igt_evict(void *ignored) cond_resched(); }
- ret = 0; out: drm_mm_for_each_node_safe(node, next, &mm) drm_mm_remove_node(node); @@ -1621,11 +1471,9 @@ static int igt_evict(void *ignored) kfree(order); err_nodes: vfree(nodes); -err: - return ret; }
-static int igt_evict_range(void *ignored) +static void igt_mm_evict_range(struct kunit *test) { DRM_RND_STATE(prng, random_seed); const unsigned int size = 8192; @@ -1637,28 +1485,22 @@ static int igt_evict_range(void *ignored) struct evict_node *nodes; struct drm_mm_node *node, *next; unsigned int *order, n; - int ret, err;
/* Like igt_evict() but now we are limiting the search to a * small portion of the full drm_mm. */
- ret = -ENOMEM; nodes = vzalloc(array_size(size, sizeof(*nodes))); - if (!nodes) - goto err; + KUNIT_ASSERT_TRUE(test, nodes);
order = drm_random_order(size, &prng); if (!order) goto err_nodes;
- ret = -EINVAL; drm_mm_init(&mm, 0, size); for (n = 0; n < size; n++) { - err = drm_mm_insert_node(&mm, &nodes[n].node, 1); - if (err) { - pr_err("insert failed, step %d\n", n); - ret = err; + if (drm_mm_insert_node(&mm, &nodes[n].node, 1)) { + KUNIT_FAIL(test, "insert failed, step %d\n", n); goto out; } } @@ -1666,26 +1508,22 @@ static int igt_evict_range(void *ignored) for (mode = evict_modes; mode->name; mode++) { for (n = 1; n <= range_size; n <<= 1) { drm_random_reorder(order, size, &prng); - err = evict_something(&mm, range_start, range_end, - nodes, order, size, - n, 1, - mode); - if (err) { - pr_err("%s evict_something(size=%u) failed with range [%u, %u]\n", - mode->name, n, range_start, range_end); + if (evict_something(test, &mm, range_start, range_end, nodes, + order, size, n, 1, mode)) { + KUNIT_FAIL(test, + "%s evict_something(size=%u) failed with range [%u, %u]\n", + mode->name, n, range_start, range_end); goto out; } }
for (n = 1; n <= range_size; n <<= 1) { drm_random_reorder(order, size, &prng); - err = evict_something(&mm, range_start, range_end, - nodes, order, size, - range_size/2, n, - mode); - if (err) { - pr_err("%s evict_something(size=%u, alignment=%u) failed with range [%u, %u]\n", - mode->name, range_size/2, n, range_start, range_end); + if (evict_something(test, &mm, range_start, range_end, nodes, + order, size, range_size/2, n, mode)) { + KUNIT_FAIL(test, + "%s evict_something(size=%u, alignment=%u) failed with range [%u, %u]\n", + mode->name, range_size/2, n, range_start, range_end); goto out; } } @@ -1696,13 +1534,11 @@ static int igt_evict_range(void *ignored) DRM_MM_BUG_ON(!nsize);
drm_random_reorder(order, size, &prng); - err = evict_something(&mm, range_start, range_end, - nodes, order, size, - nsize, n, - mode); - if (err) { - pr_err("%s evict_something(size=%u, alignment=%u) failed with range [%u, %u]\n", - mode->name, nsize, n, range_start, range_end); + if (evict_something(test, &mm, range_start, range_end, nodes, + order, size, nsize, n, mode)) { + KUNIT_FAIL(test, + "%s evict_something(size=%u, alignment=%u) failed with range [%u, %u]\n", + mode->name, nsize, n, range_start, range_end); goto out; } } @@ -1710,7 +1546,6 @@ static int igt_evict_range(void *ignored) cond_resched(); }
- ret = 0; out: drm_mm_for_each_node_safe(node, next, &mm) drm_mm_remove_node(node); @@ -1718,8 +1553,6 @@ static int igt_evict_range(void *ignored) kfree(order); err_nodes: vfree(nodes); -err: - return ret; }
static unsigned int node_index(const struct drm_mm_node *node) @@ -1727,7 +1560,7 @@ static unsigned int node_index(const struct drm_mm_node *node) return div64_u64(node->start, node->size); }
-static int igt_topdown(void *ignored) +static void igt_mm_topdown(struct kunit *test) { const struct insert_mode *topdown = &insert_modes[TOPDOWN]; DRM_RND_STATE(prng, random_seed); @@ -1737,17 +1570,14 @@ static int igt_topdown(void *ignored) struct drm_mm mm; struct drm_mm_node *nodes, *node, *next; unsigned int *order, n, m, o = 0; - int ret;
/* When allocating top-down, we expect to be returned a node * from a suitable hole at the top of the drm_mm. We check that * the returned node does match the highest available slot. */
- ret = -ENOMEM; nodes = vzalloc(array_size(count, sizeof(*nodes))); - if (!nodes) - goto err; + KUNIT_ASSERT_TRUE(test, nodes);
bitmap = bitmap_zalloc(count, GFP_KERNEL); if (!bitmap) @@ -1757,28 +1587,26 @@ static int igt_topdown(void *ignored) if (!order) goto err_bitmap;
- ret = -EINVAL; for (size = 1; size <= 64; size <<= 1) { drm_mm_init(&mm, 0, size*count); for (n = 0; n < count; n++) { - if (!expect_insert(&mm, &nodes[n], - size, 0, n, - topdown)) { - pr_err("insert failed, size %u step %d\n", size, n); + if (!expect_insert(test, &mm, &nodes[n], size, 0, n, topdown)) { + KUNIT_FAIL(test, "insert failed, size %u step %d\n", size, n); goto out; }
if (drm_mm_hole_follows(&nodes[n])) { - pr_err("hole after topdown insert %d, start=%llx\n, size=%u", - n, nodes[n].start, size); + KUNIT_FAIL(test, + "hole after topdown insert %d, start=%llx\n, size=%u", + n, nodes[n].start, size); goto out; }
- if (!assert_one_hole(&mm, 0, size*(count - n - 1))) + if (!assert_one_hole(test, &mm, 0, size*(count - n - 1))) goto out; }
- if (!assert_continuous(&mm, size)) + if (!assert_continuous(test, &mm, size)) goto out;
drm_random_reorder(order, count, &prng); @@ -1793,23 +1621,23 @@ static int igt_topdown(void *ignored) unsigned int last;
node = &nodes[order[(o + m) % count]]; - if (!expect_insert(&mm, node, - size, 0, 0, - topdown)) { - pr_err("insert failed, step %d/%d\n", m, n); + if (!expect_insert(test, &mm, node, size, 0, 0, topdown)) { + KUNIT_FAIL(test, "insert failed, step %d/%d\n", m, n); goto out; }
if (drm_mm_hole_follows(node)) { - pr_err("hole after topdown insert %d/%d, start=%llx\n", - m, n, node->start); + KUNIT_FAIL(test, + "hole after topdown insert %d/%d, start=%llx\n", + m, n, node->start); goto out; }
last = find_last_bit(bitmap, count); if (node_index(node) != last) { - pr_err("node %d/%d, size %d, not inserted into upmost hole, expected %d, found %d\n", - m, n, size, last, node_index(node)); + KUNIT_FAIL(test, + "node %d/%d, size %d, not inserted into upmost hole, expected %d, found %d\n", + m, n, size, last, node_index(node)); goto out; }
@@ -1827,7 +1655,6 @@ static int igt_topdown(void *ignored) cond_resched(); }
- ret = 0; out: drm_mm_for_each_node_safe(node, next, &mm) drm_mm_remove_node(node); @@ -1837,11 +1664,9 @@ static int igt_topdown(void *ignored) bitmap_free(bitmap); err_nodes: vfree(nodes); -err: - return ret; }
-static int igt_bottomup(void *ignored) +static void igt_mm_bottomup(struct kunit *test) { const struct insert_mode *bottomup = &insert_modes[BOTTOMUP]; DRM_RND_STATE(prng, random_seed); @@ -1851,16 +1676,13 @@ static int igt_bottomup(void *ignored) struct drm_mm mm; struct drm_mm_node *nodes, *node, *next; unsigned int *order, n, m, o = 0; - int ret;
/* Like igt_topdown, but instead of searching for the last hole, * we search for the first. */
- ret = -ENOMEM; nodes = vzalloc(array_size(count, sizeof(*nodes))); - if (!nodes) - goto err; + KUNIT_ASSERT_TRUE(test, nodes);
bitmap = bitmap_zalloc(count, GFP_KERNEL); if (!bitmap) @@ -1870,22 +1692,20 @@ static int igt_bottomup(void *ignored) if (!order) goto err_bitmap;
- ret = -EINVAL; for (size = 1; size <= 64; size <<= 1) { drm_mm_init(&mm, 0, size*count); for (n = 0; n < count; n++) { - if (!expect_insert(&mm, &nodes[n], - size, 0, n, - bottomup)) { - pr_err("bottomup insert failed, size %u step %d\n", size, n); + if (!expect_insert(test, &mm, &nodes[n], size, 0, n, bottomup)) { + KUNIT_FAIL(test, + "bottomup insert failed, size %u step %d\n", size, n); goto out; }
- if (!assert_one_hole(&mm, size*(n + 1), size*count)) + if (!assert_one_hole(test, &mm, size*(n + 1), size*count)) goto out; }
- if (!assert_continuous(&mm, size)) + if (!assert_continuous(test, &mm, size)) goto out;
drm_random_reorder(order, count, &prng); @@ -1900,17 +1720,16 @@ static int igt_bottomup(void *ignored) unsigned int first;
node = &nodes[order[(o + m) % count]]; - if (!expect_insert(&mm, node, - size, 0, 0, - bottomup)) { - pr_err("insert failed, step %d/%d\n", m, n); + if (!expect_insert(test, &mm, node, size, 0, 0, bottomup)) { + KUNIT_FAIL(test, "insert failed, step %d/%d\n", m, n); goto out; }
first = find_first_bit(bitmap, count); if (node_index(node) != first) { - pr_err("node %d/%d not inserted into bottom hole, expected %d, found %d\n", - m, n, first, node_index(node)); + KUNIT_FAIL(test, + "node %d/%d not inserted into bottom hole, expected %d, found %d\n", + m, n, first, node_index(node)); goto out; } __clear_bit(first, bitmap); @@ -1927,7 +1746,6 @@ static int igt_bottomup(void *ignored) cond_resched(); }
- ret = 0; out: drm_mm_for_each_node_safe(node, next, &mm) drm_mm_remove_node(node); @@ -1937,47 +1755,39 @@ static int igt_bottomup(void *ignored) bitmap_free(bitmap); err_nodes: vfree(nodes); -err: - return ret; }
-static int __igt_once(unsigned int mode) +static void __igt_once(struct kunit *test, unsigned int mode) { struct drm_mm mm; struct drm_mm_node rsvd_lo, rsvd_hi, node; - int err;
drm_mm_init(&mm, 0, 7);
memset(&rsvd_lo, 0, sizeof(rsvd_lo)); rsvd_lo.start = 1; rsvd_lo.size = 1; - err = drm_mm_reserve_node(&mm, &rsvd_lo); - if (err) { - pr_err("Could not reserve low node\n"); + if (drm_mm_reserve_node(&mm, &rsvd_lo)) { + KUNIT_FAIL(test, "Could not reserve low node\n"); goto err; }
memset(&rsvd_hi, 0, sizeof(rsvd_hi)); rsvd_hi.start = 5; rsvd_hi.size = 1; - err = drm_mm_reserve_node(&mm, &rsvd_hi); - if (err) { - pr_err("Could not reserve low node\n"); + if (drm_mm_reserve_node(&mm, &rsvd_hi)) { + KUNIT_FAIL(test, "Could not reserve low node\n"); goto err_lo; }
if (!drm_mm_hole_follows(&rsvd_lo) || !drm_mm_hole_follows(&rsvd_hi)) { - pr_err("Expected a hole after lo and high nodes!\n"); - err = -EINVAL; + KUNIT_FAIL(test, "Expected a hole after lo and high nodes!\n"); goto err_hi; }
memset(&node, 0, sizeof(node)); - err = drm_mm_insert_node_generic(&mm, &node, 2, 0, 0, mode); - if (err) { - pr_err("Could not insert the node into the available hole!\n"); - err = -EINVAL; + if (drm_mm_insert_node_generic(&mm, &node, 2, 0, 0, mode)) { + KUNIT_FAIL(test, "Could not insert the node into the available hole!\n"); goto err_hi; }
@@ -1988,23 +1798,20 @@ static int __igt_once(unsigned int mode) drm_mm_remove_node(&rsvd_lo); err: drm_mm_takedown(&mm); - return err; }
-static int igt_lowest(void *ignored) +static void igt_mm_lowest(struct kunit *test) { - return __igt_once(DRM_MM_INSERT_LOW); + __igt_once(test, DRM_MM_INSERT_LOW); }
-static int igt_highest(void *ignored) +static void igt_mm_highest(struct kunit *test) { - return __igt_once(DRM_MM_INSERT_HIGH); + __igt_once(test, DRM_MM_INSERT_HIGH); }
static void separate_adjacent_colors(const struct drm_mm_node *node, - unsigned long color, - u64 *start, - u64 *end) + unsigned long color, u64 *start, u64 *end) { if (drm_mm_node_allocated(node) && node->color != color) ++*start; @@ -2014,11 +1821,11 @@ static void separate_adjacent_colors(const struct drm_mm_node *node, --*end; }
-static bool colors_abutt(const struct drm_mm_node *node) +static bool colors_abutt(struct kunit *test, const struct drm_mm_node *node) { if (!drm_mm_hole_follows(node) && drm_mm_node_allocated(list_next_entry(node, node_list))) { - pr_err("colors abutt; %ld [%llx + %llx] is next to %ld [%llx + %llx]!\n", + KUNIT_FAIL(test, "colors abutt; %ld [%llx + %llx] is next to %ld [%llx + %llx]!\n", node->color, node->start, node->size, list_next_entry(node, node_list)->color, list_next_entry(node, node_list)->start, @@ -2029,14 +1836,13 @@ static bool colors_abutt(const struct drm_mm_node *node) return false; }
-static int igt_color(void *ignored) +static void igt_mm_color(struct kunit *test) { const unsigned int count = min(4096u, max_iterations); const struct insert_mode *mode; struct drm_mm mm; struct drm_mm_node *node, *nn; unsigned int n; - int ret = -EINVAL, err;
/* Color adjustment complicates everything. First we just check * that when we insert a node we apply any color_adjustment callback. @@ -2050,14 +1856,11 @@ static int igt_color(void *ignored) for (n = 1; n <= count; n++) { node = kzalloc(sizeof(*node), GFP_KERNEL); if (!node) { - ret = -ENOMEM; goto out; }
- if (!expect_insert(&mm, node, - n, 0, n, - &insert_modes[0])) { - pr_err("insert failed, step %d\n", n); + if (!expect_insert(test, &mm, node, n, 0, n, &insert_modes[0])) { + KUNIT_FAIL(test, "insert failed, step %d\n", n); kfree(node); goto out; } @@ -2065,7 +1868,7 @@ static int igt_color(void *ignored)
drm_mm_for_each_node_safe(node, nn, &mm) { if (node->color != node->size) { - pr_err("invalid color stored: expected %lld, found %ld\n", + KUNIT_FAIL(test, "invalid color stored: expected %lld, found %ld\n", node->size, node->color);
goto out; @@ -2082,17 +1885,14 @@ static int igt_color(void *ignored)
node = kzalloc(sizeof(*node), GFP_KERNEL); if (!node) { - ret = -ENOMEM; goto out; }
node->size = 1 + 2*count; node->color = node->size;
- err = drm_mm_reserve_node(&mm, node); - if (err) { - pr_err("initial reserve failed!\n"); - ret = err; + if (drm_mm_reserve_node(&mm, node)) { + KUNIT_FAIL(test, "initial reserve failed!\n"); goto out; }
@@ -2103,7 +1903,6 @@ static int igt_color(void *ignored)
node = kzalloc(sizeof(*node), GFP_KERNEL); if (!node) { - ret = -ENOMEM; goto out; }
@@ -2111,10 +1910,8 @@ static int igt_color(void *ignored) node->size = n + count; node->color = node->size;
- err = drm_mm_reserve_node(&mm, node); - if (err != -ENOSPC) { - pr_err("reserve %d did not report color overlap! err=%d\n", - n, err); + if (drm_mm_reserve_node(&mm, node) != -ENOSPC) { + KUNIT_FAIL(test, "reserve %d did not report color overlap!", n); goto out; }
@@ -2122,10 +1919,8 @@ static int igt_color(void *ignored) rem = misalignment(node, n + count); node->start += n + count - rem;
- err = drm_mm_reserve_node(&mm, node); - if (err) { - pr_err("reserve %d failed, err=%d\n", n, err); - ret = err; + if (drm_mm_reserve_node(&mm, node)) { + KUNIT_FAIL(test, "reserve %d failed", n); goto out; }
@@ -2135,15 +1930,11 @@ static int igt_color(void *ignored) for (n = 1; n <= count; n++) { node = kzalloc(sizeof(*node), GFP_KERNEL); if (!node) { - ret = -ENOMEM; goto out; }
- if (!expect_insert(&mm, node, - n, n, n, - mode)) { - pr_err("%s insert failed, step %d\n", - mode->name, n); + if (!expect_insert(test, &mm, node, n, n, n, mode)) { + KUNIT_FAIL(test, "%s insert failed, step %d\n", mode->name, n); kfree(node); goto out; } @@ -2153,19 +1944,21 @@ static int igt_color(void *ignored) u64 rem;
if (node->color != node->size) { - pr_err("%s invalid color stored: expected %lld, found %ld\n", - mode->name, node->size, node->color); + KUNIT_FAIL(test, + "%s invalid color stored: expected %lld, found %ld\n", + mode->name, node->size, node->color);
goto out; }
- if (colors_abutt(node)) + if (colors_abutt(test, node)) goto out;
div64_u64_rem(node->start, node->size, &rem); if (rem) { - pr_err("%s colored node misaligned, start=%llx expected alignment=%lld [rem=%lld]\n", - mode->name, node->start, node->size, rem); + KUNIT_FAIL(test, + "%s colored node misaligned, start=%llx expected alignment=%lld [rem=%lld]\n", + mode->name, node->start, node->size, rem); goto out; }
@@ -2176,25 +1969,18 @@ static int igt_color(void *ignored) cond_resched(); }
- ret = 0; out: drm_mm_for_each_node_safe(node, nn, &mm) { drm_mm_remove_node(node); kfree(node); } drm_mm_takedown(&mm); - return ret; }
-static int evict_color(struct drm_mm *mm, - u64 range_start, u64 range_end, - struct evict_node *nodes, - unsigned int *order, - unsigned int count, - unsigned int size, - unsigned int alignment, - unsigned long color, - const struct insert_mode *mode) +static int evict_color(struct kunit *test, struct drm_mm *mm, u64 range_start, + u64 range_end, struct evict_node *nodes, unsigned int *order, + unsigned int count, unsigned int size, unsigned int alignment, + unsigned long color, const struct insert_mode *mode) { struct drm_mm_scan scan; LIST_HEAD(evict_list); @@ -2202,39 +1988,37 @@ static int evict_color(struct drm_mm *mm, struct drm_mm_node tmp; int err;
- drm_mm_scan_init_with_range(&scan, mm, - size, alignment, color, - range_start, range_end, - mode->mode); - if (!evict_nodes(&scan, - nodes, order, count, true, - &evict_list)) + drm_mm_scan_init_with_range(&scan, mm, size, alignment, color, range_start, + range_end, mode->mode); + if (!evict_nodes(test, &scan, nodes, order, count, true, &evict_list)) return -EINVAL;
memset(&tmp, 0, sizeof(tmp)); err = drm_mm_insert_node_generic(mm, &tmp, size, alignment, color, DRM_MM_INSERT_EVICT); if (err) { - pr_err("Failed to insert into eviction hole: size=%d, align=%d, color=%lu, err=%d\n", - size, alignment, color, err); - show_scan(&scan); - show_holes(mm, 3); + KUNIT_FAIL(test, + "Failed to insert into eviction hole: size=%d, align=%d, color=%lu, err=%d\n", + size, alignment, color, err); + show_scan(test, &scan); + show_holes(test, mm, 3); return err; }
if (tmp.start < range_start || tmp.start + tmp.size > range_end) { - pr_err("Inserted [address=%llu + %llu] did not fit into the request range [%llu, %llu]\n", - tmp.start, tmp.size, range_start, range_end); + KUNIT_FAIL(test, + "Inserted [address=%llu + %llu] did not fit into the request range [%llu, %llu]\n", + tmp.start, tmp.size, range_start, range_end); err = -EINVAL; }
- if (colors_abutt(&tmp)) + if (colors_abutt(test, &tmp)) err = -EINVAL;
- if (!assert_node(&tmp, mm, size, alignment, color)) { - pr_err("Inserted did not fit the eviction hole: size=%lld [%d], align=%d [rem=%lld], start=%llx\n", - tmp.size, size, - alignment, misalignment(&tmp, alignment), tmp.start); + if (!assert_node(test, &tmp, mm, size, alignment, color)) { + KUNIT_FAIL(test, + "Inserted did not fit the eviction hole: size=%lld [%d], align=%d [rem=%lld], start=%llx\n", + tmp.size, size, alignment, misalignment(&tmp, alignment), tmp.start); err = -EINVAL; }
@@ -2245,7 +2029,7 @@ static int evict_color(struct drm_mm *mm, list_for_each_entry(e, &evict_list, link) { err = drm_mm_reserve_node(mm, &e->node); if (err) { - pr_err("Failed to reinsert node after eviction: start=%llx\n", + KUNIT_FAIL(test, "Failed to reinsert node after eviction: start=%llx\n", e->node.start); return err; } @@ -2255,7 +2039,7 @@ static int evict_color(struct drm_mm *mm, return 0; }
-static int igt_color_evict(void *ignored) +static void igt_mm_color_evict(struct kunit *test) { DRM_RND_STATE(prng, random_seed); const unsigned int total_size = min(8192u, max_iterations); @@ -2265,7 +2049,6 @@ static int igt_color_evict(void *ignored) struct evict_node *nodes; struct drm_mm_node *node, *next; unsigned int *order, n; - int ret, err;
/* Check that the drm_mm_scan also honours color adjustment when * choosing its victims to create a hole. Our color_adjust does not @@ -2273,23 +2056,20 @@ static int igt_color_evict(void *ignored) * enlarging the set of victims that must be evicted. */
- ret = -ENOMEM; nodes = vzalloc(array_size(total_size, sizeof(*nodes))); - if (!nodes) - goto err; + KUNIT_ASSERT_TRUE(test, nodes);
order = drm_random_order(total_size, &prng); if (!order) goto err_nodes;
- ret = -EINVAL; drm_mm_init(&mm, 0, 2*total_size - 1); mm.color_adjust = separate_adjacent_colors; for (n = 0; n < total_size; n++) { - if (!expect_insert(&mm, &nodes[n].node, + if (!expect_insert(test, &mm, &nodes[n].node, 1, 0, color++, &insert_modes[0])) { - pr_err("insert failed, step %d\n", n); + KUNIT_FAIL(test, "insert failed, step %d\n", n); goto out; } } @@ -2297,25 +2077,18 @@ static int igt_color_evict(void *ignored) for (mode = evict_modes; mode->name; mode++) { for (n = 1; n <= total_size; n <<= 1) { drm_random_reorder(order, total_size, &prng); - err = evict_color(&mm, 0, U64_MAX, - nodes, order, total_size, - n, 1, color++, - mode); - if (err) { - pr_err("%s evict_color(size=%u) failed\n", - mode->name, n); + if (evict_color(test, &mm, 0, U64_MAX, nodes, order, total_size, + n, 1, color++, mode)) { + KUNIT_FAIL(test, "%s evict_color(size=%u) failed\n", mode->name, n); goto out; } }
for (n = 1; n < total_size; n <<= 1) { drm_random_reorder(order, total_size, &prng); - err = evict_color(&mm, 0, U64_MAX, - nodes, order, total_size, - total_size/2, n, color++, - mode); - if (err) { - pr_err("%s evict_color(size=%u, alignment=%u) failed\n", + if (evict_color(test, &mm, 0, U64_MAX, nodes, order, total_size, + total_size/2, n, color++, mode)) { + KUNIT_FAIL(test, "%s evict_color(size=%u, alignment=%u) failed\n", mode->name, total_size/2, n); goto out; } @@ -2327,12 +2100,9 @@ static int igt_color_evict(void *ignored) DRM_MM_BUG_ON(!nsize);
drm_random_reorder(order, total_size, &prng); - err = evict_color(&mm, 0, U64_MAX, - nodes, order, total_size, - nsize, n, color++, - mode); - if (err) { - pr_err("%s evict_color(size=%u, alignment=%u) failed\n", + if (evict_color(test, &mm, 0, U64_MAX, nodes, order, total_size, + nsize, n, color++, mode)) { + KUNIT_FAIL(test, "%s evict_color(size=%u, alignment=%u) failed\n", mode->name, nsize, n); goto out; } @@ -2341,21 +2111,16 @@ static int igt_color_evict(void *ignored) cond_resched(); }
- ret = 0; out: - if (ret) - show_mm(&mm); drm_mm_for_each_node_safe(node, next, &mm) drm_mm_remove_node(node); drm_mm_takedown(&mm); kfree(order); err_nodes: vfree(nodes); -err: - return ret; }
-static int igt_color_evict_range(void *ignored) +static void igt_mm_color_evict_range(struct kunit *test) { DRM_RND_STATE(prng, random_seed); const unsigned int total_size = 8192; @@ -2368,29 +2133,25 @@ static int igt_color_evict_range(void *ignored) struct evict_node *nodes; struct drm_mm_node *node, *next; unsigned int *order, n; - int ret, err;
/* Like igt_color_evict(), but limited to small portion of the full * drm_mm range. */
- ret = -ENOMEM; nodes = vzalloc(array_size(total_size, sizeof(*nodes))); - if (!nodes) - goto err; + KUNIT_ASSERT_TRUE(test, nodes);
order = drm_random_order(total_size, &prng); if (!order) goto err_nodes;
- ret = -EINVAL; drm_mm_init(&mm, 0, 2*total_size - 1); mm.color_adjust = separate_adjacent_colors; for (n = 0; n < total_size; n++) { - if (!expect_insert(&mm, &nodes[n].node, + if (!expect_insert(test, &mm, &nodes[n].node, 1, 0, color++, &insert_modes[0])) { - pr_err("insert failed, step %d\n", n); + KUNIT_FAIL(test, "insert failed, step %d\n", n); goto out; } } @@ -2398,26 +2159,21 @@ static int igt_color_evict_range(void *ignored) for (mode = evict_modes; mode->name; mode++) { for (n = 1; n <= range_size; n <<= 1) { drm_random_reorder(order, range_size, &prng); - err = evict_color(&mm, range_start, range_end, - nodes, order, total_size, - n, 1, color++, - mode); - if (err) { - pr_err("%s evict_color(size=%u) failed for range [%x, %x]\n", - mode->name, n, range_start, range_end); + if (evict_color(test, &mm, range_start, range_end, nodes, order, + total_size, n, 1, color++, mode)) { + KUNIT_FAIL(test, "%s evict_color(size=%u) failed for range [%x, %x]\n", + mode->name, n, range_start, range_end); goto out; } }
for (n = 1; n < range_size; n <<= 1) { drm_random_reorder(order, total_size, &prng); - err = evict_color(&mm, range_start, range_end, - nodes, order, total_size, - range_size/2, n, color++, - mode); - if (err) { - pr_err("%s evict_color(size=%u, alignment=%u) failed for range [%x, %x]\n", - mode->name, total_size/2, n, range_start, range_end); + if (evict_color(test, &mm, range_start, range_end, nodes, order, + total_size, range_size/2, n, color++, mode)) { + KUNIT_FAIL(test, + "%s evict_color(size=%u, alignment=%u) failed for range [%x, %x]\n", + mode->name, total_size/2, n, range_start, range_end); goto out; } } @@ -2428,13 +2184,11 @@ static int igt_color_evict_range(void *ignored) DRM_MM_BUG_ON(!nsize);
drm_random_reorder(order, total_size, &prng); - err = evict_color(&mm, range_start, range_end, - nodes, order, total_size, - nsize, n, color++, - mode); - if (err) { - pr_err("%s evict_color(size=%u, alignment=%u) failed for range [%x, %x]\n", - mode->name, nsize, n, range_start, range_end); + if (evict_color(test, &mm, range_start, range_end, nodes, order, + total_size, nsize, n, color++, mode)) { + KUNIT_FAIL(test, + "%s evict_color(size=%u, alignment=%u) failed for range [%x, %x]\n", + mode->name, nsize, n, range_start, range_end); goto out; } } @@ -2442,46 +2196,57 @@ static int igt_color_evict_range(void *ignored) cond_resched(); }
- ret = 0; out: - if (ret) - show_mm(&mm); drm_mm_for_each_node_safe(node, next, &mm) drm_mm_remove_node(node); drm_mm_takedown(&mm); kfree(order); err_nodes: vfree(nodes); -err: - return ret; }
-#include "drm_selftest.c" - -static int __init test_drm_mm_init(void) +static int drm_mm_init_test(struct kunit *test) { - int err; - while (!random_seed) random_seed = get_random_int();
- pr_info("Testing DRM range manager (struct drm_mm), with random_seed=0x%x max_iterations=%u max_prime=%u\n", - random_seed, max_iterations, max_prime); - err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL); - - return err > 0 ? 0 : err; -} - -static void __exit test_drm_mm_exit(void) -{ + return 0; }
-module_init(test_drm_mm_init); -module_exit(test_drm_mm_exit); - module_param(random_seed, uint, 0400); module_param(max_iterations, uint, 0400); module_param(max_prime, uint, 0400);
+static struct kunit_case drm_mm_tests[] = { + KUNIT_CASE(igt_mm_init), + KUNIT_CASE(igt_mm_debug), + KUNIT_CASE(igt_mm_reserve), + KUNIT_CASE(igt_mm_insert), + KUNIT_CASE(igt_mm_replace), + KUNIT_CASE(igt_mm_insert_range), + KUNIT_CASE(igt_mm_frag), + KUNIT_CASE(igt_mm_align), + KUNIT_CASE(igt_mm_align32), + KUNIT_CASE(igt_mm_align64), + KUNIT_CASE(igt_mm_evict), + KUNIT_CASE(igt_mm_evict_range), + KUNIT_CASE(igt_mm_topdown), + KUNIT_CASE(igt_mm_bottomup), + KUNIT_CASE(igt_mm_lowest), + KUNIT_CASE(igt_mm_highest), + KUNIT_CASE(igt_mm_color), + KUNIT_CASE(igt_mm_color_evict), + KUNIT_CASE(igt_mm_color_evict_range), + {} +}; + +static struct kunit_suite drm_mm_test_suite = { + .name = "drm_mm", + .init = drm_mm_init_test, + .test_cases = drm_mm_tests, +}; + +kunit_test_suite(drm_mm_test_suite); + MODULE_AUTHOR("Intel Corporation"); MODULE_LICENSE("GPL");
linux-kselftest-mirror@lists.linaro.org