[PATCH] pathological
Matthew Auld
matthew.auld at intel.com
Tue Oct 29 22:36:50 UTC 2019
Signed-off-by: Matthew Auld <matthew.auld at intel.com>
---
.../gpu/drm/i915/gem/selftests/huge_pages.c | 157 ++++++++++++++++++
drivers/gpu/drm/i915/i915_pci.c | 3 +-
2 files changed, 159 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index 688c49a24f32..53a2bb8bb8f7 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -4,10 +4,12 @@
* Copyright © 2017 Intel Corporation
*/
+#include <linux/sort.h>
#include <linux/prime_numbers.h>
#include "i915_selftest.h"
+#include "gem/i915_gem_object_blt.h"
#include "gem/i915_gem_region.h"
#include "gem/i915_gem_lmem.h"
#include "gem/i915_gem_pm.h"
@@ -1550,6 +1552,160 @@ static int igt_ppgtt_sanity_check(void *arg)
return err;
}
+static int wrap_ktime_compare(const void *A, const void *B)
+{
+ const ktime_t *a = A, *b = B;
+
+ return ktime_compare(*a, *b);
+}
+
+static int perf_pathological_alignment(void *arg)
+{
+ struct i915_gem_context *ctx = arg;
+ struct drm_i915_private *i915 = ctx->i915;
+ struct drm_i915_gem_object *normal;
+ struct drm_i915_gem_object *obj;
+ const unsigned int n_pages = 32;
+ struct intel_context *ce;
+ struct scatterlist *sg;
+ struct sg_table *old_st;
+ struct sg_table *st;
+ unsigned long i;
+ ktime_t t[5];
+ int err;
+
+ if (!HAS_PAGE_SIZES(i915, SZ_2M))
+ return 0;
+
+ normal = huge_pages_object(i915, n_pages * SZ_2M, SZ_4K);
+ if (IS_ERR(normal))
+ return PTR_ERR(normal);
+
+ err = i915_gem_object_pin_pages(normal);
+ if (err)
+ goto out_put;
+
+ normal->mm.page_sizes.sg = SZ_4K;
+
+ obj = huge_pages_object(i915, n_pages * SZ_2M, SZ_2M);
+ if (IS_ERR(obj))
+ return PTR_ERR(obj);
+
+ err = i915_gem_object_pin_pages(obj);
+ if (err)
+ goto out_put;
+
+ GEM_BUG_ON(obj->mm.page_sizes.sg < SZ_2M);
+ obj->mm.page_sizes.sg = SZ_4K;
+
+ st = kmalloc(sizeof(*st), GFP_KERNEL);
+ if (!st) {
+ err = -ENOMEM;
+ goto out_unpin;
+ }
+
+ if (sg_alloc_table(st, obj->base.size >> PAGE_SHIFT, GFP_KERNEL)) {
+ err = -ENOMEM;
+ goto out_free;
+ }
+
+ sg = st->sgl;
+ st->nents = 0;
+
+ for (i = 0; i < obj->base.size >> PAGE_SHIFT; ++i) {
+ unsigned long idx = (SZ_2M * (i % n_pages)) >> PAGE_SHIFT;
+ dma_addr_t daddr = i915_gem_object_get_dma_address(obj, idx);
+
+ if (!IS_ALIGNED(daddr, SZ_2M)) {
+ pr_info("%s dma-mapper screwed us over, skipping\n",
+ __func__);
+ goto out_reset;
+ }
+
+ sg_dma_address(sg) = daddr;
+ sg_dma_len(sg) = PAGE_SIZE;
+
+ sg->length = PAGE_SIZE;
+
+ st->nents++;
+
+ sg = __sg_next(sg);
+ }
+
+ old_st = obj->mm.pages;
+ obj->mm.pages = st;
+
+ ce = i915->engine[BCS0]->kernel_context;
+
+ for (i = 0; i < ARRAY_SIZE(t); ++i) {
+ ktime_t t0, t1;
+
+ t0 = ktime_get();
+
+ err = i915_gem_object_fill_blt(obj, ce, 0);
+ if (err)
+ goto out_reset;
+
+ err = i915_gem_object_wait(obj,
+ I915_WAIT_ALL,
+ MAX_SCHEDULE_TIMEOUT);
+ if (err)
+ goto out_reset;
+
+ t1 = ktime_get();
+ t[i] = ktime_sub(t1, t0);
+ }
+
+ /* XXX: forgive me for i have sinned */
+ i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE);
+
+ sort(t, ARRAY_SIZE(t), sizeof(*t), wrap_ktime_compare, NULL);
+ pr_info("SLOW %zd KiB fill: %lld MiB/s\n",
+ obj->base.size >> 10,
+ div64_u64(mul_u32_u32(4 * obj->base.size,
+ 1000 * 1000 * 1000),
+ t[1] + 2 * t[2] + t[3]) >> 20);
+
+ for (i = 0; i < ARRAY_SIZE(t); ++i) {
+ ktime_t t0, t1;
+
+ t0 = ktime_get();
+
+ err = i915_gem_object_fill_blt(normal, ce, 0);
+ if (err)
+ goto out_reset;
+
+ err = i915_gem_object_wait(normal,
+ I915_WAIT_ALL,
+ MAX_SCHEDULE_TIMEOUT);
+ if (err)
+ goto out_reset;
+
+ t1 = ktime_get();
+ t[i] = ktime_sub(t1, t0);
+ }
+
+ sort(t, ARRAY_SIZE(t), sizeof(*t), wrap_ktime_compare, NULL);
+ pr_info("FAST %zd KiB fill: %lld MiB/s\n",
+ normal->base.size >> 10,
+ div64_u64(mul_u32_u32(4 * normal->base.size,
+ 1000 * 1000 * 1000),
+ t[1] + 2 * t[2] + t[3]) >> 20);
+
+out_reset:
+ obj->mm.pages = old_st;
+ sg_free_table(st);
+out_free:
+ kfree(st);
+out_unpin:
+ i915_gem_object_unpin_pages(normal);
+ i915_gem_object_unpin_pages(obj);
+out_put:
+ i915_gem_object_put(normal);
+ i915_gem_object_put(obj);
+ return err;
+}
+
static int igt_ppgtt_pin_update(void *arg)
{
struct i915_gem_context *ctx = arg;
@@ -1911,6 +2067,7 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *i915)
SUBTEST(igt_ppgtt_exhaust_huge),
SUBTEST(igt_ppgtt_smoke_huge),
SUBTEST(igt_ppgtt_sanity_check),
+ SUBTEST(perf_pathological_alignment),
};
struct drm_file *file;
struct i915_gem_context *ctx;
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 1bb701d32a5d..87e9e3887da3 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -603,7 +603,8 @@ static const struct intel_device_info intel_cherryview_info = {
#define GEN9_DEFAULT_PAGE_SIZES \
.page_sizes = I915_GTT_PAGE_SIZE_4K | \
- I915_GTT_PAGE_SIZE_64K
+ I915_GTT_PAGE_SIZE_64K | \
+ I915_GTT_PAGE_SIZE_2M
#define GEN9_FEATURES \
GEN8_FEATURES, \
--
2.20.1
More information about the Intel-gfx-trybot
mailing list