[RFC PATCH i-g-t v3 2/4] lib: Add GEM minimum page size helper

Chris Wilson chris at chris-wilson.co.uk
Wed Oct 30 10:48:22 UTC 2019


Quoting Janusz Krzysztofik (2019-10-30 10:38:48)
> Some tests assume 4kB page size while using softpin.  That assumption
> may be wrong on future GEM backends with possibly larger minimum page
> sizes.  As a result, those tests may either fail on softpin at offsets
> which are incorrectly aligned, may silently skip such incorrectly
> aligned addresses assuming them occupied by other users, or may always
> succeed when examining invalid use patterns.
> 
> Provide a helper function that detects minimum page size and returns
> the size order.  Tests may use it to calculate softpin offsets suitable
> for actually used backing store.
> 
> Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik at linux.intel.com>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
> Cc: Stuart Summers <stuart.summers at intel.com>
> ---
>  lib/ioctl_wrappers.c | 82 ++++++++++++++++++++++++++++++++++++++++++++
>  lib/ioctl_wrappers.h |  1 +
>  2 files changed, 83 insertions(+)
> 
> diff --git a/lib/ioctl_wrappers.c b/lib/ioctl_wrappers.c
> index 280fdd62..a4313832 100644
> --- a/lib/ioctl_wrappers.c
> +++ b/lib/ioctl_wrappers.c
> @@ -54,6 +54,7 @@
>  #include "intel_io.h"
>  #include "igt_debugfs.h"
>  #include "igt_sysfs.h"
> +#include "igt_x86.h"
>  #include "config.h"
>  
>  #ifdef HAVE_VALGRIND
> @@ -1157,6 +1158,87 @@ bool gem_has_softpin(int fd)
>         return has_softpin;
>  }
>  
> +static int __min_page_size_order(int fd, struct drm_i915_gem_exec_object2 *obj,
> +                                struct drm_i915_gem_execbuffer2 *eb,
> +                                uint64_t offset, int min_order, int max_order)
> +{
> +       static const uint32_t bbe = MI_BATCH_BUFFER_END;
> +       uint64_t page_size = 1ull << max_order;
> +       int order;
> +
> +       if (max_order > min_order) {
> +               /* explore upper half of the max_order at offset area */
> +               order = __min_page_size_order(fd, obj, eb, offset, min_order,
> +                                             max_order - 1);
> +               if (order < max_order)
> +                       return order;
> +       }
> +
> +       obj->offset = gen8_canonical_addr(offset - page_size);
> +       gem_write(fd, obj->handle, 0, &bbe, sizeof(bbe));
> +       if (!__gem_execbuf(fd, eb)) {
> +               /* upper half not occupied, must be the minimum */
> +               igt_debug("found min page size=%#llx, size order=%d\n",
> +                         (long long)page_size, max_order);
> +               return max_order;
> +       }
> +
> +       if (max_order > min_order) {
> +               /* explore lower half of in case the upper half was occupied */
> +               page_size >>= 1;
> +               order = __min_page_size_order(fd, obj, eb, offset - page_size,
> +                                             min_order, max_order - 1);
> +               if (order < max_order)
> +                       return order;
> +       }
> +
> +       return max_order + 1;
> +}
> +
> +/**
> + * gem_min_page_size_order:
> + * @fd: open i915 drm file descriptor
> + *
> + * This function detects the minimum size of a gem object allocated from
> + * a default backing store.  It is useful for calculating correctly aligned
> + * softpin offsets.
> + * Since size order to size conversion (size = 1 << order) is less trivial
> + * than the opposite, the function returns the size order as more handy.
> + *
> + * Returns:
> + * Size order of the minimum page size
> + */
> +int gem_min_page_size_order(int fd)
> +{
> +       struct drm_i915_gem_exec_object2 obj;
> +       struct drm_i915_gem_execbuffer2 eb;
> +       uint64_t gtt_size = gem_aperture_size(fd);
> +       int min_order = 12;     /* current I915_GTT_PAGE_SIZE equivalent */
> +       uint64_t page_size = 1ull << min_order;
> +       int max_order = 21;     /* current I915_GTT_MAX_PAGE_SIZE equivalent */
> +
> +       /* no softpin => 4kB page size */
> +       if (!gem_has_softpin(fd))
> +               return min_order;
> +
> +       memset(&obj, 0, sizeof(obj));
> +       memset(&eb, 0, sizeof(eb));
> +
> +       obj.handle = gem_create(fd, page_size);
> +       obj.flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
> +       eb.buffers_ptr = to_user_pointer(&obj);
> +       eb.buffer_count = 1;

for (int order = 12; order < 64; order++) {
	obj.offset = 1ull << order;
	if (__gem_execbuf(&eb) == 0)
		break;
}
igt_assert(obj.offset < gem_aperture_size(fd));
gem_close(obj.handle);
return obj.offset;

Our primary metric here is min gtt alignment => gem_gtt_min_alignment();
-Chris


More information about the Intel-gfx-trybot mailing list