Received: by 2002:a05:6a10:d5a5:0:0:0:0 with SMTP id gn37csp495174pxb; Thu, 30 Sep 2021 10:21:24 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzt5Ch2E+B2dmy4rb5ooAmDWHjjsqv/BhYesP3LMedB+ZVsJhoiFmBCXcrby7tyXc5sOweU X-Received: by 2002:a05:6a00:98e:b0:44b:fa98:6c93 with SMTP id u14-20020a056a00098e00b0044bfa986c93mr3308824pfg.14.1633022484652; Thu, 30 Sep 2021 10:21:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633022484; cv=none; d=google.com; s=arc-20160816; b=puOO5GTfCkJMYGQZmGk8bDM5/P8XIIHX+jZyPrqv7WhqOT2tHcIZFptmL+9jh1FvX4 U+IIkZq3sm0+Arr3l8e5KqZTcgCqu5DhCJMUiHNhepRS60gnDZt7y2+wghVH2IV3yC+Z cvyOjn4xz/sJ0xs4QIVo5u0Z7JB5kJdpejqIcU1VBeo5wg7kwt3ErwjOOwdhioiQAx3q 25c1BBfI6tjruvzTzkL79hTrB2MwtclyuzDtix8lQfvMOTs/apdjRL797IlQUPWztkx2 PSpiExgMuxwM1Onz0qX9lYExc8j8SG18ycrVSWvp3Fyc6luL1dxXNQ9Qy2aJCF3AAuiv 77kw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=tolsgUu6dvKgLFicWWnvMOLk40RPyDJn0wvYIau5gvk=; b=u53pnvgYfLt48w4j7ScnPomYQfBhP3ZvODi+4oCGLn3otAnWD7ktlViGlvLb7V45eQ GDNXk1Vir+kk225t2upb6BBGI+0uLz+aCaJ+5kd3xF3xJzwkYthuRS+A/PjqfNZvyyYS 6afXDiR4LgrYPs4V3zztKhkdX9YMnaWn2Xozul8itt1J7Y7J+rWDh6Tf/noOfZmslloC YXdwK4YgWjqJ9XGlaxLNk102miTkA6VoPPAdbhYfZI8VXHdCSmObVS9WZjj9qYII284+ kl74+bK7A9zXxULYp44EJSzXWg3AOniGDL4R2THuOhUJBKycFNworMcv4MY2tHE9w6xh pVAA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c17si4320843pls.182.2021.09.30.10.21.11; Thu, 30 Sep 2021 10:21:24 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1352503AbhI3RUb (ORCPT + 99 others); Thu, 30 Sep 2021 13:20:31 -0400 Received: from mga05.intel.com ([192.55.52.43]:4357 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1352500AbhI3RUO (ORCPT ); Thu, 30 Sep 2021 13:20:14 -0400 X-IronPort-AV: E=McAfee;i="6200,9189,10123"; a="310787686" X-IronPort-AV: E=Sophos;i="5.85,336,1624345200"; d="scan'208";a="310787686" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2021 10:16:29 -0700 X-IronPort-AV: E=Sophos;i="5.85,336,1624345200"; d="scan'208";a="520489752" Received: from dboland-mobl.ger.corp.intel.com (HELO tursulin-mobl2.home) ([10.213.223.141]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Sep 2021 10:16:28 -0700 From: Tvrtko Ursulin To: Intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Tvrtko Ursulin Subject: [RFC 6/6] drm/i915: Connect task and GPU scheduling priorities Date: Thu, 30 Sep 2021 18:15:52 +0100 Message-Id: <20210930171552.501553-7-tvrtko.ursulin@linux.intel.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210930171552.501553-1-tvrtko.ursulin@linux.intel.com> References: <20210930171552.501553-1-tvrtko.ursulin@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Tvrtko Ursulin Introduce the concept of context nice value which exactly matches the process nice, and also make use of the task user nice notifier chain to be able to dynamically adjust GPU scheduling. Apart from runtime adjustments context also inherits the nice value when created. Context nice is utilised secondary to context priority, only when the latter has been left at the default setting, in order to avoid disturbing any application made choices of low and high (batch processing and maybe latency sensitive compositing). In those cases nice value adjusts the effective priority in the narrow band of -19 to +20 around I915_CONTEXT_DEFAULT_PRIORITY. Opens: * The [-19, +20] range should work well with GuC scheduling since it effectively translates to three available buckets there, but should it perhaps be streched to cover the full [-1023, +1023] range? * Current implementation only has the nice apply to future submissions against the context. Is it worth dealing with already submitted work? I opted to avoid the complication since benefit seems marginal outside of the endless compute workloads (which would probably start up with the correct priority). Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/gem/i915_gem_context.c | 1 + .../drm/i915/gt/intel_execlists_submission.c | 2 +- drivers/gpu/drm/i915/i915_drm_client.c | 38 +++++++++++++++++-- drivers/gpu/drm/i915/i915_drm_client.h | 3 ++ drivers/gpu/drm/i915/i915_request.c | 2 +- drivers/gpu/drm/i915/i915_request.h | 5 +++ drivers/gpu/drm/i915/i915_scheduler.c | 3 +- drivers/gpu/drm/i915/i915_scheduler.h | 14 +++++++ drivers/gpu/drm/i915/i915_scheduler_types.h | 8 ++++ 9 files changed, 69 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index 8d4d687ab1d0..fed0733cb652 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -257,6 +257,7 @@ proto_context_create(struct drm_i915_private *i915, unsigned int flags) if (i915->params.enable_hangcheck) pc->user_flags |= BIT(UCONTEXT_PERSISTENCE); pc->sched.priority = I915_PRIORITY_NORMAL; + pc->sched.nice = task_nice(current); if (flags & I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE) { if (!HAS_EXECLISTS(i915)) { diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c index 7147fe80919e..13c41f1f8ba5 100644 --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c @@ -250,7 +250,7 @@ static struct i915_priolist *to_priolist(struct rb_node *rb) static int rq_prio(const struct i915_request *rq) { - return READ_ONCE(rq->sched.attr.priority); + return i915_request_priority(rq); } static int effective_prio(const struct i915_request *rq) diff --git a/drivers/gpu/drm/i915/i915_drm_client.c b/drivers/gpu/drm/i915/i915_drm_client.c index 82b9636482ef..13ac2311eb84 100644 --- a/drivers/gpu/drm/i915/i915_drm_client.c +++ b/drivers/gpu/drm/i915/i915_drm_client.c @@ -8,9 +8,33 @@ #include #include "i915_drm_client.h" +#include "gem/i915_gem_context.h" #include "i915_gem.h" #include "i915_utils.h" +static int +clients_notify(struct notifier_block *nb, unsigned long val, void *ptr) +{ + struct i915_drm_clients *clients = + container_of(nb, typeof(*clients), prio_notifier); + struct i915_drm_client *client; + unsigned long flags; + + read_lock_irqsave(&clients->lock, flags); + hash_for_each_possible(clients->tasks, client, node, (uintptr_t)ptr) { + struct i915_gem_context *ctx; + + if (client->owner != ptr) + continue; + + list_for_each_entry_rcu(ctx, &client->ctx_list, client_link) + ctx->sched.nice = (int)val; + } + read_unlock_irqrestore(&clients->lock, flags); + + return NOTIFY_DONE; +} + void i915_drm_clients_init(struct i915_drm_clients *clients, struct drm_i915_private *i915) { @@ -21,6 +45,10 @@ void i915_drm_clients_init(struct i915_drm_clients *clients, rwlock_init(&clients->lock); hash_init(clients->tasks); + + memset(&clients->prio_notifier, 0, sizeof(clients->prio_notifier)); + clients->prio_notifier.notifier_call = clients_notify; + register_user_nice_notifier(&clients->prio_notifier); } struct i915_drm_client *i915_drm_client_add(struct i915_drm_clients *clients) @@ -63,9 +91,9 @@ void __i915_drm_client_free(struct kref *kref) struct xarray *xa = &clients->xarray; unsigned long flags; - write_lock(&clients->lock); + write_lock_irq(&clients->lock); hash_del(&client->node); - write_unlock(&clients->lock); + write_unlock_irq(&clients->lock); xa_lock_irqsave(xa, flags); __xa_erase(xa, client->id); @@ -75,6 +103,8 @@ void __i915_drm_client_free(struct kref *kref) void i915_drm_clients_fini(struct i915_drm_clients *clients) { + unregister_user_nice_notifier(&clients->prio_notifier); + GEM_BUG_ON(!xa_empty(&clients->xarray)); xa_destroy(&clients->xarray); } @@ -88,12 +118,12 @@ void i915_drm_client_update_owner(struct i915_drm_client *client, return; clients = client->clients; - write_lock(&clients->lock); + write_lock_irq(&clients->lock); if (READ_ONCE(client->owner) != owner) { if (client->owner) hash_del(&client->node); client->owner = owner; hash_add(clients->tasks, &client->node, (uintptr_t)owner); } - write_unlock(&clients->lock); + write_unlock_irq(&clients->lock); } diff --git a/drivers/gpu/drm/i915/i915_drm_client.h b/drivers/gpu/drm/i915/i915_drm_client.h index 42fd79f0558a..dda26aa42ac9 100644 --- a/drivers/gpu/drm/i915/i915_drm_client.h +++ b/drivers/gpu/drm/i915/i915_drm_client.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,8 @@ struct i915_drm_clients { rwlock_t lock; DECLARE_HASHTABLE(tasks, 6); + + struct notifier_block prio_notifier; }; struct i915_drm_client { diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 79da5eca60af..a8c6f3a64895 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -1930,7 +1930,7 @@ static int print_sched_attr(const struct i915_sched_attr *attr, return x; x += snprintf(buf + x, len - x, - " prio=%d", attr->priority); + " prio=%d nice=%d", attr->priority, attr->nice); return x; } diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index 7bd9ed20623e..c2c4c344837e 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -399,6 +399,11 @@ long i915_request_wait(struct i915_request *rq, #define I915_WAIT_PRIORITY BIT(1) /* small priority bump for the request */ #define I915_WAIT_ALL BIT(2) /* used by i915_gem_object_wait() */ +static inline int i915_request_priority(const struct i915_request *rq) +{ + return i915_sched_attr_priority(&rq->sched.attr); +} + void i915_request_show(struct drm_printer *m, const struct i915_request *rq, const char *prefix, diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c index 762127dd56c5..3883511f90ea 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.c +++ b/drivers/gpu/drm/i915/i915_scheduler.c @@ -155,7 +155,7 @@ lock_sched_engine(struct i915_sched_node *node, static void __i915_schedule(struct i915_sched_node *node, const struct i915_sched_attr *attr) { - const int prio = max(attr->priority, node->attr.priority); + const int prio = max(i915_sched_attr_priority(attr), node->attr.priority); struct i915_sched_engine *sched_engine; struct i915_dependency *dep, *p; struct i915_dependency stack; @@ -305,6 +305,7 @@ void i915_sched_node_init(struct i915_sched_node *node) void i915_sched_node_reinit(struct i915_sched_node *node) { node->attr.priority = I915_PRIORITY_INVALID; + node->attr.nice = 0; node->semaphores = 0; node->flags = 0; diff --git a/drivers/gpu/drm/i915/i915_scheduler.h b/drivers/gpu/drm/i915/i915_scheduler.h index 0b9b86af6c7f..75ccc9f55d14 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.h +++ b/drivers/gpu/drm/i915/i915_scheduler.h @@ -38,6 +38,20 @@ void i915_sched_node_fini(struct i915_sched_node *node); void i915_schedule(struct i915_request *request, const struct i915_sched_attr *attr); +static inline int i915_sched_attr_priority(const struct i915_sched_attr *attr) +{ + int prio = attr->priority; + + /* + * Only allow I915_CONTEXT_DEFAULT_PRIORITY to be affected by the + * nice setting. + */ + if (!prio) + prio = -attr->nice; + + return prio; +} + struct list_head * i915_sched_lookup_priolist(struct i915_sched_engine *sched_engine, int prio); diff --git a/drivers/gpu/drm/i915/i915_scheduler_types.h b/drivers/gpu/drm/i915/i915_scheduler_types.h index b0a1b58c7893..34124cfc93e9 100644 --- a/drivers/gpu/drm/i915/i915_scheduler_types.h +++ b/drivers/gpu/drm/i915/i915_scheduler_types.h @@ -29,6 +29,14 @@ struct i915_sched_attr { * The &drm_i915_private.kernel_context is assigned the lowest priority. */ int priority; + + /** + * @nice: context nice level + * + * Nice level follows the CPU scheduler nice value as set for the + * process owning the GPU context. + */ + int nice; }; /* -- 2.30.2