Commit 98dc0454 authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915/selftests: Refactor common flush_test()



Pull igt_flush_test() out into its own library before copying and
pasting the code for a third time.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180505091014.26126-1-chris@chris-wilson.co.uk
parent c11c7bfd
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -158,7 +158,8 @@ i915-y += dvo_ch7017.o \
i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
i915-$(CONFIG_DRM_I915_SELFTEST) += \
	selftests/i915_random.o \
	selftests/i915_selftest.o
	selftests/i915_selftest.o \
	selftests/igt_flush_test.o

# virtual gpu code
i915-y += i915_vgpu.o
+64 −0
Original line number Diff line number Diff line
/*
 * SPDX-License-Identifier: MIT
 *
 * Copyright © 2018 Intel Corporation
 */

#include "../i915_drv.h"

#include "../i915_selftest.h"
#include "igt_flush_test.h"

struct wedge_me {
	struct delayed_work work;
	struct drm_i915_private *i915;
	const void *symbol;
};

static void wedge_me(struct work_struct *work)
{
	struct wedge_me *w = container_of(work, typeof(*w), work.work);

	pr_err("%pS timed out, cancelling all further testing.\n", w->symbol);

	GEM_TRACE("%pS timed out.\n", w->symbol);
	GEM_TRACE_DUMP();

	i915_gem_set_wedged(w->i915);
}

static void __init_wedge(struct wedge_me *w,
			 struct drm_i915_private *i915,
			 long timeout,
			 const void *symbol)
{
	w->i915 = i915;
	w->symbol = symbol;

	INIT_DELAYED_WORK_ONSTACK(&w->work, wedge_me);
	schedule_delayed_work(&w->work, timeout);
}

static void __fini_wedge(struct wedge_me *w)
{
	cancel_delayed_work_sync(&w->work);
	destroy_delayed_work_on_stack(&w->work);
	w->i915 = NULL;
}

#define wedge_on_timeout(W, DEV, TIMEOUT)				\
	for (__init_wedge((W), (DEV), (TIMEOUT), __builtin_return_address(0)); \
	     (W)->i915;							\
	     __fini_wedge((W)))

int igt_flush_test(struct drm_i915_private *i915, unsigned int flags)
{
	struct wedge_me w;

	cond_resched();

	wedge_on_timeout(&w, i915, HZ)
		i915_gem_wait_for_idle(i915, flags);

	return i915_terminally_wedged(&i915->gpu_error) ? -EIO : 0;
}
+14 −0
Original line number Diff line number Diff line
/*
 * SPDX-License-Identifier: MIT
 *
 * Copyright © 2018 Intel Corporation
 */

#ifndef IGT_FLUSH_TEST_H
#define IGT_FLUSH_TEST_H

struct drm_i915_private;

int igt_flush_test(struct drm_i915_private *i915, unsigned int flags);

#endif /* IGT_FLUSH_TEST_H */
+6 −60
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@

#include "../i915_selftest.h"
#include "i915_random.h"
#include "igt_flush_test.h"

#include "mock_context.h"
#include "mock_drm.h"
@@ -253,61 +254,6 @@ static u32 hws_seqno(const struct hang *h, const struct i915_request *rq)
	return READ_ONCE(h->seqno[rq->fence.context % (PAGE_SIZE/sizeof(u32))]);
}

struct wedge_me {
	struct delayed_work work;
	struct drm_i915_private *i915;
	const void *symbol;
};

static void wedge_me(struct work_struct *work)
{
	struct wedge_me *w = container_of(work, typeof(*w), work.work);

	pr_err("%pS timed out, cancelling all further testing.\n", w->symbol);

	GEM_TRACE("%pS timed out.\n", w->symbol);
	GEM_TRACE_DUMP();

	i915_gem_set_wedged(w->i915);
}

static void __init_wedge(struct wedge_me *w,
			 struct drm_i915_private *i915,
			 long timeout,
			 const void *symbol)
{
	w->i915 = i915;
	w->symbol = symbol;

	INIT_DELAYED_WORK_ONSTACK(&w->work, wedge_me);
	schedule_delayed_work(&w->work, timeout);
}

static void __fini_wedge(struct wedge_me *w)
{
	cancel_delayed_work_sync(&w->work);
	destroy_delayed_work_on_stack(&w->work);
	w->i915 = NULL;
}

#define wedge_on_timeout(W, DEV, TIMEOUT)				\
	for (__init_wedge((W), (DEV), (TIMEOUT), __builtin_return_address(0)); \
	     (W)->i915;							\
	     __fini_wedge((W)))

static noinline int
flush_test(struct drm_i915_private *i915, unsigned int flags)
{
	struct wedge_me w;

	cond_resched();

	wedge_on_timeout(&w, i915, HZ)
		i915_gem_wait_for_idle(i915, flags);

	return i915_terminally_wedged(&i915->gpu_error) ? -EIO : 0;
}

static void hang_fini(struct hang *h)
{
	*h->batch = MI_BATCH_BUFFER_END;
@@ -321,7 +267,7 @@ static void hang_fini(struct hang *h)

	kernel_context_close(h->ctx);

	flush_test(h->i915, I915_WAIT_LOCKED);
	igt_flush_test(h->i915, I915_WAIT_LOCKED);
}

static bool wait_until_running(struct hang *h, struct i915_request *rq)
@@ -575,7 +521,7 @@ static int __igt_reset_engine(struct drm_i915_private *i915, bool active)
		if (err)
			break;

		err = flush_test(i915, 0);
		err = igt_flush_test(i915, 0);
		if (err)
			break;
	}
@@ -874,7 +820,7 @@ unwind:
		if (err)
			break;

		err = flush_test(i915, 0);
		err = igt_flush_test(i915, 0);
		if (err)
			break;
	}
@@ -1168,7 +1114,7 @@ static int igt_reset_queue(void *arg)

		i915_request_put(prev);

		err = flush_test(i915, I915_WAIT_LOCKED);
		err = igt_flush_test(i915, I915_WAIT_LOCKED);
		if (err)
			break;
	}
@@ -1280,7 +1226,7 @@ int intel_hangcheck_live_selftests(struct drm_i915_private *i915)
	err = i915_subtests(tests, i915);

	mutex_lock(&i915->drm.struct_mutex);
	flush_test(i915, I915_WAIT_LOCKED);
	igt_flush_test(i915, I915_WAIT_LOCKED);
	mutex_unlock(&i915->drm.struct_mutex);

	i915_modparams.enable_hangcheck = saved_hangcheck;
+7 −61
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
 */

#include "../i915_selftest.h"
#include "igt_flush_test.h"

#include "mock_context.h"

@@ -168,61 +169,6 @@ static u32 hws_seqno(const struct spinner *spin, const struct i915_request *rq)
	return READ_ONCE(*seqno);
}

struct wedge_me {
	struct delayed_work work;
	struct drm_i915_private *i915;
	const void *symbol;
};

static void wedge_me(struct work_struct *work)
{
	struct wedge_me *w = container_of(work, typeof(*w), work.work);

	pr_err("%pS timed out, cancelling all further testing.\n", w->symbol);

	GEM_TRACE("%pS timed out.\n", w->symbol);
	GEM_TRACE_DUMP();

	i915_gem_set_wedged(w->i915);
}

static void __init_wedge(struct wedge_me *w,
			 struct drm_i915_private *i915,
			 long timeout,
			 const void *symbol)
{
	w->i915 = i915;
	w->symbol = symbol;

	INIT_DELAYED_WORK_ONSTACK(&w->work, wedge_me);
	schedule_delayed_work(&w->work, timeout);
}

static void __fini_wedge(struct wedge_me *w)
{
	cancel_delayed_work_sync(&w->work);
	destroy_delayed_work_on_stack(&w->work);
	w->i915 = NULL;
}

#define wedge_on_timeout(W, DEV, TIMEOUT)				\
	for (__init_wedge((W), (DEV), (TIMEOUT), __builtin_return_address(0)); \
	     (W)->i915;							\
	     __fini_wedge((W)))

static noinline int
flush_test(struct drm_i915_private *i915, unsigned int flags)
{
	struct wedge_me w;

	cond_resched();

	wedge_on_timeout(&w, i915, HZ)
		i915_gem_wait_for_idle(i915, flags);

	return i915_terminally_wedged(&i915->gpu_error) ? -EIO : 0;
}

static void spinner_end(struct spinner *spin)
{
	*spin->batch = MI_BATCH_BUFFER_END;
@@ -295,7 +241,7 @@ static int live_sanitycheck(void *arg)
		}

		spinner_end(&spin);
		if (flush_test(i915, I915_WAIT_LOCKED)) {
		if (igt_flush_test(i915, I915_WAIT_LOCKED)) {
			err = -EIO;
			goto err_ctx;
		}
@@ -307,7 +253,7 @@ err_ctx:
err_spin:
	spinner_fini(&spin);
err_unlock:
	flush_test(i915, I915_WAIT_LOCKED);
	igt_flush_test(i915, I915_WAIT_LOCKED);
	mutex_unlock(&i915->drm.struct_mutex);
	return err;
}
@@ -380,7 +326,7 @@ static int live_preempt(void *arg)

		spinner_end(&spin_hi);
		spinner_end(&spin_lo);
		if (flush_test(i915, I915_WAIT_LOCKED)) {
		if (igt_flush_test(i915, I915_WAIT_LOCKED)) {
			err = -EIO;
			goto err_ctx_lo;
		}
@@ -396,7 +342,7 @@ err_spin_lo:
err_spin_hi:
	spinner_fini(&spin_hi);
err_unlock:
	flush_test(i915, I915_WAIT_LOCKED);
	igt_flush_test(i915, I915_WAIT_LOCKED);
	mutex_unlock(&i915->drm.struct_mutex);
	return err;
}
@@ -470,7 +416,7 @@ static int live_late_preempt(void *arg)

		spinner_end(&spin_hi);
		spinner_end(&spin_lo);
		if (flush_test(i915, I915_WAIT_LOCKED)) {
		if (igt_flush_test(i915, I915_WAIT_LOCKED)) {
			err = -EIO;
			goto err_ctx_lo;
		}
@@ -486,7 +432,7 @@ err_spin_lo:
err_spin_hi:
	spinner_fini(&spin_hi);
err_unlock:
	flush_test(i915, I915_WAIT_LOCKED);
	igt_flush_test(i915, I915_WAIT_LOCKED);
	mutex_unlock(&i915->drm.struct_mutex);
	return err;