unsigned int *i915_random_order(unsigned int count, struct rnd_state *state) { unsigned int *order, i; order = kmalloc_array(count, sizeof(*order), GFP_TEMPORARY); if (!order) return order; for (i = 0; i < count; i++) order[i] = i; i915_random_reorder(order, count, state); return order; }
static int igt_random_insert_remove(void *arg) { const u32 seqno_bias = 0x1000; I915_RND_STATE(prng); struct intel_engine_cs *engine = arg; struct intel_wait *waiters; const int count = 4096; unsigned int *order; unsigned long *bitmap; int err = -ENOMEM; int n; mock_engine_reset(engine); waiters = kvmalloc_array(count, sizeof(*waiters), GFP_KERNEL); if (!waiters) goto out_engines; bitmap = kcalloc(DIV_ROUND_UP(count, BITS_PER_LONG), sizeof(*bitmap), GFP_KERNEL); if (!bitmap) goto out_waiters; order = i915_random_order(count, &prng); if (!order) goto out_bitmap; for (n = 0; n < count; n++) intel_wait_init_for_seqno(&waiters[n], seqno_bias + n); err = check_rbtree(engine, bitmap, waiters, count); if (err) goto out_order; /* Add and remove waiters into the rbtree in random order. At each * step, we verify that the rbtree is correctly ordered. */ for (n = 0; n < count; n++) { int i = order[n]; intel_engine_add_wait(engine, &waiters[i]); __set_bit(i, bitmap); err = check_rbtree(engine, bitmap, waiters, count); if (err) goto out_order; } i915_random_reorder(order, count, &prng); for (n = 0; n < count; n++) { int i = order[n]; intel_engine_remove_wait(engine, &waiters[i]); __clear_bit(i, bitmap); err = check_rbtree(engine, bitmap, waiters, count); if (err) goto out_order; } err = check_rbtree_empty(engine); out_order: kfree(order); out_bitmap: kfree(bitmap); out_waiters: kvfree(waiters); out_engines: mock_engine_flush(engine); return err; }