Re: [PATCH v4] drm/i915/selftests: Add a simple exerciser for suspend/hibernate

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Looks good to me, thanks for the test case (btw maybe it's worth
mentioning in the commit message that the test fails without doing
gt.resume?)

Reviewed-by: Jakub Bartmiński <jakub.bartminski@xxxxxxxxx>

On Thu, 2018-08-30 at 14:48 +0100, Chris Wilson wrote:
> Although we cannot do a full system-level test of suspend/hibernate
> from
> deep with the kernel selftests, we can exercise the GEM subsystem in
> isolation and simulate the external effects (such as losing stolen
> contents and trashing the register state).
> 
> v2: Don't forget to hold rpm
> v3: Suspend the GTT mappings, and more rpm!
> 
> Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
> Cc: Jakub Bartmiński <jakub.bartminski@xxxxxxxxx>
> Cc: Matthew Auld <matthew.william.auld@xxxxxxxxx>
> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx>
> ---
>  drivers/gpu/drm/i915/i915_gem.c               |   1 +
>  drivers/gpu/drm/i915/selftests/i915_gem.c     | 221
> ++++++++++++++++++
>  .../drm/i915/selftests/i915_live_selftests.h  |   1 +
>  3 files changed, 223 insertions(+)
>  create mode 100644 drivers/gpu/drm/i915/selftests/i915_gem.c
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem.c
> b/drivers/gpu/drm/i915/i915_gem.c
> index 0453eb42a1a3..7b7bbfe59697 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -6207,4 +6207,5 @@ int i915_gem_object_attach_phys(struct
> drm_i915_gem_object *obj, int align)
>  #include "selftests/huge_pages.c"
>  #include "selftests/i915_gem_object.c"
>  #include "selftests/i915_gem_coherency.c"
> +#include "selftests/i915_gem.c"
>  #endif
> diff --git a/drivers/gpu/drm/i915/selftests/i915_gem.c
> b/drivers/gpu/drm/i915/selftests/i915_gem.c
> new file mode 100644
> index 000000000000..e9cfc1fb0c07
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/selftests/i915_gem.c
> @@ -0,0 +1,221 @@
> +/*
> + * SPDX-License-Identifier: MIT
> + *
> + * Copyright © 2018 Intel Corporation
> + */
> +
> +#include <linux/random.h>
> +
> +#include "../i915_selftest.h"
> +
> +#include "mock_context.h"
> +#include "igt_flush_test.h"
> +
> +static int switch_to_context(struct drm_i915_private *i915,
> +			     struct i915_gem_context *ctx)
> +{
> +	struct intel_engine_cs *engine;
> +	enum intel_engine_id id;
> +	int err = 0;
> +
> +	intel_runtime_pm_get(i915);
> +
> +	for_each_engine(engine, i915, id) {
> +		struct i915_request *rq;
> +
> +		rq = i915_request_alloc(engine, ctx);
> +		if (IS_ERR(rq)) {
> +			err = PTR_ERR(rq);
> +			break;
> +		}
> +
> +		i915_request_add(rq);
> +	}
> +
> +	intel_runtime_pm_put(i915);
> +
> +	return err;
> +}
> +
> +static int pm_prepare(struct drm_i915_private *i915)
> +{
> +	int err = 0;
> +
> +	if (i915_gem_suspend(i915)) {
> +		pr_err("i915_gem_suspend failed\n");
> +		err = -EINVAL;
> +	}
> +
> +	return err;
> +}
> +
> +static void trash_stolen(struct drm_i915_private *i915)
> +{
> +	struct i915_ggtt *ggtt = &i915->ggtt;
> +	const u64 slot = ggtt->error_capture.start;
> +	const resource_size_t size = resource_size(&i915->dsm);
> +	unsigned long page;
> +	u32 prng = 0x12345678;
> +
> +	for (page = 0; page < size; page += PAGE_SIZE) {
> +		const dma_addr_t dma = i915->dsm.start + page;
> +		u32 __iomem *s;
> +		int x;
> +
> +		ggtt->vm.insert_page(&ggtt->vm, dma, slot,
> I915_CACHE_NONE, 0);
> +
> +		s = io_mapping_map_atomic_wc(&ggtt->iomap, slot);
> +		for (x = 0; x < PAGE_SIZE / sizeof(u32); x++) {
> +			prng = next_pseudo_random32(prng);
> +			iowrite32(prng, &s[x]);
> +		}
> +		io_mapping_unmap_atomic(s);
> +	}
> +
> +	ggtt->vm.clear_range(&ggtt->vm, slot, PAGE_SIZE);
> +}
> +
> +static void simulate_hibernate(struct drm_i915_private *i915)
> +{
> +	intel_runtime_pm_get(i915);
> +
> +	/*
> +	 * As a final sting in the tail, invalidate stolen. Under a
> real S4,
> +	 * stolen is lost and needs to be refilled on resume.
> However, under
> +	 * CI we merely do S4-device testing (as full S4 is too
> unreliable
> +	 * for automated testing across a cluster), so to simulate
> the effect
> +	 * of stolen being trashed across S4, we trash it ourselves.
> +	 */
> +	trash_stolen(i915);
> +
> +	intel_runtime_pm_put(i915);
> +}
> +
> +static void pm_resume(struct drm_i915_private *i915)
> +{
> +	/*
> +	 * Both suspend and hibernate follow the same wakeup path
> and assume
> +	 * that runtime-pm just works.
> +	 */
> +	intel_runtime_pm_get(i915);
> +
> +	intel_engines_sanitize(i915);
> +	i915_gem_sanitize(i915);
> +	i915_gem_resume(i915);
> +
> +	intel_runtime_pm_put(i915);
> +}
> +
> +static void pm_suspend(struct drm_i915_private *i915)
> +{
> +	intel_runtime_pm_get(i915);
> +
> +	i915_gem_suspend_gtt_mappings(i915);
> +	i915_gem_suspend_late(i915);
> +
> +	intel_runtime_pm_put(i915);
> +}
> +
> +static int igt_gem_suspend(void *arg)
> +{
> +	struct drm_i915_private *i915 = arg;
> +	struct i915_gem_context *ctx;
> +	struct drm_file *file;
> +	int err;
> +
> +	file = mock_file(i915);
> +	if (IS_ERR(file))
> +		return PTR_ERR(file);
> +
> +	err = -ENOMEM;
> +	mutex_lock(&i915->drm.struct_mutex);
> +	ctx = live_context(i915, file);
> +	if (!IS_ERR(ctx))
> +		err = switch_to_context(i915, ctx);
> +	mutex_unlock(&i915->drm.struct_mutex);
> +	if (err)
> +		goto out;
> +
> +	err = pm_prepare(i915);
> +	if (err)
> +		goto out;
> +
> +	pm_suspend(i915);
> +
> +	/* Here be dragons! Note that with S3RST any S3 may become
> S4! */
> +	simulate_hibernate(i915);
> +
> +	pm_resume(i915);
> +
> +	mutex_lock(&i915->drm.struct_mutex);
> +	err = switch_to_context(i915, ctx);
> +	if (igt_flush_test(i915, I915_WAIT_LOCKED))
> +		err = -EIO;
> +	mutex_unlock(&i915->drm.struct_mutex);
> +out:
> +	mock_file_free(i915, file);
> +	return err;
> +}
> +
> +static void pm_hibernate(struct drm_i915_private *i915)
> +{
> +	intel_runtime_pm_get(i915);
> +
> +	i915_gem_suspend_gtt_mappings(i915);
> +
> +	i915_gem_freeze(i915);
> +	i915_gem_freeze_late(i915);
> +
> +	intel_runtime_pm_put(i915);
> +}
> +
> +static int igt_gem_hibernate(void *arg)
> +{
> +	struct drm_i915_private *i915 = arg;
> +	struct i915_gem_context *ctx;
> +	struct drm_file *file;
> +	int err;
> +
> +	file = mock_file(i915);
> +	if (IS_ERR(file))
> +		return PTR_ERR(file);
> +
> +	err = -ENOMEM;
> +	mutex_lock(&i915->drm.struct_mutex);
> +	ctx = live_context(i915, file);
> +	if (!IS_ERR(ctx))
> +		err = switch_to_context(i915, ctx);
> +	mutex_unlock(&i915->drm.struct_mutex);
> +	if (err)
> +		goto out;
> +
> +	err = pm_prepare(i915);
> +	if (err)
> +		goto out;
> +
> +	pm_hibernate(i915);
> +
> +	/* Here be dragons! */
> +	simulate_hibernate(i915);
> +
> +	pm_resume(i915);
> +
> +	mutex_lock(&i915->drm.struct_mutex);
> +	err = switch_to_context(i915, ctx);
> +	if (igt_flush_test(i915, I915_WAIT_LOCKED))
> +		err = -EIO;
> +	mutex_unlock(&i915->drm.struct_mutex);
> +out:
> +	mock_file_free(i915, file);
> +	return err;
> +}
> +
> +int i915_gem_live_selftests(struct drm_i915_private *i915)
> +{
> +	static const struct i915_subtest tests[] = {
> +		SUBTEST(igt_gem_suspend),
> +		SUBTEST(igt_gem_hibernate),
> +	};
> +
> +	return i915_subtests(tests, i915);
> +}
> diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
> b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
> index a00e2bd08bce..a15713cae3b3 100644
> --- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
> +++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h
> @@ -17,6 +17,7 @@ selftest(objects, i915_gem_object_live_selftests)
>  selftest(dmabuf, i915_gem_dmabuf_live_selftests)
>  selftest(coherency, i915_gem_coherency_live_selftests)
>  selftest(gtt, i915_gem_gtt_live_selftests)
> +selftest(gem, i915_gem_live_selftests)
>  selftest(evict, i915_gem_evict_live_selftests)
>  selftest(hugepages, i915_gem_huge_page_live_selftests)
>  selftest(contexts, i915_gem_context_live_selftests)

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux