Check that we can request alignment to any power-of-two or prime using a plain drm_mm_node_insert(), and also handle a reasonable selection of primes. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/selftests/drm_mm_selftests.h | 3 + drivers/gpu/drm/selftests/test-drm_mm.c | 104 +++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h b/drivers/gpu/drm/selftests/drm_mm_selftests.h index f2bd271fc21c..9eb0c9fd9dff 100644 --- a/drivers/gpu/drm/selftests/drm_mm_selftests.h +++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h @@ -5,6 +5,9 @@ * * Tests are executed in reverse order by igt/drm_mm */ +selftest(align64, igt_align64) +selftest(align32, igt_align32) +selftest(align, igt_align) selftest(insert_range, igt_insert_range) selftest(replace, igt_replace) selftest(insert, igt_insert) diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c b/drivers/gpu/drm/selftests/test-drm_mm.c index 92744221749b..be47e4aeec12 100644 --- a/drivers/gpu/drm/selftests/test-drm_mm.c +++ b/drivers/gpu/drm/selftests/test-drm_mm.c @@ -669,6 +669,110 @@ static int igt_insert_range(void *ignored) return 0; } +static int igt_align(void *ignored) +{ + struct drm_mm mm; + struct drm_mm_node *node, *next; + int ret = -EINVAL; + int prime; + + drm_mm_init(&mm, 1, U64_MAX - 1); + + drm_for_each_prime(prime, 8192) { + u64 size; + int err; + + node = kzalloc(sizeof(*node), GFP_KERNEL); + if (!node) { + ret = -ENOMEM; + goto out; + } + + size = drm_next_prime_number(prime); + err = drm_mm_insert_node_generic(&mm, node, size, prime, 0, + DRM_MM_SEARCH_DEFAULT, + DRM_MM_CREATE_DEFAULT); + if (err) { + pr_err("insert failed with alignment=%d", prime); + ret = err; + goto out; + } + + if ((int)node->start % prime) { + pr_err("node inserted into wrong location %llx, expected alignment to %d [rem %d]\n", + node->start, prime, (int)node->start % prime); + goto out; + } + } + + 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_align_pot(int max) +{ + struct drm_mm mm; + struct drm_mm_node *node, *next; + int bit; + int ret = -EINVAL; + + drm_mm_init(&mm, 1, U64_MAX - 1); + + for (bit = max - 1; bit; bit--) { + u64 align, size; + int err; + + node = kzalloc(sizeof(*node), GFP_KERNEL); + if (!node) { + ret = -ENOMEM; + goto out; + } + + align = BIT_ULL(bit); + size = BIT_ULL(bit-1) + 1; + err = drm_mm_insert_node_generic(&mm, node, size, align, 0, + DRM_MM_SEARCH_DEFAULT, + DRM_MM_CREATE_DEFAULT); + if (err) { + pr_err("insert failed with alignment=%llx [%d]", + align, bit); + ret = err; + goto out; + } + + if (node->start & (align - 1)) { + pr_err("node inserted into wrong location %llx, expected alignment to %llx [%d]\n", + node->start, align, bit); + goto out; + } + } + + 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) +{ + return igt_align_pot(32); +} + +static int igt_align64(void *ignored) +{ + return igt_align_pot(64); +} + #include "drm_selftest.c" static int __init test_drm_mm_init(void) -- 2.11.0 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel