Merge tag 'drm-intel-gt-next-2024-06-12' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next
UAPI Changes: - Support replaying GPU hangs with captured context image (Tvrtko Ursulin) Driver Changes: Fixes/improvements/new stuff: - Automate CCS Mode setting during engine resets [gt] (Andi Shyti) - Revert "drm/i915: Remove extra multi-gt pm-references" (Janusz Krzysztofik) - Fix HAS_REGION() usage in intel_gt_probe_lmem() (Ville Syrjälä) - Disarm breadcrumbs if engines are already idle [gt] (Chris Wilson) - Shadow default engine context image in the context (Tvrtko Ursulin) - Support replaying GPU hangs with captured context image (Tvrtko Ursulin) - avoid FIELD_PREP warning [guc] (Arnd Bergmann) - Fix CCS id's calculation for CCS mode setting [gt] (Andi Shyti) - Increase FLR timeout from 3s to 9s (Andi Shyti) - Update workaround 14018575942 [mtl] (Angus Chen) Future platform enablement: - Enable w/a 16021333562 for DG2, MTL and ARL [guc] (John Harrison) Miscellaneous: - Pass the region ID rather than a bitmask to HAS_REGION() (Ville Syrjälä) - Remove counter productive REGION_* wrappers (Ville Syrjälä) - Fix typo [gem/i915_gem_ttm_move] (Deming Wang) - Delete the live_hearbeat_fast selftest [gt] (Krzysztof Niemiec) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Tvrtko Ursulin <tursulin@igalia.com> Link: https://patchwork.freedesktop.org/patch/msgid/Zmmazub+U9ewH9ts@linux
This commit is contained in:
@@ -16,6 +16,23 @@ config DRM_I915_WERROR
|
||||
|
||||
If in doubt, say "N".
|
||||
|
||||
config DRM_I915_REPLAY_GPU_HANGS_API
|
||||
bool "Enable GPU hang replay userspace API"
|
||||
depends on DRM_I915
|
||||
depends on EXPERT
|
||||
default n
|
||||
help
|
||||
Choose this option if you want to enable special and unstable
|
||||
userspace API used for replaying GPU hangs on a running system.
|
||||
|
||||
This API is intended to be used by userspace graphics stack developers
|
||||
and provides no stability guarantees.
|
||||
|
||||
The API needs to be activated at boot time using the
|
||||
enable_debug_only_api module parameter.
|
||||
|
||||
If in doubt, say "N".
|
||||
|
||||
config DRM_I915_DEBUG
|
||||
bool "Enable additional driver debugging"
|
||||
depends on DRM_I915
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
#include "gt/intel_engine_user.h"
|
||||
#include "gt/intel_gpu_commands.h"
|
||||
#include "gt/intel_ring.h"
|
||||
#include "gt/shmem_utils.h"
|
||||
|
||||
#include "pxp/intel_pxp.h"
|
||||
|
||||
@@ -957,6 +958,7 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
|
||||
case I915_CONTEXT_PARAM_NO_ZEROMAP:
|
||||
case I915_CONTEXT_PARAM_BAN_PERIOD:
|
||||
case I915_CONTEXT_PARAM_RINGSIZE:
|
||||
case I915_CONTEXT_PARAM_CONTEXT_IMAGE:
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
@@ -2104,6 +2106,95 @@ static int get_protected(struct i915_gem_context *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_context_image(struct i915_gem_context *ctx,
|
||||
struct drm_i915_gem_context_param *args)
|
||||
{
|
||||
struct i915_gem_context_param_context_image user;
|
||||
struct intel_context *ce;
|
||||
struct file *shmem_state;
|
||||
unsigned long lookup;
|
||||
void *state;
|
||||
int ret = 0;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API))
|
||||
return -EINVAL;
|
||||
|
||||
if (!ctx->i915->params.enable_debug_only_api)
|
||||
return -EINVAL;
|
||||
|
||||
if (args->size < sizeof(user))
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(&user, u64_to_user_ptr(args->value), sizeof(user)))
|
||||
return -EFAULT;
|
||||
|
||||
if (user.mbz)
|
||||
return -EINVAL;
|
||||
|
||||
if (user.flags & ~(I915_CONTEXT_IMAGE_FLAG_ENGINE_INDEX))
|
||||
return -EINVAL;
|
||||
|
||||
lookup = 0;
|
||||
if (user.flags & I915_CONTEXT_IMAGE_FLAG_ENGINE_INDEX)
|
||||
lookup |= LOOKUP_USER_INDEX;
|
||||
|
||||
ce = lookup_user_engine(ctx, lookup, &user.engine);
|
||||
if (IS_ERR(ce))
|
||||
return PTR_ERR(ce);
|
||||
|
||||
if (user.size < ce->engine->context_size) {
|
||||
ret = -EINVAL;
|
||||
goto out_ce;
|
||||
}
|
||||
|
||||
if (drm_WARN_ON_ONCE(&ctx->i915->drm,
|
||||
test_bit(CONTEXT_ALLOC_BIT, &ce->flags))) {
|
||||
/*
|
||||
* This is racy but for a debug only API, if userspace is keen
|
||||
* to create and configure contexts, while simultaneously using
|
||||
* them from a second thread, let them suffer by potentially not
|
||||
* executing with the context image they just raced to apply.
|
||||
*/
|
||||
ret = -EBUSY;
|
||||
goto out_ce;
|
||||
}
|
||||
|
||||
state = kmalloc(ce->engine->context_size, GFP_KERNEL);
|
||||
if (!state) {
|
||||
ret = -ENOMEM;
|
||||
goto out_ce;
|
||||
}
|
||||
|
||||
if (copy_from_user(state, u64_to_user_ptr(user.image),
|
||||
ce->engine->context_size)) {
|
||||
ret = -EFAULT;
|
||||
goto out_state;
|
||||
}
|
||||
|
||||
shmem_state = shmem_create_from_data(ce->engine->name,
|
||||
state, ce->engine->context_size);
|
||||
if (IS_ERR(shmem_state)) {
|
||||
ret = PTR_ERR(shmem_state);
|
||||
goto out_state;
|
||||
}
|
||||
|
||||
if (intel_context_set_own_state(ce)) {
|
||||
ret = -EBUSY;
|
||||
fput(shmem_state);
|
||||
goto out_state;
|
||||
}
|
||||
|
||||
ce->default_state = shmem_state;
|
||||
|
||||
args->size = sizeof(user);
|
||||
|
||||
out_state:
|
||||
kfree(state);
|
||||
out_ce:
|
||||
intel_context_put(ce);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ctx_setparam(struct drm_i915_file_private *fpriv,
|
||||
struct i915_gem_context *ctx,
|
||||
struct drm_i915_gem_context_param *args)
|
||||
@@ -2156,6 +2247,10 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
|
||||
ret = set_persistence(ctx, args);
|
||||
break;
|
||||
|
||||
case I915_CONTEXT_PARAM_CONTEXT_IMAGE:
|
||||
ret = set_context_image(ctx, args);
|
||||
break;
|
||||
|
||||
case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
|
||||
case I915_CONTEXT_PARAM_NO_ZEROMAP:
|
||||
case I915_CONTEXT_PARAM_BAN_PERIOD:
|
||||
@@ -2500,6 +2595,7 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
|
||||
case I915_CONTEXT_PARAM_BAN_PERIOD:
|
||||
case I915_CONTEXT_PARAM_ENGINES:
|
||||
case I915_CONTEXT_PARAM_RINGSIZE:
|
||||
case I915_CONTEXT_PARAM_CONTEXT_IMAGE:
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
@@ -2612,5 +2708,22 @@ int __init i915_gem_context_module_init(void)
|
||||
if (!slab_luts)
|
||||
return -ENOMEM;
|
||||
|
||||
if (IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API)) {
|
||||
pr_notice("**************************************************************\n");
|
||||
pr_notice("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n");
|
||||
pr_notice("** **\n");
|
||||
if (i915_modparams.enable_debug_only_api)
|
||||
pr_notice("** i915.enable_debug_only_api is intended to be set **\n");
|
||||
else
|
||||
pr_notice("** CONFIG_DRM_I915_REPLAY_GPU_HANGS_API builds are intended **\n");
|
||||
pr_notice("** for specific userspace graphics stack developers only! **\n");
|
||||
pr_notice("** **\n");
|
||||
pr_notice("** If you are seeing this message please report this to the **\n");
|
||||
pr_notice("** provider of your kernel build. **\n");
|
||||
pr_notice("** **\n");
|
||||
pr_notice("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n");
|
||||
pr_notice("**************************************************************\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ void i915_ttm_adjust_gem_after_move(struct drm_i915_gem_object *obj)
|
||||
* @bo: The ttm buffer object.
|
||||
*
|
||||
* This function prepares an object for move by removing all GPU bindings,
|
||||
* removing all CPU mapings and finally releasing the pages sg-table.
|
||||
* removing all CPU mappings and finally releasing the pages sg-table.
|
||||
*
|
||||
* Return: 0 if successful, negative error code on error.
|
||||
*/
|
||||
|
||||
@@ -27,6 +27,8 @@ static void rcu_context_free(struct rcu_head *rcu)
|
||||
struct intel_context *ce = container_of(rcu, typeof(*ce), rcu);
|
||||
|
||||
trace_intel_context_free(ce);
|
||||
if (intel_context_has_own_state(ce))
|
||||
fput(ce->default_state);
|
||||
kmem_cache_free(slab_ce, ce);
|
||||
}
|
||||
|
||||
|
||||
@@ -375,6 +375,28 @@ intel_context_clear_nopreempt(struct intel_context *ce)
|
||||
clear_bit(CONTEXT_NOPREEMPT, &ce->flags);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API)
|
||||
static inline bool intel_context_has_own_state(const struct intel_context *ce)
|
||||
{
|
||||
return test_bit(CONTEXT_OWN_STATE, &ce->flags);
|
||||
}
|
||||
|
||||
static inline bool intel_context_set_own_state(struct intel_context *ce)
|
||||
{
|
||||
return test_and_set_bit(CONTEXT_OWN_STATE, &ce->flags);
|
||||
}
|
||||
#else
|
||||
static inline bool intel_context_has_own_state(const struct intel_context *ce)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool intel_context_set_own_state(struct intel_context *ce)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
u64 intel_context_get_total_runtime_ns(struct intel_context *ce);
|
||||
u64 intel_context_get_avg_runtime_ns(struct intel_context *ce);
|
||||
|
||||
|
||||
@@ -99,6 +99,8 @@ struct intel_context {
|
||||
struct i915_address_space *vm;
|
||||
struct i915_gem_context __rcu *gem_context;
|
||||
|
||||
struct file *default_state;
|
||||
|
||||
/*
|
||||
* @signal_lock protects the list of requests that need signaling,
|
||||
* @signals. While there are any requests that need signaling,
|
||||
@@ -131,6 +133,7 @@ struct intel_context {
|
||||
#define CONTEXT_IS_PARKING 12
|
||||
#define CONTEXT_EXITING 13
|
||||
#define CONTEXT_LOW_LATENCY 14
|
||||
#define CONTEXT_OWN_STATE 15
|
||||
|
||||
struct {
|
||||
u64 timeout_us;
|
||||
|
||||
@@ -1017,9 +1017,8 @@ void lrc_init_state(struct intel_context *ce,
|
||||
|
||||
set_redzone(state, engine);
|
||||
|
||||
if (engine->default_state) {
|
||||
shmem_read(engine->default_state, 0,
|
||||
state, engine->context_size);
|
||||
if (ce->default_state) {
|
||||
shmem_read(ce->default_state, 0, state, engine->context_size);
|
||||
__set_bit(CONTEXT_VALID_BIT, &ce->flags);
|
||||
inhibit = false;
|
||||
}
|
||||
@@ -1131,6 +1130,9 @@ int lrc_alloc(struct intel_context *ce, struct intel_engine_cs *engine)
|
||||
|
||||
GEM_BUG_ON(ce->state);
|
||||
|
||||
if (!intel_context_has_own_state(ce))
|
||||
ce->default_state = engine->default_state;
|
||||
|
||||
vma = __lrc_alloc_state(ce, engine);
|
||||
if (IS_ERR(vma))
|
||||
return PTR_ERR(vma);
|
||||
|
||||
@@ -474,8 +474,7 @@ static int ring_context_init_default_state(struct intel_context *ce,
|
||||
if (IS_ERR(vaddr))
|
||||
return PTR_ERR(vaddr);
|
||||
|
||||
shmem_read(ce->engine->default_state, 0,
|
||||
vaddr, ce->engine->context_size);
|
||||
shmem_read(ce->default_state, 0, vaddr, ce->engine->context_size);
|
||||
|
||||
i915_gem_object_flush_map(obj);
|
||||
__i915_gem_object_release_map(obj);
|
||||
@@ -491,7 +490,7 @@ static int ring_context_pre_pin(struct intel_context *ce,
|
||||
struct i915_address_space *vm;
|
||||
int err = 0;
|
||||
|
||||
if (ce->engine->default_state &&
|
||||
if (ce->default_state &&
|
||||
!test_bit(CONTEXT_VALID_BIT, &ce->flags)) {
|
||||
err = ring_context_init_default_state(ce, ww);
|
||||
if (err)
|
||||
@@ -570,6 +569,9 @@ static int ring_context_alloc(struct intel_context *ce)
|
||||
{
|
||||
struct intel_engine_cs *engine = ce->engine;
|
||||
|
||||
if (!intel_context_has_own_state(ce))
|
||||
ce->default_state = engine->default_state;
|
||||
|
||||
/* One ringbuffer to rule them all */
|
||||
GEM_BUG_ON(!engine->legacy.ring);
|
||||
ce->ring = engine->legacy.ring;
|
||||
|
||||
@@ -1590,6 +1590,14 @@ xelpmp_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
|
||||
*/
|
||||
wa_write_or(wal, XELPMP_GSC_MOD_CTRL, FORCE_MISS_FTLB);
|
||||
|
||||
/*
|
||||
* Wa_14018575942
|
||||
*
|
||||
* Issue is seen on media KPI test running on VDBOX engine
|
||||
* especially VP9 encoding WLs
|
||||
*/
|
||||
wa_write_or(wal, XELPMP_VDBX_MOD_CTRL, FORCE_MISS_FTLB);
|
||||
|
||||
/* Wa_22016670082 */
|
||||
wa_write_or(wal, GEN12_SQCNT1, GEN12_STRICT_RAR_ENABLE);
|
||||
|
||||
|
||||
@@ -193,115 +193,6 @@ static int live_idle_pulse(void *arg)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cmp_u32(const void *_a, const void *_b)
|
||||
{
|
||||
const u32 *a = _a, *b = _b;
|
||||
|
||||
return *a - *b;
|
||||
}
|
||||
|
||||
static int __live_heartbeat_fast(struct intel_engine_cs *engine)
|
||||
{
|
||||
const unsigned int error_threshold = max(20000u, jiffies_to_usecs(6));
|
||||
struct intel_context *ce;
|
||||
struct i915_request *rq;
|
||||
ktime_t t0, t1;
|
||||
u32 times[5];
|
||||
int err;
|
||||
int i;
|
||||
|
||||
ce = intel_context_create(engine);
|
||||
if (IS_ERR(ce))
|
||||
return PTR_ERR(ce);
|
||||
|
||||
intel_engine_pm_get(engine);
|
||||
|
||||
err = intel_engine_set_heartbeat(engine, 1);
|
||||
if (err)
|
||||
goto err_pm;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(times); i++) {
|
||||
do {
|
||||
/* Manufacture a tick */
|
||||
intel_engine_park_heartbeat(engine);
|
||||
GEM_BUG_ON(engine->heartbeat.systole);
|
||||
engine->serial++; /* pretend we are not idle! */
|
||||
intel_engine_unpark_heartbeat(engine);
|
||||
|
||||
flush_delayed_work(&engine->heartbeat.work);
|
||||
if (!delayed_work_pending(&engine->heartbeat.work)) {
|
||||
pr_err("%s: heartbeat %d did not start\n",
|
||||
engine->name, i);
|
||||
err = -EINVAL;
|
||||
goto err_pm;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
rq = READ_ONCE(engine->heartbeat.systole);
|
||||
if (rq)
|
||||
rq = i915_request_get_rcu(rq);
|
||||
rcu_read_unlock();
|
||||
} while (!rq);
|
||||
|
||||
t0 = ktime_get();
|
||||
while (rq == READ_ONCE(engine->heartbeat.systole))
|
||||
yield(); /* work is on the local cpu! */
|
||||
t1 = ktime_get();
|
||||
|
||||
i915_request_put(rq);
|
||||
times[i] = ktime_us_delta(t1, t0);
|
||||
}
|
||||
|
||||
sort(times, ARRAY_SIZE(times), sizeof(times[0]), cmp_u32, NULL);
|
||||
|
||||
pr_info("%s: Heartbeat delay: %uus [%u, %u]\n",
|
||||
engine->name,
|
||||
times[ARRAY_SIZE(times) / 2],
|
||||
times[0],
|
||||
times[ARRAY_SIZE(times) - 1]);
|
||||
|
||||
/*
|
||||
* Ideally, the upper bound on min work delay would be something like
|
||||
* 2 * 2 (worst), +1 for scheduling, +1 for slack. In practice, we
|
||||
* are, even with system_wq_highpri, at the mercy of the CPU scheduler
|
||||
* and may be stuck behind some slow work for many millisecond. Such
|
||||
* as our very own display workers.
|
||||
*/
|
||||
if (times[ARRAY_SIZE(times) / 2] > error_threshold) {
|
||||
pr_err("%s: Heartbeat delay was %uus, expected less than %dus\n",
|
||||
engine->name,
|
||||
times[ARRAY_SIZE(times) / 2],
|
||||
error_threshold);
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
reset_heartbeat(engine);
|
||||
err_pm:
|
||||
intel_engine_pm_put(engine);
|
||||
intel_context_put(ce);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int live_heartbeat_fast(void *arg)
|
||||
{
|
||||
struct intel_gt *gt = arg;
|
||||
struct intel_engine_cs *engine;
|
||||
enum intel_engine_id id;
|
||||
int err = 0;
|
||||
|
||||
/* Check that the heartbeat ticks at the desired rate. */
|
||||
if (!CONFIG_DRM_I915_HEARTBEAT_INTERVAL)
|
||||
return 0;
|
||||
|
||||
for_each_engine(engine, gt, id) {
|
||||
err = __live_heartbeat_fast(engine);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __live_heartbeat_off(struct intel_engine_cs *engine)
|
||||
{
|
||||
int err;
|
||||
@@ -372,7 +263,6 @@ int intel_heartbeat_live_selftests(struct drm_i915_private *i915)
|
||||
static const struct i915_subtest tests[] = {
|
||||
SUBTEST(live_idle_flush),
|
||||
SUBTEST(live_idle_pulse),
|
||||
SUBTEST(live_heartbeat_fast),
|
||||
SUBTEST(live_heartbeat_off),
|
||||
};
|
||||
int saved_hangcheck;
|
||||
|
||||
@@ -106,6 +106,7 @@ enum {
|
||||
*/
|
||||
enum {
|
||||
GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE = 0x9001,
|
||||
GUC_WORKAROUND_KLV_BLOCK_INTERRUPTS_WHEN_MGSR_BLOCKED = 0x9002,
|
||||
};
|
||||
|
||||
#endif /* _ABI_GUC_KLVS_ABI_H */
|
||||
|
||||
@@ -815,23 +815,23 @@ engine_instance_list:
|
||||
return PAGE_ALIGN(total_size);
|
||||
}
|
||||
|
||||
/* Wa_14019159160 */
|
||||
static u32 guc_waklv_ra_mode(struct intel_guc *guc, u32 offset, u32 remain)
|
||||
static void guc_waklv_enable_simple(struct intel_guc *guc,
|
||||
u32 klv_id, u32 *offset, u32 *remain)
|
||||
{
|
||||
u32 size;
|
||||
u32 klv_entry[] = {
|
||||
/* 16:16 key/length */
|
||||
FIELD_PREP(GUC_KLV_0_KEY, GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE) |
|
||||
FIELD_PREP(GUC_KLV_0_KEY, klv_id) |
|
||||
FIELD_PREP(GUC_KLV_0_LEN, 0),
|
||||
/* 0 dwords data */
|
||||
};
|
||||
|
||||
size = sizeof(klv_entry);
|
||||
GEM_BUG_ON(remain < size);
|
||||
GEM_BUG_ON(*remain < size);
|
||||
|
||||
iosys_map_memcpy_to(&guc->ads_map, offset, klv_entry, size);
|
||||
|
||||
return size;
|
||||
iosys_map_memcpy_to(&guc->ads_map, *offset, klv_entry, size);
|
||||
*offset += size;
|
||||
*remain -= size;
|
||||
}
|
||||
|
||||
static void guc_waklv_init(struct intel_guc *guc)
|
||||
@@ -850,11 +850,19 @@ static void guc_waklv_init(struct intel_guc *guc)
|
||||
remain = guc_ads_waklv_size(guc);
|
||||
|
||||
/* Wa_14019159160 */
|
||||
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
|
||||
size = guc_waklv_ra_mode(guc, offset, remain);
|
||||
offset += size;
|
||||
remain -= size;
|
||||
}
|
||||
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
|
||||
guc_waklv_enable_simple(guc,
|
||||
GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE,
|
||||
&offset, &remain);
|
||||
|
||||
/* Wa_16021333562 */
|
||||
if ((GUC_FIRMWARE_VER(guc) >= MAKE_GUC_VER(70, 21, 1)) &&
|
||||
(IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)) ||
|
||||
IS_MEDIA_GT_IP_RANGE(gt, IP_VER(13, 0), IP_VER(13, 0)) ||
|
||||
IS_DG2(gt->i915)))
|
||||
guc_waklv_enable_simple(guc,
|
||||
GUC_WORKAROUND_KLV_BLOCK_INTERRUPTS_WHEN_MGSR_BLOCKED,
|
||||
&offset, &remain);
|
||||
|
||||
size = guc_ads_waklv_size(guc) - remain;
|
||||
if (!size)
|
||||
|
||||
@@ -724,8 +724,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
|
||||
*/
|
||||
#define HAS_64K_PAGES(i915) (INTEL_INFO(i915)->has_64k_pages)
|
||||
|
||||
#define HAS_REGION(i915, i) (INTEL_INFO(i915)->memory_regions & (i))
|
||||
#define HAS_LMEM(i915) HAS_REGION(i915, REGION_LMEM)
|
||||
#define HAS_REGION(i915, id) (INTEL_INFO(i915)->memory_regions & BIT(id))
|
||||
#define HAS_LMEM(i915) HAS_REGION(i915, INTEL_REGION_LMEM_0)
|
||||
|
||||
#define HAS_EXTRA_GT_LIST(i915) (INTEL_INFO(i915)->extra_gt_list)
|
||||
|
||||
|
||||
@@ -131,6 +131,11 @@ i915_param_named_unsafe(lmem_size, uint, 0400,
|
||||
i915_param_named_unsafe(lmem_bar_size, uint, 0400,
|
||||
"Set the lmem bar size(in MiB).");
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API)
|
||||
i915_param_named(enable_debug_only_api, bool, 0400,
|
||||
"Enable support for unstable debug only userspace API. (default:false)");
|
||||
#endif
|
||||
|
||||
static void _param_print_bool(struct drm_printer *p, const char *name,
|
||||
bool val)
|
||||
{
|
||||
|
||||
@@ -63,7 +63,8 @@ struct drm_printer;
|
||||
/* leave bools at the end to not create holes */ \
|
||||
param(bool, enable_hangcheck, true, 0600) \
|
||||
param(bool, error_capture, true, IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) ? 0600 : 0) \
|
||||
param(bool, enable_gvt, false, IS_ENABLED(CONFIG_DRM_I915_GVT) ? 0400 : 0)
|
||||
param(bool, enable_gvt, false, IS_ENABLED(CONFIG_DRM_I915_GVT) ? 0400 : 0) \
|
||||
param(bool, enable_debug_only_api, false, IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API) ? 0400 : 0)
|
||||
|
||||
#define MEMBER(T, member, ...) T member;
|
||||
struct i915_params {
|
||||
|
||||
@@ -76,7 +76,7 @@ __diag_ignore_all("-Woverride-init", "Allow field initialization overrides for d
|
||||
.__runtime.page_sizes = I915_GTT_PAGE_SIZE_4K
|
||||
|
||||
#define GEN_DEFAULT_REGIONS \
|
||||
.memory_regions = REGION_SMEM | REGION_STOLEN_SMEM
|
||||
.memory_regions = BIT(INTEL_REGION_SMEM) | BIT(INTEL_REGION_STOLEN_SMEM)
|
||||
|
||||
#define I830_FEATURES \
|
||||
GEN(2), \
|
||||
@@ -655,7 +655,7 @@ static const struct intel_device_info rkl_info = {
|
||||
};
|
||||
|
||||
#define DGFX_FEATURES \
|
||||
.memory_regions = REGION_SMEM | REGION_LMEM | REGION_STOLEN_LMEM, \
|
||||
.memory_regions = BIT(INTEL_REGION_SMEM) | BIT(INTEL_REGION_LMEM_0) | BIT(INTEL_REGION_STOLEN_LMEM), \
|
||||
.has_llc = 0, \
|
||||
.has_pxp = 0, \
|
||||
.has_snoop = 1, \
|
||||
@@ -781,7 +781,7 @@ static const struct intel_device_info mtl_info = {
|
||||
.has_snoop = 1,
|
||||
.max_pat_index = 4,
|
||||
.has_pxp = 1,
|
||||
.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
|
||||
.memory_regions = BIT(INTEL_REGION_SMEM) | BIT(INTEL_REGION_STOLEN_LMEM),
|
||||
.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
|
||||
MTL_CACHELEVEL,
|
||||
};
|
||||
|
||||
@@ -332,7 +332,7 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
|
||||
struct intel_memory_region *mem = ERR_PTR(-ENODEV);
|
||||
u16 type, instance;
|
||||
|
||||
if (!HAS_REGION(i915, BIT(i)))
|
||||
if (!HAS_REGION(i915, i))
|
||||
continue;
|
||||
|
||||
type = intel_region_map[i].class;
|
||||
|
||||
@@ -38,11 +38,6 @@ enum intel_region_id {
|
||||
INTEL_REGION_UNKNOWN, /* Should be last */
|
||||
};
|
||||
|
||||
#define REGION_SMEM BIT(INTEL_REGION_SMEM)
|
||||
#define REGION_LMEM BIT(INTEL_REGION_LMEM_0)
|
||||
#define REGION_STOLEN_SMEM BIT(INTEL_REGION_STOLEN_SMEM)
|
||||
#define REGION_STOLEN_LMEM BIT(INTEL_REGION_STOLEN_LMEM)
|
||||
|
||||
#define I915_ALLOC_CONTIGUOUS BIT(0)
|
||||
|
||||
#define for_each_memory_region(mr, i915, id) \
|
||||
|
||||
@@ -2614,11 +2614,18 @@ void intel_uncore_prune_engine_fw_domains(struct intel_uncore *uncore,
|
||||
static void driver_initiated_flr(struct intel_uncore *uncore)
|
||||
{
|
||||
struct drm_i915_private *i915 = uncore->i915;
|
||||
const unsigned int flr_timeout_ms = 3000; /* specs recommend a 3s wait */
|
||||
unsigned int flr_timeout_ms;
|
||||
int ret;
|
||||
|
||||
drm_dbg(&i915->drm, "Triggering Driver-FLR\n");
|
||||
|
||||
/*
|
||||
* The specification recommends a 3 seconds FLR reset timeout. To be
|
||||
* cautious, we will extend this to 9 seconds, three times the specified
|
||||
* timeout.
|
||||
*/
|
||||
flr_timeout_ms = 9000;
|
||||
|
||||
/*
|
||||
* Make sure any pending FLR requests have cleared by waiting for the
|
||||
* FLR trigger bit to go to zero. Also clear GU_DEBUG's DRIVERFLR_STATUS
|
||||
|
||||
@@ -122,7 +122,7 @@ static const struct intel_device_info mock_info = {
|
||||
.__runtime.page_sizes = (I915_GTT_PAGE_SIZE_4K |
|
||||
I915_GTT_PAGE_SIZE_64K |
|
||||
I915_GTT_PAGE_SIZE_2M),
|
||||
.memory_regions = REGION_SMEM,
|
||||
.memory_regions = BIT(INTEL_REGION_SMEM),
|
||||
.platform_engine_mask = BIT(0),
|
||||
|
||||
/* simply use legacy cache level for mock device */
|
||||
|
||||
@@ -2163,6 +2163,15 @@ struct drm_i915_gem_context_param {
|
||||
* supports this per context flag.
|
||||
*/
|
||||
#define I915_CONTEXT_PARAM_LOW_LATENCY 0xe
|
||||
|
||||
/*
|
||||
* I915_CONTEXT_PARAM_CONTEXT_IMAGE:
|
||||
*
|
||||
* Allows userspace to provide own context images.
|
||||
*
|
||||
* Note that this is a debug API not available on production kernel builds.
|
||||
*/
|
||||
#define I915_CONTEXT_PARAM_CONTEXT_IMAGE 0xf
|
||||
/* Must be kept compact -- no holes and well documented */
|
||||
|
||||
/** @value: Context parameter value to be set or queried */
|
||||
@@ -2564,6 +2573,24 @@ struct i915_context_param_engines {
|
||||
struct i915_engine_class_instance engines[N__]; \
|
||||
} __attribute__((packed)) name__
|
||||
|
||||
struct i915_gem_context_param_context_image {
|
||||
/** @engine: Engine class & instance to be configured. */
|
||||
struct i915_engine_class_instance engine;
|
||||
|
||||
/** @flags: One of the supported flags or zero. */
|
||||
__u32 flags;
|
||||
#define I915_CONTEXT_IMAGE_FLAG_ENGINE_INDEX (1u << 0)
|
||||
|
||||
/** @size: Size of the image blob pointed to by @image. */
|
||||
__u32 size;
|
||||
|
||||
/** @mbz: Must be zero. */
|
||||
__u32 mbz;
|
||||
|
||||
/** @image: Userspace memory containing the context image. */
|
||||
__u64 image;
|
||||
} __attribute__((packed));
|
||||
|
||||
/**
|
||||
* struct drm_i915_gem_context_create_ext_setparam - Context parameter
|
||||
* to set or query during context creation.
|
||||
|
||||
Reference in New Issue
Block a user