Check that if we request top-down allocation with a particular alignment from drm_mm_insert_node() that the start of the node matches our request. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/drm_mm_selftests.h | 1 + drivers/gpu/drm/test-drm_mm.c | 92 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/drivers/gpu/drm/drm_mm_selftests.h b/drivers/gpu/drm/drm_mm_selftests.h index d435234e0e86..6bbdbb929714 100644 --- a/drivers/gpu/drm/drm_mm_selftests.h +++ b/drivers/gpu/drm/drm_mm_selftests.h @@ -5,6 +5,7 @@ * * Tests are executed in reverse order by igt/drm_mm */ +selftest(topdown_align, igt_topdown_align) selftest(topdown, igt_topdown) selftest(evict, igt_evict) selftest(align64, igt_align64) diff --git a/drivers/gpu/drm/test-drm_mm.c b/drivers/gpu/drm/test-drm_mm.c index 270d0732f1ab..7699e7e2c698 100644 --- a/drivers/gpu/drm/test-drm_mm.c +++ b/drivers/gpu/drm/test-drm_mm.c @@ -1038,6 +1038,98 @@ static int igt_topdown(void *ignored) return ret; } +static int igt_topdown_align(void *ignored) +{ + struct drm_mm mm; + struct drm_mm_node tmp, resv; + int ret = -EINVAL; + int n, m, err; + + drm_mm_init(&mm, 0, ~0ull); + memset(&tmp, 0, sizeof(tmp)); + memset(&resv, 0, sizeof(resv)); + + for (m = 0; m < 32; m++) { + u64 end = ~0ull; + + if (m) { + resv.size = BIT_ULL(m); + end -= resv.size; + resv.start = end; + + err = drm_mm_reserve_node(&mm, &resv); + if (err) { + pr_err("reservation of sentinel node failed\n"); + ret = err; + goto out; + } + } + + for (n = 0; n < 63 - m; n++) { + u64 align = BIT_ULL(n); + + err = drm_mm_insert_node_generic(&mm, &tmp, 1, align, 0, + DRM_MM_SEARCH_BELOW, + DRM_MM_CREATE_TOP); + drm_mm_remove_node(&tmp); + if (err) { + pr_err("insert failed, ret=%d\n", err); + ret = err; + goto out; + } + + if (tmp.start & (align - 1)) { + pr_err("insert alignment failed, aligment=%llx, start=%llx\n", + align, tmp.start); + goto out; + } + + if (tmp.start < end - align) { + pr_err("topdown insert failed, start=%llx, align=%llx, end=%llx\n", + tmp.start, align, end); + goto out; + } + } + + for_each_prime(n, min(8192ull, end - 1)) { + u64 rem; + + err = drm_mm_insert_node_generic(&mm, &tmp, n, 0, 0, + DRM_MM_SEARCH_BELOW, + DRM_MM_CREATE_TOP); + drm_mm_remove_node(&tmp); + if (err) { + pr_err("insert failed, ret=%d\n", err); + ret = err; + goto out; + } + + div64_u64_rem(tmp.start, n, &rem); + if (rem) { + pr_err("insert alignment failed, aligment=%d, start=%llx (offset %d)\n", + n, tmp.start, (int)rem); + goto out; + } + + if (tmp.start < end - n) { + pr_err("topdown insert failed, start=%llx, align=%d, end=%llx\n", + tmp.start, n, end); + goto out; + } + } + + if (resv.allocated) + drm_mm_remove_node(&resv); + } + + ret = 0; +out: + if (resv.allocated) + drm_mm_remove_node(&resv); + drm_mm_takedown(&mm); + return ret; +} + #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