Check that if we request top-down allocation from drm_mm_insert_node() we receive the next available hole from the top. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/selftests/drm_mm_selftests.h | 1 + drivers/gpu/drm/selftests/test-drm_mm.c | 97 ++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h b/drivers/gpu/drm/selftests/drm_mm_selftests.h index 0b60b1da39a1..357fe430e36e 100644 --- a/drivers/gpu/drm/selftests/drm_mm_selftests.h +++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h @@ -5,6 +5,7 @@ * * Tests are executed in reverse order by igt/drm_mm */ +selftest(topdown, igt_topdown) selftest(evict_range, igt_evict_range) selftest(evict, igt_evict) selftest(align64, igt_align64) diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c b/drivers/gpu/drm/selftests/test-drm_mm.c index 48e576531ead..22e7904cdaea 100644 --- a/drivers/gpu/drm/selftests/test-drm_mm.c +++ b/drivers/gpu/drm/selftests/test-drm_mm.c @@ -1214,6 +1214,103 @@ static int igt_evict_range(void *ignored) return ret; } +static int igt_topdown(void *ignored) +{ + u32 lcg_state = random_seed; + const int size = 8192; + unsigned long *bitmap; + struct drm_mm mm; + struct drm_mm_node *nodes, *node, *next; + int *order, n, m, o = 0; + int ret; + + ret = -ENOMEM; + nodes = vzalloc(size * sizeof(*nodes)); + if (!nodes) + goto err; + + bitmap = kzalloc(size / BITS_PER_LONG * sizeof(unsigned long), + GFP_TEMPORARY); + if (!bitmap) + goto err_nodes; + + order = drm_random_order(size, &lcg_state); + if (!order) + goto err_bitmap; + + ret = -EINVAL; + drm_mm_init(&mm, 0, size); + for (n = 0; n < size; n++) { + int err; + + err = drm_mm_insert_node_generic(&mm, &nodes[n], 1, 0, 0, + DRM_MM_SEARCH_BELOW, + DRM_MM_CREATE_TOP); + if (err) { + pr_err("insert failed, step %d\n", n); + ret = err; + goto out; + } + + if (nodes[n].hole_follows) { + pr_err("hole after topdown insert %d, start=%llx\n", + n, nodes[n].start); + goto out; + } + } + + drm_for_each_prime(n, size) { + for (m = 0; m < n; m++) { + node = &nodes[order[(o + m) % size]]; + drm_mm_remove_node(node); + __set_bit(node->start, bitmap); + } + + for (m = 0; m < n; m++) { + int err, last; + + node = &nodes[order[(o + m) % size]]; + err = drm_mm_insert_node_generic(&mm, node, 1, 0, 0, + DRM_MM_SEARCH_BELOW, + DRM_MM_CREATE_TOP); + if (err) { + pr_err("insert failed, step %d/%d\n", m, n); + ret = err; + goto out; + } + + if (node->hole_follows) { + pr_err("hole after topdown insert %d/%d, start=%llx\n", + m, n, node->start); + goto out; + } + + last = find_last_bit(bitmap, size); + if (node->start != last) { + pr_err("node %d/%d not inserted into upmost hole, expected %d, found %lld\n", + m, n, last, node->start); + goto out; + } + __clear_bit(last, bitmap); + } + + o += n; + } + + ret = 0; +out: + drm_mm_for_each_node_safe(node, next, &mm) + drm_mm_remove_node(node); + drm_mm_takedown(&mm); + kfree(order); +err_bitmap: + kfree(bitmap); +err_nodes: + vfree(nodes); +err: + 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