mirror of
https://github.com/tiagovignatti/intel-gpu-tools.git
synced 2025-06-10 01:16:18 +00:00
lib/igt_gt: Document and consolidate
Also move forcewake and stop_rings code from igt_debugfs to igt_gt since it fits better. And move the hang injection fork helpers from igt_aux to igt_gt, too. Also push the intel_gen call into igt_hang_ring while at it. Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
This commit is contained in:
parent
25c4347078
commit
3cd45dec2e
@ -21,6 +21,7 @@
|
|||||||
<xi:include href="xml/igt_kms.xml"/>
|
<xi:include href="xml/igt_kms.xml"/>
|
||||||
<xi:include href="xml/igt_fb.xml"/>
|
<xi:include href="xml/igt_fb.xml"/>
|
||||||
<xi:include href="xml/igt_aux.xml"/>
|
<xi:include href="xml/igt_aux.xml"/>
|
||||||
|
<xi:include href="xml/igt_gt.xml"/>
|
||||||
<xi:include href="xml/ioctl_wrappers.xml"/>
|
<xi:include href="xml/ioctl_wrappers.xml"/>
|
||||||
<xi:include href="xml/intel_batchbuffer.xml"/>
|
<xi:include href="xml/intel_batchbuffer.xml"/>
|
||||||
<xi:include href="xml/intel_chipset.xml"/>
|
<xi:include href="xml/intel_chipset.xml"/>
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include "i915_drm.h"
|
#include "i915_drm.h"
|
||||||
#include "intel_chipset.h"
|
#include "intel_chipset.h"
|
||||||
#include "intel_io.h"
|
#include "intel_io.h"
|
||||||
|
#include "igt_gt.h"
|
||||||
#include "igt_debugfs.h"
|
#include "igt_debugfs.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -132,74 +132,6 @@ void igt_stop_signal_helper(void)
|
|||||||
sig_stat = 0;
|
sig_stat = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GPU abusers */
|
|
||||||
static struct igt_helper_process hang_helper;
|
|
||||||
static void __attribute__((noreturn))
|
|
||||||
hang_helper_process(pid_t pid, int fd, int gen)
|
|
||||||
{
|
|
||||||
while (1) {
|
|
||||||
if (kill(pid, 0)) /* Parent has died, so must we. */
|
|
||||||
exit(0);
|
|
||||||
|
|
||||||
igt_post_hang_ring(fd,
|
|
||||||
igt_hang_ring(fd, gen, I915_EXEC_DEFAULT));
|
|
||||||
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* igt_fork_hang_helper:
|
|
||||||
*
|
|
||||||
* Fork a child process using #igt_fork_helper to hang the default engine
|
|
||||||
* of the GPU at regular intervals.
|
|
||||||
*
|
|
||||||
* This is useful to exercise slow running code (such as aperture placement)
|
|
||||||
* which needs to be robust against a GPU reset.
|
|
||||||
*
|
|
||||||
* In tests with subtests this function can be called outside of failure
|
|
||||||
* catching code blocks like #igt_fixture or #igt_subtest.
|
|
||||||
*/
|
|
||||||
int igt_fork_hang_helper(void)
|
|
||||||
{
|
|
||||||
int fd, gen;
|
|
||||||
|
|
||||||
if (igt_only_list_subtests())
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
fd = drm_open_any();
|
|
||||||
if (fd == -1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
gen = intel_gen(intel_get_drm_devid(fd));
|
|
||||||
if (gen < 5) {
|
|
||||||
close(fd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
igt_fork_helper(&hang_helper)
|
|
||||||
hang_helper_process(getppid(), fd, gen);
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* igt_stop_hang_helper:
|
|
||||||
*
|
|
||||||
* Stops the child process spawned with igt_fork_hang_helper().
|
|
||||||
*
|
|
||||||
* In tests with subtests this function can be called outside of failure
|
|
||||||
* catching code blocks like #igt_fixture or #igt_subtest.
|
|
||||||
*/
|
|
||||||
void igt_stop_hang_helper(void)
|
|
||||||
{
|
|
||||||
if (igt_only_list_subtests())
|
|
||||||
return;
|
|
||||||
|
|
||||||
igt_stop_helper(&hang_helper);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* igt_check_boolean_env_var:
|
* igt_check_boolean_env_var:
|
||||||
* @env_var: environment variable name
|
* @env_var: environment variable name
|
||||||
|
@ -39,9 +39,6 @@ extern int num_trash_bos;
|
|||||||
void igt_fork_signal_helper(void);
|
void igt_fork_signal_helper(void);
|
||||||
void igt_stop_signal_helper(void);
|
void igt_stop_signal_helper(void);
|
||||||
|
|
||||||
int igt_fork_hang_helper(void);
|
|
||||||
void igt_stop_hang_helper(void);
|
|
||||||
|
|
||||||
void igt_exchange_int(void *array, unsigned i, unsigned j);
|
void igt_exchange_int(void *array, unsigned i, unsigned j);
|
||||||
void igt_permute_array(void *array, unsigned size,
|
void igt_permute_array(void *array, unsigned size,
|
||||||
void (*exchange_func)(void *array,
|
void (*exchange_func)(void *array,
|
||||||
|
@ -613,125 +613,3 @@ void igt_enable_prefault(void)
|
|||||||
{
|
{
|
||||||
igt_prefault_control(true);
|
igt_prefault_control(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* igt_open_forcewake_handle:
|
|
||||||
*
|
|
||||||
* This functions opens the debugfs forcewake file and so prevents the GT from
|
|
||||||
* suspending. The reference is automatically dropped when the is closed.
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* The file descriptor of the forcewake handle or -1 if that didn't work out.
|
|
||||||
*/
|
|
||||||
int igt_open_forcewake_handle(void)
|
|
||||||
{
|
|
||||||
if (getenv("IGT_NO_FORCEWAKE"))
|
|
||||||
return -1;
|
|
||||||
return igt_debugfs_open("i915_forcewake_user", O_WRONLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* igt_to_stop_ring_flag:
|
|
||||||
* @ring: the specified ring flag from execbuf ioctl (I915_EXEC_*)
|
|
||||||
*
|
|
||||||
* This converts the specified ring to a ring flag to be used
|
|
||||||
* with igt_get_stop_rings() and igt_set_stop_rings().
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* Ring flag for the given ring.
|
|
||||||
*/
|
|
||||||
enum stop_ring_flags igt_to_stop_ring_flag(int ring) {
|
|
||||||
if (ring == I915_EXEC_DEFAULT)
|
|
||||||
return STOP_RING_RENDER;
|
|
||||||
|
|
||||||
igt_assert(ring && ((ring & ~I915_EXEC_RING_MASK) == 0));
|
|
||||||
return 1 << (ring - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void stop_rings_write(uint32_t mask)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
char buf[80];
|
|
||||||
|
|
||||||
igt_assert(snprintf(buf, sizeof(buf), "0x%08x", mask) == 10);
|
|
||||||
fd = igt_debugfs_open("i915_ring_stop", O_WRONLY);
|
|
||||||
igt_assert(fd >= 0);
|
|
||||||
|
|
||||||
igt_assert(write(fd, buf, strlen(buf)) == strlen(buf));
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* igt_get_stop_rings:
|
|
||||||
*
|
|
||||||
* Read current ring flags from 'i915_ring_stop' debugfs entry.
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* Current ring flags.
|
|
||||||
*/
|
|
||||||
enum stop_ring_flags igt_get_stop_rings(void)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
char buf[80];
|
|
||||||
int l;
|
|
||||||
unsigned long long ring_mask;
|
|
||||||
|
|
||||||
fd = igt_debugfs_open("i915_ring_stop", O_RDONLY);
|
|
||||||
igt_assert(fd >= 0);
|
|
||||||
l = read(fd, buf, sizeof(buf)-1);
|
|
||||||
igt_assert(l > 0);
|
|
||||||
igt_assert(l < sizeof(buf));
|
|
||||||
|
|
||||||
buf[l] = '\0';
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
ring_mask = strtoull(buf, NULL, 0);
|
|
||||||
igt_assert(errno == 0);
|
|
||||||
return ring_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* igt_set_stop_rings:
|
|
||||||
* @flags: Ring flags to write
|
|
||||||
*
|
|
||||||
* This writes @flags to 'i915_ring_stop' debugfs entry. Driver will
|
|
||||||
* prevent the CPU from writing tail pointer for the ring that @flags
|
|
||||||
* specify. Note that the ring is not stopped right away. Instead any
|
|
||||||
* further command emissions won't be executed after the flag is set.
|
|
||||||
*
|
|
||||||
* This is the least invasive way to make the GPU stuck. Hence you must
|
|
||||||
* set this after a batch submission with it's own invalid or endless
|
|
||||||
* looping instructions. In this case it is merely for giving notification
|
|
||||||
* for the driver that this was simulated hang, as the batch would have
|
|
||||||
* caused hang in any case. On the other hand if you use a valid or noop
|
|
||||||
* batch and want to hang the ring (GPU), you must set corresponding flag
|
|
||||||
* before submitting the batch.
|
|
||||||
*
|
|
||||||
* Driver checks periodically if a ring is making any progress, and if
|
|
||||||
* it is not, it will declare the ring to be hung and will reset the GPU.
|
|
||||||
* After reset, the driver will clear flags in 'i915_ring_stop'
|
|
||||||
*
|
|
||||||
* Note: Always when hanging the GPU, use igt_set_stop_rings() to
|
|
||||||
* notify the driver. Driver controls hang log messaging based on
|
|
||||||
* these flags and thus prevents false positives on logs.
|
|
||||||
*/
|
|
||||||
void igt_set_stop_rings(enum stop_ring_flags flags)
|
|
||||||
{
|
|
||||||
enum stop_ring_flags current;
|
|
||||||
|
|
||||||
igt_assert((flags & ~(STOP_RING_ALL |
|
|
||||||
STOP_RING_ALLOW_BAN |
|
|
||||||
STOP_RING_ALLOW_ERRORS)) == 0);
|
|
||||||
|
|
||||||
current = igt_get_stop_rings();
|
|
||||||
igt_assert_f(flags == 0 || current == 0,
|
|
||||||
"previous i915_ring_stop is still 0x%x\n", current);
|
|
||||||
|
|
||||||
stop_rings_write(flags);
|
|
||||||
current = igt_get_stop_rings();
|
|
||||||
igt_warn_on_f(current != flags,
|
|
||||||
"i915_ring_stop readback mismatch 0x%x vs 0x%x\n",
|
|
||||||
flags, current);
|
|
||||||
}
|
|
||||||
|
@ -142,39 +142,4 @@ void igt_drop_caches_set(uint64_t val);
|
|||||||
void igt_disable_prefault(void);
|
void igt_disable_prefault(void);
|
||||||
void igt_enable_prefault(void);
|
void igt_enable_prefault(void);
|
||||||
|
|
||||||
int igt_open_forcewake_handle(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* stop_ring_flags:
|
|
||||||
* @STOP_RING_NONE: Can be used to clear the pending stop (warning: hang might
|
|
||||||
* be declared already). Returned by igt_get_stop_rings() if there is
|
|
||||||
* no currently stopped rings.
|
|
||||||
* @STOP_RING_RENDER: Render ring
|
|
||||||
* @STOP_RING_BSD: Video encoding/decoding ring
|
|
||||||
* @STOP_RING_BLT: Blitter ring
|
|
||||||
* @STOP_RING_VEBOX: Video enhancement ring
|
|
||||||
* @STOP_RING_ALL: All rings
|
|
||||||
* @STOP_RING_ALLOW_ERRORS: Driver will not omit expected DRM_ERRORS
|
|
||||||
* @STOP_RING_ALLOW_BAN: Driver will use context ban policy
|
|
||||||
* @STOP_RING_DEFAULTS: STOP_RING_ALL | STOP_RING_ALLOW_ERRORS
|
|
||||||
*
|
|
||||||
* Enumeration of all supported flags for igt_set_stop_rings().
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
enum stop_ring_flags {
|
|
||||||
STOP_RING_NONE = 0x00,
|
|
||||||
STOP_RING_RENDER = (1 << 0),
|
|
||||||
STOP_RING_BSD = (1 << 1),
|
|
||||||
STOP_RING_BLT = (1 << 2),
|
|
||||||
STOP_RING_VEBOX = (1 << 3),
|
|
||||||
STOP_RING_ALL = 0xff,
|
|
||||||
STOP_RING_ALLOW_ERRORS = (1 << 30),
|
|
||||||
STOP_RING_ALLOW_BAN = (1 << 31),
|
|
||||||
STOP_RING_DEFAULTS = STOP_RING_ALL | STOP_RING_ALLOW_ERRORS,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum stop_ring_flags igt_to_stop_ring_flag(int ring);
|
|
||||||
void igt_set_stop_rings(enum stop_ring_flags flags);
|
|
||||||
enum stop_ring_flags igt_get_stop_rings(void);
|
|
||||||
|
|
||||||
#endif /* __IGT_DEBUGFS_H__ */
|
#endif /* __IGT_DEBUGFS_H__ */
|
||||||
|
240
lib/igt_gt.c
240
lib/igt_gt.c
@ -22,8 +22,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "drmtest.h"
|
||||||
#include "igt_core.h"
|
#include "igt_core.h"
|
||||||
#include "igt_gt.h"
|
#include "igt_gt.h"
|
||||||
#include "igt_debugfs.h"
|
#include "igt_debugfs.h"
|
||||||
@ -31,13 +36,46 @@
|
|||||||
#include "intel_reg.h"
|
#include "intel_reg.h"
|
||||||
#include "intel_chipset.h"
|
#include "intel_chipset.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:igt_gt
|
||||||
|
* @short_description: GT support library
|
||||||
|
* @title: i-g-t gt
|
||||||
|
* @include: igt_gt.h
|
||||||
|
*
|
||||||
|
* This library provides various auxiliary helper functions to handle general
|
||||||
|
* interactions with the GT like forcewake handling, injecting hangs or stopping
|
||||||
|
* engines.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* igt_require_hang_ring:
|
||||||
|
* @fd: open i915 drm file descriptor
|
||||||
|
* @ring: execbuf ring flag
|
||||||
|
*
|
||||||
|
* Convenience helper to check whether advanced hang injection is supported by
|
||||||
|
* the kernel. Uses igt_skip to automatically skip the test/subtest if this
|
||||||
|
* isn't the case.
|
||||||
|
*/
|
||||||
void igt_require_hang_ring(int fd, int ring)
|
void igt_require_hang_ring(int fd, int ring)
|
||||||
{
|
{
|
||||||
gem_context_require_param(fd, LOCAL_CONTEXT_PARAM_BAN_PERIOD);
|
gem_context_require_param(fd, LOCAL_CONTEXT_PARAM_BAN_PERIOD);
|
||||||
igt_require(intel_gen(intel_get_drm_devid(fd)) >= 5);
|
igt_require(intel_gen(intel_get_drm_devid(fd)) >= 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct igt_hang_ring igt_hang_ring(int fd, int gen, int ring)
|
/**
|
||||||
|
* igt_hang_ring:
|
||||||
|
* @fd: open i915 drm file descriptor
|
||||||
|
* @ring: execbuf ring flag
|
||||||
|
*
|
||||||
|
* This helper function injects a hanging batch into @ring. It returns a
|
||||||
|
* #igt_hang_ring_t structure which must be passed to igt_post_hang_ring() for
|
||||||
|
* hang post-processing (after the gpu hang interaction has been tested.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Structure with helper internal state for igt_post_hang_ring().
|
||||||
|
*/
|
||||||
|
igt_hang_ring_t igt_hang_ring(int fd, int ring)
|
||||||
{
|
{
|
||||||
struct drm_i915_gem_relocation_entry reloc;
|
struct drm_i915_gem_relocation_entry reloc;
|
||||||
struct drm_i915_gem_execbuffer2 execbuf;
|
struct drm_i915_gem_execbuffer2 execbuf;
|
||||||
@ -66,7 +104,7 @@ struct igt_hang_ring igt_hang_ring(int fd, int gen, int ring)
|
|||||||
exec.relocs_ptr = (uintptr_t)&reloc;
|
exec.relocs_ptr = (uintptr_t)&reloc;
|
||||||
|
|
||||||
len = 2;
|
len = 2;
|
||||||
if (gen >= 8)
|
if (intel_gen(intel_get_drm_devid(fd)) >= 8)
|
||||||
len++;
|
len++;
|
||||||
b[0] = MI_BATCH_BUFFER_START | (len - 2);
|
b[0] = MI_BATCH_BUFFER_START | (len - 2);
|
||||||
b[len] = MI_BATCH_BUFFER_END;
|
b[len] = MI_BATCH_BUFFER_END;
|
||||||
@ -86,6 +124,14 @@ struct igt_hang_ring igt_hang_ring(int fd, int gen, int ring)
|
|||||||
return (struct igt_hang_ring){ exec.handle, ban };
|
return (struct igt_hang_ring){ exec.handle, ban };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* igt_hang_ring:
|
||||||
|
* @fd: open i915 drm file descriptor
|
||||||
|
* @arg: hang state from igt_hang_ring()
|
||||||
|
*
|
||||||
|
* This function does the necessary post-processing after a gpu hang injected
|
||||||
|
* with igt_hang_ring().
|
||||||
|
*/
|
||||||
void igt_post_hang_ring(int fd, struct igt_hang_ring arg)
|
void igt_post_hang_ring(int fd, struct igt_hang_ring arg)
|
||||||
{
|
{
|
||||||
struct local_i915_gem_context_param param;
|
struct local_i915_gem_context_param param;
|
||||||
@ -103,3 +149,193 @@ void igt_post_hang_ring(int fd, struct igt_hang_ring arg)
|
|||||||
param.value = arg.ban;
|
param.value = arg.ban;
|
||||||
gem_context_set_param(fd, ¶m);
|
gem_context_set_param(fd, ¶m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* GPU abusers */
|
||||||
|
static struct igt_helper_process hang_helper;
|
||||||
|
static void __attribute__((noreturn))
|
||||||
|
hang_helper_process(pid_t pid, int fd)
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
if (kill(pid, 0)) /* Parent has died, so must we. */
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
igt_post_hang_ring(fd,
|
||||||
|
igt_hang_ring(fd, I915_EXEC_DEFAULT));
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* igt_fork_hang_helper:
|
||||||
|
*
|
||||||
|
* Fork a child process using #igt_fork_helper to hang the default engine
|
||||||
|
* of the GPU at regular intervals.
|
||||||
|
*
|
||||||
|
* This is useful to exercise slow running code (such as aperture placement)
|
||||||
|
* which needs to be robust against a GPU reset.
|
||||||
|
*
|
||||||
|
* In tests with subtests this function can be called outside of failure
|
||||||
|
* catching code blocks like #igt_fixture or #igt_subtest.
|
||||||
|
*/
|
||||||
|
int igt_fork_hang_helper(void)
|
||||||
|
{
|
||||||
|
int fd, gen;
|
||||||
|
|
||||||
|
if (igt_only_list_subtests())
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
fd = drm_open_any();
|
||||||
|
if (fd == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
gen = intel_gen(intel_get_drm_devid(fd));
|
||||||
|
if (gen < 5) {
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
igt_fork_helper(&hang_helper)
|
||||||
|
hang_helper_process(getppid(), fd);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* igt_stop_hang_helper:
|
||||||
|
*
|
||||||
|
* Stops the child process spawned with igt_fork_hang_helper().
|
||||||
|
*
|
||||||
|
* In tests with subtests this function can be called outside of failure
|
||||||
|
* catching code blocks like #igt_fixture or #igt_subtest.
|
||||||
|
*/
|
||||||
|
void igt_stop_hang_helper(void)
|
||||||
|
{
|
||||||
|
if (igt_only_list_subtests())
|
||||||
|
return;
|
||||||
|
|
||||||
|
igt_stop_helper(&hang_helper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* igt_open_forcewake_handle:
|
||||||
|
*
|
||||||
|
* This functions opens the debugfs forcewake file and so prevents the GT from
|
||||||
|
* suspending. The reference is automatically dropped when the is closed.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* The file descriptor of the forcewake handle or -1 if that didn't work out.
|
||||||
|
*/
|
||||||
|
int igt_open_forcewake_handle(void)
|
||||||
|
{
|
||||||
|
if (getenv("IGT_NO_FORCEWAKE"))
|
||||||
|
return -1;
|
||||||
|
return igt_debugfs_open("i915_forcewake_user", O_WRONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* igt_to_stop_ring_flag:
|
||||||
|
* @ring: the specified ring flag from execbuf ioctl (I915_EXEC_*)
|
||||||
|
*
|
||||||
|
* This converts the specified ring to a ring flag to be used
|
||||||
|
* with igt_get_stop_rings() and igt_set_stop_rings().
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Ring flag for the given ring.
|
||||||
|
*/
|
||||||
|
enum stop_ring_flags igt_to_stop_ring_flag(int ring) {
|
||||||
|
if (ring == I915_EXEC_DEFAULT)
|
||||||
|
return STOP_RING_RENDER;
|
||||||
|
|
||||||
|
igt_assert(ring && ((ring & ~I915_EXEC_RING_MASK) == 0));
|
||||||
|
return 1 << (ring - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void stop_rings_write(uint32_t mask)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
char buf[80];
|
||||||
|
|
||||||
|
igt_assert(snprintf(buf, sizeof(buf), "0x%08x", mask) == 10);
|
||||||
|
fd = igt_debugfs_open("i915_ring_stop", O_WRONLY);
|
||||||
|
igt_assert(fd >= 0);
|
||||||
|
|
||||||
|
igt_assert(write(fd, buf, strlen(buf)) == strlen(buf));
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* igt_get_stop_rings:
|
||||||
|
*
|
||||||
|
* Read current ring flags from 'i915_ring_stop' debugfs entry.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Current ring flags.
|
||||||
|
*/
|
||||||
|
enum stop_ring_flags igt_get_stop_rings(void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
char buf[80];
|
||||||
|
int l;
|
||||||
|
unsigned long long ring_mask;
|
||||||
|
|
||||||
|
fd = igt_debugfs_open("i915_ring_stop", O_RDONLY);
|
||||||
|
igt_assert(fd >= 0);
|
||||||
|
l = read(fd, buf, sizeof(buf)-1);
|
||||||
|
igt_assert(l > 0);
|
||||||
|
igt_assert(l < sizeof(buf));
|
||||||
|
|
||||||
|
buf[l] = '\0';
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
ring_mask = strtoull(buf, NULL, 0);
|
||||||
|
igt_assert(errno == 0);
|
||||||
|
return ring_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* igt_set_stop_rings:
|
||||||
|
* @flags: Ring flags to write
|
||||||
|
*
|
||||||
|
* This writes @flags to 'i915_ring_stop' debugfs entry. Driver will
|
||||||
|
* prevent the CPU from writing tail pointer for the ring that @flags
|
||||||
|
* specify. Note that the ring is not stopped right away. Instead any
|
||||||
|
* further command emissions won't be executed after the flag is set.
|
||||||
|
*
|
||||||
|
* This is the least invasive way to make the GPU stuck. Hence you must
|
||||||
|
* set this after a batch submission with it's own invalid or endless
|
||||||
|
* looping instructions. In this case it is merely for giving notification
|
||||||
|
* for the driver that this was simulated hang, as the batch would have
|
||||||
|
* caused hang in any case. On the other hand if you use a valid or noop
|
||||||
|
* batch and want to hang the ring (GPU), you must set corresponding flag
|
||||||
|
* before submitting the batch.
|
||||||
|
*
|
||||||
|
* Driver checks periodically if a ring is making any progress, and if
|
||||||
|
* it is not, it will declare the ring to be hung and will reset the GPU.
|
||||||
|
* After reset, the driver will clear flags in 'i915_ring_stop'
|
||||||
|
*
|
||||||
|
* Note: Always when hanging the GPU, use igt_set_stop_rings() to
|
||||||
|
* notify the driver. Driver controls hang log messaging based on
|
||||||
|
* these flags and thus prevents false positives on logs.
|
||||||
|
*/
|
||||||
|
void igt_set_stop_rings(enum stop_ring_flags flags)
|
||||||
|
{
|
||||||
|
enum stop_ring_flags current;
|
||||||
|
|
||||||
|
igt_assert((flags & ~(STOP_RING_ALL |
|
||||||
|
STOP_RING_ALLOW_BAN |
|
||||||
|
STOP_RING_ALLOW_ERRORS)) == 0);
|
||||||
|
|
||||||
|
current = igt_get_stop_rings();
|
||||||
|
igt_assert_f(flags == 0 || current == 0,
|
||||||
|
"previous i915_ring_stop is still 0x%x\n", current);
|
||||||
|
|
||||||
|
stop_rings_write(flags);
|
||||||
|
current = igt_get_stop_rings();
|
||||||
|
igt_warn_on_f(current != flags,
|
||||||
|
"i915_ring_stop readback mismatch 0x%x vs 0x%x\n",
|
||||||
|
flags, current);
|
||||||
|
}
|
||||||
|
46
lib/igt_gt.h
46
lib/igt_gt.h
@ -24,12 +24,54 @@
|
|||||||
#ifndef IGT_GT_H
|
#ifndef IGT_GT_H
|
||||||
#define IGT_GT_H
|
#define IGT_GT_H
|
||||||
|
|
||||||
|
#include "igt_debugfs.h"
|
||||||
|
|
||||||
void igt_require_hang_ring(int fd, int ring);
|
void igt_require_hang_ring(int fd, int ring);
|
||||||
|
|
||||||
struct igt_hang_ring {
|
typedef struct igt_hang_ring {
|
||||||
unsigned handle;
|
unsigned handle;
|
||||||
unsigned ban;
|
unsigned ban;
|
||||||
} igt_hang_ring(int fd, int gen, int ring);
|
} igt_hang_ring_t;
|
||||||
|
|
||||||
|
struct igt_hang_ring igt_hang_ring(int fd, int ring);
|
||||||
void igt_post_hang_ring(int fd, struct igt_hang_ring data);
|
void igt_post_hang_ring(int fd, struct igt_hang_ring data);
|
||||||
|
|
||||||
|
int igt_fork_hang_helper(void);
|
||||||
|
void igt_stop_hang_helper(void);
|
||||||
|
|
||||||
|
int igt_open_forcewake_handle(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stop_ring_flags:
|
||||||
|
* @STOP_RING_NONE: Can be used to clear the pending stop (warning: hang might
|
||||||
|
* be declared already). Returned by igt_get_stop_rings() if there is
|
||||||
|
* no currently stopped rings.
|
||||||
|
* @STOP_RING_RENDER: Render ring
|
||||||
|
* @STOP_RING_BSD: Video encoding/decoding ring
|
||||||
|
* @STOP_RING_BLT: Blitter ring
|
||||||
|
* @STOP_RING_VEBOX: Video enhancement ring
|
||||||
|
* @STOP_RING_ALL: All rings
|
||||||
|
* @STOP_RING_ALLOW_ERRORS: Driver will not omit expected DRM_ERRORS
|
||||||
|
* @STOP_RING_ALLOW_BAN: Driver will use context ban policy
|
||||||
|
* @STOP_RING_DEFAULTS: STOP_RING_ALL | STOP_RING_ALLOW_ERRORS
|
||||||
|
*
|
||||||
|
* Enumeration of all supported flags for igt_set_stop_rings().
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
enum stop_ring_flags {
|
||||||
|
STOP_RING_NONE = 0x00,
|
||||||
|
STOP_RING_RENDER = (1 << 0),
|
||||||
|
STOP_RING_BSD = (1 << 1),
|
||||||
|
STOP_RING_BLT = (1 << 2),
|
||||||
|
STOP_RING_VEBOX = (1 << 3),
|
||||||
|
STOP_RING_ALL = 0xff,
|
||||||
|
STOP_RING_ALLOW_ERRORS = (1 << 30),
|
||||||
|
STOP_RING_ALLOW_BAN = (1 << 31),
|
||||||
|
STOP_RING_DEFAULTS = STOP_RING_ALL | STOP_RING_ALLOW_ERRORS,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum stop_ring_flags igt_to_stop_ring_flag(int ring);
|
||||||
|
void igt_set_stop_rings(enum stop_ring_flags flags);
|
||||||
|
enum stop_ring_flags igt_get_stop_rings(void);
|
||||||
|
|
||||||
#endif /* IGT_GT_H */
|
#endif /* IGT_GT_H */
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
#include "intel_io.h"
|
#include "intel_io.h"
|
||||||
#include "igt_core.h"
|
#include "igt_core.h"
|
||||||
#include "igt_debugfs.h"
|
#include "igt_gt.h"
|
||||||
#include "intel_chipset.h"
|
#include "intel_chipset.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include "intel_chipset.h"
|
#include "intel_chipset.h"
|
||||||
#include "drmtest.h"
|
#include "drmtest.h"
|
||||||
#include "igt_aux.h"
|
#include "igt_aux.h"
|
||||||
#include "igt_debugfs.h"
|
#include "igt_gt.h"
|
||||||
#include "ioctl_wrappers.h"
|
#include "ioctl_wrappers.h"
|
||||||
|
|
||||||
#ifndef I915_PARAM_CMD_PARSER_VERSION
|
#ifndef I915_PARAM_CMD_PARSER_VERSION
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
#include "ioctl_wrappers.h"
|
#include "ioctl_wrappers.h"
|
||||||
#include "drmtest.h"
|
#include "drmtest.h"
|
||||||
#include "igt_debugfs.h"
|
#include "igt_gt.h"
|
||||||
#include "igt_aux.h"
|
#include "igt_aux.h"
|
||||||
|
|
||||||
#define OBJECT_SIZE (16*1024*1024)
|
#define OBJECT_SIZE (16*1024*1024)
|
||||||
|
@ -464,12 +464,12 @@ static struct igt_hang_ring no_hang(void)
|
|||||||
|
|
||||||
static struct igt_hang_ring bcs_hang(void)
|
static struct igt_hang_ring bcs_hang(void)
|
||||||
{
|
{
|
||||||
return igt_hang_ring(fd, gen, I915_EXEC_BLT);
|
return igt_hang_ring(fd, I915_EXEC_BLT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct igt_hang_ring rcs_hang(void)
|
static struct igt_hang_ring rcs_hang(void)
|
||||||
{
|
{
|
||||||
return igt_hang_ring(fd, gen, I915_EXEC_RENDER);
|
return igt_hang_ring(fd, I915_EXEC_RENDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hang_require(void)
|
static void hang_require(void)
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
#include "ioctl_wrappers.h"
|
#include "ioctl_wrappers.h"
|
||||||
#include "drmtest.h"
|
#include "drmtest.h"
|
||||||
#include "igt_aux.h"
|
#include "igt_aux.h"
|
||||||
#include "igt_debugfs.h"
|
#include "igt_gt.h"
|
||||||
|
|
||||||
IGT_TEST_DESCRIPTION("Test basic context switch functionality.");
|
IGT_TEST_DESCRIPTION("Test basic context switch functionality.");
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "drmtest.h"
|
#include "drmtest.h"
|
||||||
#include "intel_chipset.h"
|
#include "intel_chipset.h"
|
||||||
#include "igt_aux.h"
|
#include "igt_aux.h"
|
||||||
|
#include "igt_gt.h"
|
||||||
|
|
||||||
IGT_TEST_DESCRIPTION("Run a couple of big batches to force the unbind on"
|
IGT_TEST_DESCRIPTION("Run a couple of big batches to force the unbind on"
|
||||||
" misalignment code.");
|
" misalignment code.");
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#include "ioctl_wrappers.h"
|
#include "ioctl_wrappers.h"
|
||||||
#include "drmtest.h"
|
#include "drmtest.h"
|
||||||
#include "intel_chipset.h"
|
#include "intel_chipset.h"
|
||||||
|
#include "igt_gt.h"
|
||||||
|
|
||||||
#include "eviction_common.c"
|
#include "eviction_common.c"
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ static struct igt_hang_ring no_hang(int fd)
|
|||||||
|
|
||||||
static struct igt_hang_ring bcs_hang(int fd)
|
static struct igt_hang_ring bcs_hang(int fd)
|
||||||
{
|
{
|
||||||
return igt_hang_ring(fd, batch->gen, batch->gen >= 6 ? I915_EXEC_BLT : I915_EXEC_DEFAULT);
|
return igt_hang_ring(fd, batch->gen >= 6 ? I915_EXEC_BLT : I915_EXEC_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_test(int fd, int cache_level,
|
static void do_test(int fd, int cache_level,
|
||||||
|
@ -198,7 +198,7 @@ static struct igt_hang_ring no_hang(int fd)
|
|||||||
|
|
||||||
static struct igt_hang_ring bcs_hang(int fd)
|
static struct igt_hang_ring bcs_hang(int fd)
|
||||||
{
|
{
|
||||||
return igt_hang_ring(fd, batch->gen, I915_EXEC_BLT);
|
return igt_hang_ring(fd, I915_EXEC_BLT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_test(int fd, bool faulting_reloc,
|
static void do_test(int fd, bool faulting_reloc,
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
#include "ioctl_wrappers.h"
|
#include "ioctl_wrappers.h"
|
||||||
#include "drmtest.h"
|
#include "drmtest.h"
|
||||||
#include "igt_debugfs.h"
|
#include "igt_gt.h"
|
||||||
#include "intel_chipset.h"
|
#include "intel_chipset.h"
|
||||||
#include "intel_io.h"
|
#include "intel_io.h"
|
||||||
#include "igt_aux.h"
|
#include "igt_aux.h"
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
#include "ioctl_wrappers.h"
|
#include "ioctl_wrappers.h"
|
||||||
#include "drmtest.h"
|
#include "drmtest.h"
|
||||||
#include "igt_debugfs.h"
|
#include "igt_gt.h"
|
||||||
#include "igt_aux.h"
|
#include "igt_aux.h"
|
||||||
#include "intel_chipset.h"
|
#include "intel_chipset.h"
|
||||||
#include "intel_io.h"
|
#include "intel_io.h"
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
#include "intel_batchbuffer.h"
|
#include "intel_batchbuffer.h"
|
||||||
#include "igt_kms.h"
|
#include "igt_kms.h"
|
||||||
#include "igt_aux.h"
|
#include "igt_aux.h"
|
||||||
#include "igt_debugfs.h"
|
#include "igt_gt.h"
|
||||||
|
|
||||||
#define TEST_DPMS (1 << 0)
|
#define TEST_DPMS (1 << 0)
|
||||||
#define TEST_WITH_DUMMY_BCS (1 << 1)
|
#define TEST_WITH_DUMMY_BCS (1 << 1)
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "drmtest.h"
|
#include "drmtest.h"
|
||||||
#include "igt_debugfs.h"
|
#include "igt_gt.h"
|
||||||
#include "igt_kms.h"
|
#include "igt_kms.h"
|
||||||
#include "igt_aux.h"
|
#include "igt_aux.h"
|
||||||
#include "ioctl_wrappers.h"
|
#include "ioctl_wrappers.h"
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
#include "ioctl_wrappers.h"
|
#include "ioctl_wrappers.h"
|
||||||
#include "igt_aux.h"
|
#include "igt_aux.h"
|
||||||
#include "igt_kms.h"
|
#include "igt_kms.h"
|
||||||
#include "igt_debugfs.h"
|
#include "igt_gt.h"
|
||||||
|
|
||||||
/* One day, this will be on your libdrm. */
|
/* One day, this will be on your libdrm. */
|
||||||
#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
|
#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
#include "intel_bufmgr.h"
|
#include "intel_bufmgr.h"
|
||||||
#include "intel_batchbuffer.h"
|
#include "intel_batchbuffer.h"
|
||||||
#include "intel_chipset.h"
|
#include "intel_chipset.h"
|
||||||
#include "igt_debugfs.h"
|
#include "igt_gt.h"
|
||||||
#include "ioctl_wrappers.h"
|
#include "ioctl_wrappers.h"
|
||||||
|
|
||||||
static int drm_fd;
|
static int drm_fd;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user