From patchwork Tue Apr 17 12:27:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 10344905 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 B1F566039A for ; Tue, 17 Apr 2018 12:28:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A7D44286EC for ; Tue, 17 Apr 2018 12:28:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9CB0828A8E; Tue, 17 Apr 2018 12:28:23 +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=-5.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,T_DKIM_INVALID 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 ED31C286EC for ; Tue, 17 Apr 2018 12:28:22 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9BEAE6E45E; Tue, 17 Apr 2018 12:28:19 +0000 (UTC) X-Original-To: Intel-gfx@lists.freedesktop.org Delivered-To: Intel-gfx@lists.freedesktop.org Received: from mail-wr0-x242.google.com (mail-wr0-x242.google.com [IPv6:2a00:1450:400c:c0c::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id C7D0D6E1C0 for ; Tue, 17 Apr 2018 12:28:15 +0000 (UTC) Received: by mail-wr0-x242.google.com with SMTP id v24so17941876wra.8 for ; Tue, 17 Apr 2018 05:28:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ursulin-net.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=f/27qUvN9UDSfek+QvhB/iU0IkDCWh6kBPZ1u18vADI=; b=QhhtckKWkopcXYHs1Iewb/atxp4lku/qOygGOvUaWApi+wW2AwoqRs/8Yin6mJCFwb 0jGztGdQz3LxnVnGJgNDVFQLs/m8YhWojBXOVSk3AHFRysBViz9KRZNbNq27xOwqQSeS jcAdyTpnKgU/2Isqk7AEjCuiMkmIRRAGMjvPbnUCdjBf/JX9XDrhWa+IiA29YPAPHHZu /HKG2bpJTFhiRbJyyALwenpxGBFrAjmLH7G2xT8gRKUMfflQaD7oWgRN98bMIwG6XidF DcxixrIM0h6sx34JsPCPMatQb8gYYwAaM9Cq2rH17TfciucBJ4xq7nYMXtuoPQ48Etdp HBuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=f/27qUvN9UDSfek+QvhB/iU0IkDCWh6kBPZ1u18vADI=; b=fN6PLUj8yVbG/qr/efZuZZE377Y7diMenlSo654yqC9VTS8y0mosXzo2KG2DFAJLNt KptXKKJh6+Gjwda5lSsJqZdC1IBeF7kxd3lXs3pZFe7FKvFMGdXrtQMLdJMHMeBktkph 9IL5m52xIRzl8Qw3X4PRhuHSY/Acxo2aLojfXrWKe+G5vqZro9xFiiv7uArtOPQn1RIM wN0HRrxBKiM7XhN17mrbCx7AxtGJvjOpV9eGMplQNxguS32WnoG9mFPV+uP4D02dNg79 F824ZzXVhY4/97V/+WX8cVTu6BkE30vlSTdPwk662SSwhbh38stRe9Y4sUlJY/l7U6YO 7oMg== X-Gm-Message-State: ALQs6tAx452INY2+pf8ZRjfGnJMeoCuh2foLzhXtQrz2hgmWnEzHqVq7 iwaWI77rryQlDSe+4o+/gXRE8Q== X-Google-Smtp-Source: AIpwx48BJl1f6r5cIR9ePxlWeWGavRa0xCAL+11RMjsDFVIGPhsmW8Ol9NK1JgyBiHn1FEpeJzwDcQ== X-Received: by 10.28.215.136 with SMTP id o130mr925795wmg.41.1523968094374; Tue, 17 Apr 2018 05:28:14 -0700 (PDT) Received: from localhost.localdomain ([95.146.151.144]) by smtp.gmail.com with ESMTPSA id f22sm9226027wmc.3.2018.04.17.05.28.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 17 Apr 2018 05:28:13 -0700 (PDT) From: Tvrtko Ursulin X-Google-Original-From: Tvrtko Ursulin To: igt-dev@lists.freedesktop.org Date: Tue, 17 Apr 2018 13:27:36 +0100 Message-Id: <20180417122736.11603-8-tvrtko.ursulin@linux.intel.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180417122736.11603-1-tvrtko.ursulin@linux.intel.com> References: <20180417122736.11603-1-tvrtko.ursulin@linux.intel.com> Subject: [Intel-gfx] [RFC 7/7] drm/i915: Allow clients to query own per-engine busyness X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Intel-gfx@lists.freedesktop.org, gordon.kelly@intel.com MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP From: Tvrtko Ursulin Some customers want to know how much of the GPU time are their clients using in order to make dynamic load balancing decisions. With the accounting infrastructure in place in the previous patch, we add a new context param (I915_CONTEXT_GET_ENGINES_BUSY) which points to struct drm_i915_context_engines_busy, followed by a variable number of structs drm_i915_context_engine_busy. Userspace needs to provide the number of attached structures in the num_engines fields, as well as set args->size to byte size of the provided buffer. Attached drm_i915_context_engine_busy objects need to have the class and instance of the engine which userspace wants to query busyness of initialized. Kernel will then report accumulated engine busyness as monotonically increasing number of nano-seconds the engine spent executing jobs belonging to this context. v2: * Use intel_context_engine_get_busy_time. * Refactor to only use struct_mutex while initially enabling engine stats. v3: * Fix stats enabling. v4: * Change uAPI to enable querying multiple engines at a time. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Cc: gordon.kelly@intel.com --- This version has been compile tested only until acceptable to everyone. --- drivers/gpu/drm/i915/i915_gem_context.c | 97 ++++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/i915_gem_context.h | 1 + include/uapi/drm/i915_drm.h | 21 +++++++ 3 files changed, 116 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index e9b0940ce7f9..7cfec17b51cf 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -126,6 +126,9 @@ static void i915_gem_context_free(struct i915_gem_context *ctx) for (i = 0; i < I915_NUM_ENGINES; i++) { struct intel_context *ce = &ctx->engine[i]; + if (ctx->i915->engine[i] && ce->stats.enabled) + intel_disable_engine_stats(ctx->i915->engine[i]); + if (!ce->state) continue; @@ -730,11 +733,95 @@ int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, return 0; } +static int +get_engines_busy(struct drm_i915_private *i915, + struct i915_gem_context *ctx, + struct drm_i915_gem_context_param *args) +{ + struct drm_i915_context_engine_busy __user *busy_user; + struct drm_i915_context_engines_busy engines; + struct drm_i915_context_engine_busy busy; + bool mutex = false; + unsigned int i; + int ret = 0; + + if (args->size < sizeof(engines)) + return -EINVAL; + + if (copy_from_user(&engines, u64_to_user_ptr(args->value), + sizeof(engines))) + return -EFAULT; + + if (engines.pad || engines.mbz) + return -EINVAL; + + if (engines.num_engines == 0 || engines.num_engines > I915_NUM_ENGINES) + return -EINVAL; + + if (!access_ok(VERIFY_WRITE, args->value, + sizeof(engines) + engines.num_engines * sizeof(busy))) + return -EFAULT; + + busy_user = (struct drm_i915_context_engine_busy __user *) + ((char __user *)args->value + sizeof(engines)); + + for (i = 0; i < engines.num_engines; i++, busy_user++) { + struct intel_engine_cs *engine; + struct intel_context *ce; + + __copy_from_user(busy_user, &busy, sizeof(busy)); + + if (busy.mbz || busy.flags || busy.busy) { + ret = -EINVAL; + goto out; + } + + engine = intel_engine_lookup_user(i915, + busy.class, busy.instance); + if (!engine) { + ret = -EINVAL; + goto out; + } + + /* Enable stats on first query. */ + ce = &ctx->engine[engine->id]; + if (!READ_ONCE(ce->stats.enabled)) { + /* Grab mutex if need to enable engine stats. */ + if (!mutex) { + ret = i915_mutex_lock_interruptible(&i915->drm); + if (!ret) + break; + mutex = true; + } + + if (!ce->stats.enabled) { + ret = intel_enable_engine_stats(engine); + if (!ret) + goto out; + ce->stats.enabled = true; + } + } + + busy.busy = + ktime_to_ns(intel_context_engine_get_busy_time(ctx, + engine)); + + __copy_to_user(busy_user, &busy, sizeof(busy)); + } + +out: + if (mutex) + mutex_unlock(&i915->drm.struct_mutex); + + return ret; +} + int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { struct drm_i915_file_private *file_priv = file->driver_priv; struct drm_i915_gem_context_param *args = data; + struct drm_i915_private *i915 = to_i915(dev); struct i915_gem_context *ctx; int ret = 0; @@ -753,10 +840,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, case I915_CONTEXT_PARAM_GTT_SIZE: if (ctx->ppgtt) args->value = ctx->ppgtt->base.total; - else if (to_i915(dev)->mm.aliasing_ppgtt) - args->value = to_i915(dev)->mm.aliasing_ppgtt->base.total; + else if (i915->mm.aliasing_ppgtt) + args->value = i915->mm.aliasing_ppgtt->base.total; else - args->value = to_i915(dev)->ggtt.base.total; + args->value = i915->ggtt.base.total; break; case I915_CONTEXT_PARAM_NO_ERROR_CAPTURE: args->value = i915_gem_context_no_error_capture(ctx); @@ -767,6 +854,9 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, case I915_CONTEXT_PARAM_PRIORITY: args->value = ctx->priority; break; + case I915_CONTEXT_GET_ENGINES_BUSY: + ret = get_engines_busy(i915, ctx, args); + break; default: ret = -EINVAL; break; @@ -842,6 +932,7 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data, } break; + case I915_CONTEXT_GET_ENGINES_BUSY: default: ret = -EINVAL; break; diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h index 159223c5fc5f..e468c971a7f5 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.h +++ b/drivers/gpu/drm/i915/i915_gem_context.h @@ -163,6 +163,7 @@ struct i915_gem_context { int pin_count; struct { seqlock_t lock; + bool enabled; bool active; ktime_t start; ktime_t total; diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index c82035b71824..c1bdae484594 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -1460,6 +1460,26 @@ struct drm_i915_gem_userptr { __u32 handle; }; +struct drm_i915_context_engine_busy { + __u8 class; /* in/out */ + __u8 instance; /* in/out */ + + __u16 mbz; + + __u32 flags; /* in/out/mbz */ + + __u64 busy; /* out/mbz */ +}; + +struct drm_i915_context_engines_busy { + __u32 num_engines; /* in */ + __u32 pad; /* mbz */ + + __u64 mbz; + + struct drm_i915_context_engine_busy engines[0]; +}; + struct drm_i915_gem_context_param { __u32 ctx_id; __u32 size; @@ -1473,6 +1493,7 @@ struct drm_i915_gem_context_param { #define I915_CONTEXT_MAX_USER_PRIORITY 1023 /* inclusive */ #define I915_CONTEXT_DEFAULT_PRIORITY 0 #define I915_CONTEXT_MIN_USER_PRIORITY -1023 /* inclusive */ +#define I915_CONTEXT_GET_ENGINES_BUSY 0x7 __u64 value; };