From patchwork Fri Sep 1 17:12:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lionel Landwerlin X-Patchwork-Id: 9934913 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3733C6016C for ; Fri, 1 Sep 2017 17:12:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1D6EC223C6 for ; Fri, 1 Sep 2017 17:12:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 124AF26E49; Fri, 1 Sep 2017 17:12:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 97CEE223C6 for ; Fri, 1 Sep 2017 17:12:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 26F116E89B; Fri, 1 Sep 2017 17:12:45 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id 64FF86E8A3 for ; Fri, 1 Sep 2017 17:12:43 +0000 (UTC) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP; 01 Sep 2017 10:12:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.41,459,1498546800"; d="scan'208"; a="1213545348" Received: from delly.ld.intel.com ([10.103.239.215]) by fmsmga002.fm.intel.com with ESMTP; 01 Sep 2017 10:12:41 -0700 From: Lionel Landwerlin To: intel-gfx@lists.freedesktop.org Date: Fri, 1 Sep 2017 18:12:30 +0100 Message-Id: <20170901171230.28677-5-lionel.g.landwerlin@intel.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170901171230.28677-1-lionel.g.landwerlin@intel.com> References: <20170901171230.28677-1-lionel.g.landwerlin@intel.com> Subject: [Intel-gfx] [RFC PATCH 4/4] drm/i915: Expose RPCS (SSEU) configuration to userspace X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP From: Chris Wilson We want to allow userspace to reconfigure the subslice configuration for its own use case. To do so, we expose a context parameter to allow adjustment of the RPCS register stored within the context image (and currently not accessible via LRI). If the context is adjusted before first use, the adjustment is for "free"; otherwise if the context is active we flush the context off the GPU (stalling all users) and forcing the GPU to save the context to memory where we can modify it and so ensure that the register is reloaded on next execution. The overhead of managing additional EU subslices can be significant, especially in multi-context workloads. Non-GPGPU contexts should preferably disable the subslices it is not using, and others should fine-tune the number to match their workload. We expose complete control over the RPCS register, allowing configuration of slice/subslice, via masks packed into a u64 for simplicity. For example, struct drm_i915_gem_context_param arg; memset(&arg, 0, sizeof(arg)); arg.ctx_id = ctx; arg.param = I915_CONTEXT_PARAM_SSEU; if (drmIoctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &arg) == 0) { union drm_i915_gem_context_param_sseu *sseu = &arg.value; sseu->packed.subslice_mask = 0; drmIoctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &arg); } could be used to disable all subslices where supported. v2: Fix offset of CTX_R_PWR_CLK_STATE in intel_lr_context_set_sseu() (Lionel) Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100899 Signed-off-by: Chris Wilson Signed-off-by: Lionel Landwerlin Cc: Dmitry Rogozhkin CC: Tvrtko Ursulin CC: Zhipeng Gong CC: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_gem_context.c | 11 ++++++ drivers/gpu/drm/i915/intel_lrc.c | 69 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_lrc.h | 2 + include/uapi/drm/i915_drm.h | 11 ++++++ 4 files changed, 93 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 97fcb01d70eb..d399b03f452c 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -1042,6 +1042,9 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, case I915_CONTEXT_PARAM_BANNABLE: args->value = i915_gem_context_is_bannable(ctx); break; + case I915_CONTEXT_PARAM_SSEU: + args->value = intel_lr_context_get_sseu(ctx); + break; default: ret = -EINVAL; break; @@ -1097,6 +1100,14 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data, else i915_gem_context_clear_bannable(ctx); break; + case I915_CONTEXT_PARAM_SSEU: + if (args->size) + ret = -EINVAL; + else if (!i915.enable_execlists) + ret = -ENODEV; + else + ret = intel_lr_context_set_sseu(ctx, args->value); + break; default: ret = -EINVAL; break; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 1693fd9d279b..c063b84911d5 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -2122,3 +2122,72 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv) } } } + +int intel_lr_context_set_sseu(struct i915_gem_context *ctx, u64 value) +{ + union drm_i915_gem_context_param_sseu user = { .value = value }; + struct drm_i915_private *i915 = ctx->i915; + struct intel_context *ce = &ctx->engine[RCS]; + struct sseu_dev_info sseu = ctx->engine[RCS].sseu; + struct intel_engine_cs *engine; + enum intel_engine_id id; + int ret; + + lockdep_assert_held(&i915->drm.struct_mutex); + + sseu.slice_mask = + user.packed.slice_mask & INTEL_INFO(i915)->sseu.slice_mask; + sseu.subslice_mask = + user.packed.subslice_mask & INTEL_INFO(i915)->sseu.subslice_mask; + sseu.min_eu_per_subslice = + max(user.packed.min_eu_per_subslice, + INTEL_INFO(i915)->sseu.min_eu_per_subslice); + sseu.max_eu_per_subslice = + min(user.packed.max_eu_per_subslice, + INTEL_INFO(i915)->sseu.max_eu_per_subslice); + + if (memcmp(&sseu, &ctx->engine[RCS].sseu, sizeof(sseu)) == 0) + return 0; + + if (ce->pin_count) { /* Assume that the context is active! */ + ret = i915_gem_switch_to_kernel_context(i915); + if (ret) + return ret; + + ret = i915_gem_wait_for_idle(i915, + I915_WAIT_INTERRUPTIBLE | + I915_WAIT_LOCKED); + if (ret) + return ret; + } + + if (ce->state) { + u32 *regs; + + regs = i915_gem_object_pin_map(ce->state->obj, I915_MAP_WB) + + LRC_STATE_PN * PAGE_SIZE; + if (IS_ERR(regs)) + return PTR_ERR(regs); + + regs[CTX_R_PWR_CLK_STATE + 1] = make_rpcs(&sseu); + i915_gem_object_unpin_map(ce->state->obj); + } + + for_each_engine(engine, i915, id) + ctx->engine[id].sseu = sseu; + + return 0; +} + +u64 intel_lr_context_get_sseu(struct i915_gem_context *ctx) +{ + union drm_i915_gem_context_param_sseu user; + const struct sseu_dev_info *sseu = &ctx->engine[RCS].sseu; + + user.packed.slice_mask = sseu->slice_mask; + user.packed.subslice_mask = sseu->subslice_mask; + user.packed.min_eu_per_subslice = sseu->min_eu_per_subslice; + user.packed.max_eu_per_subslice = sseu->max_eu_per_subslice; + + return user.value; +} diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 57ef5833c427..4ef6a6143f5d 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -80,6 +80,8 @@ struct i915_gem_context; void intel_lr_context_resume(struct drm_i915_private *dev_priv); uint64_t intel_lr_context_descriptor(struct i915_gem_context *ctx, struct intel_engine_cs *engine); +int intel_lr_context_set_sseu(struct i915_gem_context *ctx, u64 value); +u64 intel_lr_context_get_sseu(struct i915_gem_context *ctx); /* Execlists */ int intel_sanitize_enable_execlists(struct drm_i915_private *dev_priv, diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index 6598fb76d2c2..f1e4d0c8c63b 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -1358,6 +1358,17 @@ struct drm_i915_gem_context_param { #define I915_CONTEXT_PARAM_GTT_SIZE 0x3 #define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4 #define I915_CONTEXT_PARAM_BANNABLE 0x5 +#define I915_CONTEXT_PARAM_SSEU 0x6 + __u64 value; +}; + +union drm_i915_gem_context_param_sseu { + struct { + __u8 slice_mask; + __u8 subslice_mask; + __u8 min_eu_per_subslice; + __u8 max_eu_per_subslice; + } packed; __u64 value; };