Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright © 2020 Intel Corporation
0004  */
0005 
0006 static struct intel_ring *mock_ring(unsigned long sz)
0007 {
0008     struct intel_ring *ring;
0009 
0010     ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
0011     if (!ring)
0012         return NULL;
0013 
0014     kref_init(&ring->ref);
0015     ring->size = sz;
0016     ring->wrap = BITS_PER_TYPE(ring->size) - ilog2(sz);
0017     ring->effective_size = sz;
0018     ring->vaddr = (void *)(ring + 1);
0019     atomic_set(&ring->pin_count, 1);
0020 
0021     intel_ring_update_space(ring);
0022 
0023     return ring;
0024 }
0025 
0026 static void mock_ring_free(struct intel_ring *ring)
0027 {
0028     kfree(ring);
0029 }
0030 
0031 static int check_ring_direction(struct intel_ring *ring,
0032                 u32 next, u32 prev,
0033                 int expected)
0034 {
0035     int result;
0036 
0037     result = intel_ring_direction(ring, next, prev);
0038     if (result < 0)
0039         result = -1;
0040     else if (result > 0)
0041         result = 1;
0042 
0043     if (result != expected) {
0044         pr_err("intel_ring_direction(%u, %u):%d != %d\n",
0045                next, prev, result, expected);
0046         return -EINVAL;
0047     }
0048 
0049     return 0;
0050 }
0051 
0052 static int check_ring_step(struct intel_ring *ring, u32 x, u32 step)
0053 {
0054     u32 prev = x, next = intel_ring_wrap(ring, x + step);
0055     int err = 0;
0056 
0057     err |= check_ring_direction(ring, next, next,  0);
0058     err |= check_ring_direction(ring, prev, prev,  0);
0059     err |= check_ring_direction(ring, next, prev,  1);
0060     err |= check_ring_direction(ring, prev, next, -1);
0061 
0062     return err;
0063 }
0064 
0065 static int check_ring_offset(struct intel_ring *ring, u32 x, u32 step)
0066 {
0067     int err = 0;
0068 
0069     err |= check_ring_step(ring, x, step);
0070     err |= check_ring_step(ring, intel_ring_wrap(ring, x + 1), step);
0071     err |= check_ring_step(ring, intel_ring_wrap(ring, x - 1), step);
0072 
0073     return err;
0074 }
0075 
0076 static int igt_ring_direction(void *dummy)
0077 {
0078     struct intel_ring *ring;
0079     unsigned int half = 2048;
0080     int step, err = 0;
0081 
0082     ring = mock_ring(2 * half);
0083     if (!ring)
0084         return -ENOMEM;
0085 
0086     GEM_BUG_ON(ring->size != 2 * half);
0087 
0088     /* Precision of wrap detection is limited to ring->size / 2 */
0089     for (step = 1; step < half; step <<= 1) {
0090         err |= check_ring_offset(ring, 0, step);
0091         err |= check_ring_offset(ring, half, step);
0092     }
0093     err |= check_ring_step(ring, 0, half - 64);
0094 
0095     /* And check unwrapped handling for good measure */
0096     err |= check_ring_offset(ring, 0, 2 * half + 64);
0097     err |= check_ring_offset(ring, 3 * half, 1);
0098 
0099     mock_ring_free(ring);
0100     return err;
0101 }
0102 
0103 int intel_ring_mock_selftests(void)
0104 {
0105     static const struct i915_subtest tests[] = {
0106         SUBTEST(igt_ring_direction),
0107     };
0108 
0109     return i915_subtests(tests, NULL);
0110 }