This CL adds the ioctl necessary to set the watchdog timer
after each batch buffer is submitted.
This is part of the Timeout Detection and Recovery (TDR)
mechanism previously done here in upstream:
https://patchwork.freedesktop.org/series/21868/.
Tested-by: Carlos Santa <carlos.santa(a)intel.com>
Signed-off-by: Carlos Santa <carlos.santa(a)intel.com>
---
src/i965_drv_video.c | 14 +++++++++++++
src/i965_drv_video.h | 3 +++
src/intel_batchbuffer.c | 17 ++++++++++++----
src/intel_batchbuffer.h | 10 ++++++---
src/intel_driver.c | 45 +++++++++++++++++++++++++++++++++++++++++
src/intel_driver.h | 24 ++++++++++++++++++++++
6 files changed, 106 insertions(+), 7 deletions(-)
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index e1b688a..0962855 100644
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -2553,6 +2553,7 @@ i965_CreateContext(VADriverContextP ctx,
VAContextID *context) /* out */
{
struct i965_driver_data *i965 = i965_driver_data(ctx);
+ struct intel_driver_data *intel = intel_driver_data(ctx);
struct object_config *obj_config = CONFIG(config_id);
struct object_context *obj_context = NULL;
VAConfigAttrib *attrib;
@@ -2742,6 +2743,15 @@ i965_CreateContext(VADriverContextP ctx,
i965->current_context_id = contextID;
+ i965->bufmgr = drm_intel_bufmgr_gem_init(intel->fd, 4096);
+
+ i965->gem_context = drm_intel_gem_context_create(i965->bufmgr);
+ intel->gem_context = i965->gem_context;
+ intel->gem_ctx_id = i965->gem_context->ctx_id;
+
+ if (kernel_has_gpu_watchdog_support(&i965->intel))
+ i965->intel.has_watchdog = 1;
+
return vaStatus;
}
@@ -2766,6 +2776,10 @@ i965_DestroyContext(VADriverContextP ctx, VAContextID context)
obj_context->wrapper_context = VA_INVALID_ID;
}
+ drm_intel_gem_context_destroy(i965->gem_context);
+
+ i965->intel.has_watchdog = 0;
+
i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
return va_status;
diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h
index b4326e5..1fb7248 100644
--- a/src/i965_drv_video.h
+++ b/src/i965_drv_video.h
@@ -547,6 +547,9 @@ struct i965_driver_data {
VADisplayAttribute *saturation_attrib;
VAContextID current_context_id;
+ drm_intel_bufmgr *bufmgr;
+ drm_intel_context *gem_context;
+
/* VA/DRI (X11) specific data */
struct va_dri_output *dri_output;
diff --git a/src/intel_batchbuffer.c b/src/intel_batchbuffer.c
index 6d12130..ab86ba6 100644
--- a/src/intel_batchbuffer.c
+++ b/src/intel_batchbuffer.c
@@ -30,10 +30,10 @@
#include <assert.h>
#include "intel_batchbuffer.h"
+#include "i965_drv_video.h"
#define MAX_BATCH_SIZE 0x400000
-
#define LOCAL_I915_EXEC_BSD_MASK (3<<13)
#define LOCAL_I915_EXEC_BSD_DEFAULT (0<<13) /* default ping-pong mode */
#define LOCAL_I915_EXEC_BSD_RING0 (1<<13)
@@ -73,7 +73,6 @@ intel_batchbuffer_space(struct intel_batchbuffer *batch)
return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
}
-
struct intel_batchbuffer *
intel_batchbuffer_new(struct intel_driver_data *intel, int flag, int buffer_size)
{
@@ -98,7 +97,7 @@ intel_batchbuffer_new(struct intel_driver_data *intel, int flag, int
buffer_size
assert(batch);
batch->intel = intel;
batch->flag = flag;
- batch->run = drm_intel_bo_mrb_exec;
+ batch->run = drm_intel_gem_bo_fence_exec;
if (IS_GEN6(intel->device_info) &&
flag == I915_EXEC_RENDER)
@@ -130,6 +129,7 @@ void
intel_batchbuffer_flush(struct intel_batchbuffer *batch)
{
unsigned int used = batch->ptr - batch->map;
+ int ring_flag = batch->flag & I915_EXEC_RING_MASK;
if (used == 0) {
return;
@@ -144,7 +144,16 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch)
batch->ptr += 4;
dri_bo_unmap(batch->buffer);
used = batch->ptr - batch->map;
- batch->run(batch->buffer, used, 0, 0, 0, batch->flag);
+
+ if (batch->intel->has_watchdog)
+ intel_batchbuffer_configure_watchdog(batch->intel->fd,
batch->intel->gem_ctx_id, batch->flag);
+
+ /* FIXME: Add BSD2 ring on supported platforms */
+ if (ring_flag == I915_EXEC_BSD)
+ batch->flag |= LOCAL_I915_EXEC_BSD_RING0;
+
+ batch->run(batch->buffer, batch->intel->gem_context, used, -1, NULL,
batch->flag);
+
intel_batchbuffer_reset(batch, batch->size);
}
diff --git a/src/intel_batchbuffer.h b/src/intel_batchbuffer.h
index cbc5d79..3c47ddc 100644
--- a/src/intel_batchbuffer.h
+++ b/src/intel_batchbuffer.h
@@ -20,9 +20,13 @@ struct intel_batchbuffer {
int emit_total;
unsigned char *emit_start;
- int (*run)(drm_intel_bo *bo, int used,
- drm_clip_rect_t *cliprects, int num_cliprects,
- int DR4, unsigned int ring_flag);
+ /* Media reset timeout for this buffer in ms */
+ unsigned long watchdog_threshold;
+
+ int (*run)(drm_intel_bo *bo,
+ drm_intel_context *ctx,
+ int used, int in_fence,
+ int *out_fence, unsigned int flags);
/* Used for Sandybdrige workaround */
dri_bo *wa_render_bo;
diff --git a/src/intel_driver.c b/src/intel_driver.c
index 8e8c9af..5bcebc1 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -56,6 +56,51 @@ uint32_t g_intel_debug_option_flags = 0;
#define LOCAL_I915_PARAM_EU_TOTAL 34
#endif
+bool intel_batchbuffer_configure_watchdog(int fd, unsigned int gem_ctx_id, int flag)
+{
+ unsigned threshold[5];
+ int ring_flag;
+
+ ring_flag = flag & I915_EXEC_RING_MASK;
+
+ struct drm_i915_gem_context_param cp = {
+ .ctx_id = gem_ctx_id,
+ .param = LOCAL_I915_CONTEXT_PARAM_WATCHDOG,
+ .value = (uint64_t)&threshold,
+ .size = sizeof(threshold)
+ };
+
+ memset(threshold, 0, sizeof(threshold));
+
+ /* set watchdog threshold to VCS's engine only */
+ if (ring_flag == I915_EXEC_BSD || ring_flag == LOCAL_I915_EXEC_VCS2) {
+ threshold[VIDEO_DECODE_CLASS] = 1200;
+ }
+
+ if (drmIoctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &cp))
+ return false;
+
+ return true;
+}
+
+bool kernel_has_gpu_watchdog_support(struct intel_driver_data *intel)
+{
+ struct drm_i915_gem_context_param cp;
+ uint32_t threshold[16];
+
+ memset(&cp, 0, sizeof(cp));
+ cp.ctx_id = intel->gem_ctx_id;
+ cp.param = LOCAL_I915_CONTEXT_PARAM_WATCHDOG;
+ memset(threshold, 0, sizeof(threshold));
+ cp.size = sizeof(threshold);
+ cp.value = (uint64_t)threshold;
+
+ if (drmIoctl(intel->fd, DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &cp))
+ return false;
+
+ return true;
+}
+
static Bool
intel_driver_get_param(struct intel_driver_data *intel, int param, int *value)
{
diff --git a/src/intel_driver.h b/src/intel_driver.h
index c46a9cf..c0010b5 100644
--- a/src/intel_driver.h
+++ b/src/intel_driver.h
@@ -111,6 +111,18 @@ extern uint32_t g_intel_debug_option_flags;
#define VA_INTEL_DEBUG_OPTION_BENCH (1 << 1)
#define VA_INTEL_DEBUG_OPTION_DUMP_AUB (1 << 2)
+#define LOCAL_I915_CONTEXT_PARAM_WATCHDOG 0x7
+#define LOCAL_I915_EXEC_VEBOX (4<<0)
+#define LOCAL_I915_EXEC_VCS2 (5<<0)
+
+typedef enum _gen_gpu_class_engine {
+ RENDER_CLASS = 0,
+ VIDEO_DECODE_CLASS,
+ VIDEO_ENHANCEMENT_CLASS,
+ COPY_ENGINE_CLASS,
+ GEN_GPU_ENGINE_NUMBER
+} _gen_gpu_class_engine, *pgen_gpu_class_engine;
+
#define ASSERT_RET(value, fail_ret) do { \
if (!(value)) { \
if (g_intel_debug_option_flags & VA_INTEL_DEBUG_OPTION_ASSERT) \
@@ -183,6 +195,8 @@ struct intel_driver_data {
int locked;
dri_bufmgr *bufmgr;
+ unsigned int gem_ctx_id;
+ drm_intel_context *gem_context;
unsigned int has_exec2 : 1; /* Flag: has execbuffer2? */
unsigned int has_bsd : 1; /* Flag: has bitstream decoder for H.264? */
@@ -190,6 +204,7 @@ struct intel_driver_data {
unsigned int has_vebox : 1; /* Flag: has VEBOX unit */
unsigned int has_bsd2 : 1; /* Flag: has the second BSD video ring unit */
unsigned int has_huc : 1; /* Flag: has a fully loaded HuC firmware? */
+ unsigned int has_watchdog : 1; /* Flag: whether kmd has GPU watchdog support? */
int eu_total;
@@ -197,8 +212,16 @@ struct intel_driver_data {
unsigned int mocs_state;
};
+/* FIXME: this struct is currently private and part of libdrm */
+struct _drm_intel_context {
+ unsigned int ctx_id;
+ struct _drm_intel_bufmgr *bufmgr;
+};
+
bool intel_driver_init(VADriverContextP ctx);
void intel_driver_terminate(VADriverContextP ctx);
+bool intel_batchbuffer_configure_watchdog(int fd, unsigned int ctx_id, int flag);
+bool kernel_has_gpu_watchdog_support(struct intel_driver_data *intel);
static INLINE struct intel_driver_data *
intel_driver_data(VADriverContextP ctx)
@@ -243,4 +266,5 @@ struct intel_region {
#define IS_GEN10(device_info) (device_info->gen == 10)
+
#endif /* _INTEL_DRIVER_H_ */
--
2.17.1