From: Matthew Brost <matthew.brost@intel.com>
To: dri-devel@lists.freedesktop.org, intel-xe@lists.freedesktop.org
Cc: robdclark@chromium.org, sarah.walker@imgtec.com,
ketil.johnsen@arm.com, frank.binns@imgtec.com,
Liviu.Dudau@arm.com, luben.tuikov@amd.com, lina@asahilina.net,
donald.robson@imgtec.com, daniel@ffwll.ch,
boris.brezillon@collabora.com, airlied@gmail.com,
christian.koenig@amd.com, faith.ekstrand@collabora.com
Subject: [Intel-xe] [PATCH v2 3/9] drm/sched: Add DRM_SCHED_POLICY_SINGLE_ENTITY scheduling policy
Date: Thu, 10 Aug 2023 19:31:31 -0700 [thread overview]
Message-ID: <20230811023137.659037-4-matthew.brost@intel.com> (raw)
In-Reply-To: <20230811023137.659037-1-matthew.brost@intel.com>
DRM_SCHED_POLICY_SINGLE_ENTITY creates a 1 to 1 relationship between
scheduler and entity. No priorities or run queue used in this mode.
Intended for devices with firmware schedulers.
v2:
- Drop sched / rq union (Luben)
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
---
drivers/gpu/drm/scheduler/sched_entity.c | 69 ++++++++++++++++++------
drivers/gpu/drm/scheduler/sched_fence.c | 2 +-
drivers/gpu/drm/scheduler/sched_main.c | 63 +++++++++++++++++++---
include/drm/gpu_scheduler.h | 8 +++
4 files changed, 119 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
index 65a972b52eda..1dec97caaba3 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -83,6 +83,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
memset(entity, 0, sizeof(struct drm_sched_entity));
INIT_LIST_HEAD(&entity->list);
entity->rq = NULL;
+ entity->single_sched = NULL;
entity->guilty = guilty;
entity->num_sched_list = num_sched_list;
entity->priority = priority;
@@ -90,8 +91,17 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
RCU_INIT_POINTER(entity->last_scheduled, NULL);
RB_CLEAR_NODE(&entity->rb_tree_node);
- if(num_sched_list)
- entity->rq = &sched_list[0]->sched_rq[entity->priority];
+ if (num_sched_list) {
+ if (sched_list[0]->sched_policy !=
+ DRM_SCHED_POLICY_SINGLE_ENTITY) {
+ entity->rq = &sched_list[0]->sched_rq[entity->priority];
+ } else {
+ if (num_sched_list != 1 || sched_list[0]->single_entity)
+ return -EINVAL;
+ sched_list[0]->single_entity = entity;
+ entity->single_sched = sched_list[0];
+ }
+ }
init_completion(&entity->entity_idle);
@@ -124,7 +134,8 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity,
struct drm_gpu_scheduler **sched_list,
unsigned int num_sched_list)
{
- WARN_ON(!num_sched_list || !sched_list);
+ WARN_ON(!num_sched_list || !sched_list ||
+ !!entity->single_sched);
entity->sched_list = sched_list;
entity->num_sched_list = num_sched_list;
@@ -231,13 +242,15 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
{
struct drm_sched_job *job;
struct dma_fence *prev;
+ bool single_entity = !!entity->single_sched;
- if (!entity->rq)
+ if (!entity->rq && !single_entity)
return;
spin_lock(&entity->rq_lock);
entity->stopped = true;
- drm_sched_rq_remove_entity(entity->rq, entity);
+ if (!single_entity)
+ drm_sched_rq_remove_entity(entity->rq, entity);
spin_unlock(&entity->rq_lock);
/* Make sure this entity is not used by the scheduler at the moment */
@@ -259,6 +272,20 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
dma_fence_put(prev);
}
+/**
+ * drm_sched_entity_to_scheduler - Schedule entity to GPU scheduler
+ * @entity: scheduler entity
+ *
+ * Returns GPU scheduler for the entity
+ */
+struct drm_gpu_scheduler *
+drm_sched_entity_to_scheduler(struct drm_sched_entity *entity)
+{
+ bool single_entity = !!entity->single_sched;
+
+ return single_entity ? entity->single_sched : entity->rq->sched;
+}
+
/**
* drm_sched_entity_flush - Flush a context entity
*
@@ -276,11 +303,12 @@ long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout)
struct drm_gpu_scheduler *sched;
struct task_struct *last_user;
long ret = timeout;
+ bool single_entity = !!entity->single_sched;
- if (!entity->rq)
+ if (!entity->rq && !single_entity)
return 0;
- sched = entity->rq->sched;
+ sched = drm_sched_entity_to_scheduler(entity);
/**
* The client will not queue more IBs during this fini, consume existing
* queued IBs or discard them on SIGKILL
@@ -373,7 +401,7 @@ static void drm_sched_entity_wakeup(struct dma_fence *f,
container_of(cb, struct drm_sched_entity, cb);
drm_sched_entity_clear_dep(f, cb);
- drm_sched_wakeup_if_can_queue(entity->rq->sched);
+ drm_sched_wakeup_if_can_queue(drm_sched_entity_to_scheduler(entity));
}
/**
@@ -387,6 +415,8 @@ static void drm_sched_entity_wakeup(struct dma_fence *f,
void drm_sched_entity_set_priority(struct drm_sched_entity *entity,
enum drm_sched_priority priority)
{
+ WARN_ON(!!entity->single_sched);
+
spin_lock(&entity->rq_lock);
entity->priority = priority;
spin_unlock(&entity->rq_lock);
@@ -399,7 +429,7 @@ EXPORT_SYMBOL(drm_sched_entity_set_priority);
*/
static bool drm_sched_entity_add_dependency_cb(struct drm_sched_entity *entity)
{
- struct drm_gpu_scheduler *sched = entity->rq->sched;
+ struct drm_gpu_scheduler *sched = drm_sched_entity_to_scheduler(entity);
struct dma_fence *fence = entity->dependency;
struct drm_sched_fence *s_fence;
@@ -501,7 +531,8 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
* Update the entity's location in the min heap according to
* the timestamp of the next job, if any.
*/
- if (entity->rq->sched->sched_policy == DRM_SCHED_POLICY_FIFO) {
+ if (drm_sched_entity_to_scheduler(entity)->sched_policy ==
+ DRM_SCHED_POLICY_FIFO) {
struct drm_sched_job *next;
next = to_drm_sched_job(spsc_queue_peek(&entity->job_queue));
@@ -524,6 +555,8 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
struct drm_gpu_scheduler *sched;
struct drm_sched_rq *rq;
+ WARN_ON(!!entity->single_sched);
+
/* single possible engine and already selected */
if (!entity->sched_list)
return;
@@ -573,12 +606,13 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
{
struct drm_sched_entity *entity = sched_job->entity;
- bool first, fifo = entity->rq->sched->sched_policy ==
- DRM_SCHED_POLICY_FIFO;
+ bool single_entity = !!entity->single_sched;
+ bool first;
ktime_t submit_ts;
trace_drm_sched_job(sched_job, entity);
- atomic_inc(entity->rq->sched->score);
+ if (!single_entity)
+ atomic_inc(entity->rq->sched->score);
WRITE_ONCE(entity->last_user, current->group_leader);
/*
@@ -591,6 +625,10 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
/* first job wakes up scheduler */
if (first) {
+ struct drm_gpu_scheduler *sched =
+ drm_sched_entity_to_scheduler(entity);
+ bool fifo = sched->sched_policy == DRM_SCHED_POLICY_FIFO;
+
/* Add the entity to the run queue */
spin_lock(&entity->rq_lock);
if (entity->stopped) {
@@ -600,13 +638,14 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
return;
}
- drm_sched_rq_add_entity(entity->rq, entity);
+ if (!single_entity)
+ drm_sched_rq_add_entity(entity->rq, entity);
spin_unlock(&entity->rq_lock);
if (fifo)
drm_sched_rq_update_fifo(entity, submit_ts);
- drm_sched_wakeup_if_can_queue(entity->rq->sched);
+ drm_sched_wakeup_if_can_queue(sched);
}
}
EXPORT_SYMBOL(drm_sched_entity_push_job);
diff --git a/drivers/gpu/drm/scheduler/sched_fence.c b/drivers/gpu/drm/scheduler/sched_fence.c
index 06cedfe4b486..f6b926f5e188 100644
--- a/drivers/gpu/drm/scheduler/sched_fence.c
+++ b/drivers/gpu/drm/scheduler/sched_fence.c
@@ -225,7 +225,7 @@ void drm_sched_fence_init(struct drm_sched_fence *fence,
{
unsigned seq;
- fence->sched = entity->rq->sched;
+ fence->sched = drm_sched_entity_to_scheduler(entity);
seq = atomic_inc_return(&entity->fence_seq);
dma_fence_init(&fence->scheduled, &drm_sched_fence_ops_scheduled,
&fence->lock, entity->fence_context, seq);
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
index 545d5298c086..cede47afc800 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -32,7 +32,8 @@
* backend operations to the scheduler like submitting a job to hardware run queue,
* returning the dependencies of a job etc.
*
- * The organisation of the scheduler is the following:
+ * The organisation of the scheduler is the following for scheduling policies
+ * DRM_SCHED_POLICY_RR and DRM_SCHED_POLICY_FIFO:
*
* 1. Each hw run queue has one scheduler
* 2. Each scheduler has multiple run queues with different priorities
@@ -43,6 +44,23 @@
*
* The jobs in a entity are always scheduled in the order that they were pushed.
*
+ * The organisation of the scheduler is the following for scheduling policy
+ * DRM_SCHED_POLICY_SINGLE_ENTITY:
+ *
+ * 1. One to one relationship between scheduler and entity
+ * 2. No priorities implemented per scheduler (single job queue)
+ * 3. No run queues in scheduler rather jobs are directly dequeued from entity
+ * 4. The entity maintains a queue of jobs that will be scheduled on the
+ * hardware
+ *
+ * The jobs in a entity are always scheduled in the order that they were pushed
+ * regardless of scheduling policy.
+ *
+ * A policy of DRM_SCHED_POLICY_RR or DRM_SCHED_POLICY_FIFO is expected to used
+ * when the KMD is scheduling directly on the hardware while a scheduling policy
+ * of DRM_SCHED_POLICY_SINGLE_ENTITY is expected to be used when there is a
+ * firmware scheduler.
+ *
* Note that once a job was taken from the entities queue and pushed to the
* hardware, i.e. the pending queue, the entity must not be referenced anymore
* through the jobs entity pointer.
@@ -96,6 +114,8 @@ static inline void drm_sched_rq_remove_fifo_locked(struct drm_sched_entity *enti
void drm_sched_rq_update_fifo(struct drm_sched_entity *entity, ktime_t ts)
{
+ WARN_ON(!!entity->single_sched);
+
/*
* Both locks need to be grabbed, one to protect from entity->rq change
* for entity from within concurrent drm_sched_entity_select_rq and the
@@ -126,6 +146,8 @@ void drm_sched_rq_update_fifo(struct drm_sched_entity *entity, ktime_t ts)
static void drm_sched_rq_init(struct drm_gpu_scheduler *sched,
struct drm_sched_rq *rq)
{
+ WARN_ON(sched->sched_policy == DRM_SCHED_POLICY_SINGLE_ENTITY);
+
spin_lock_init(&rq->lock);
INIT_LIST_HEAD(&rq->entities);
rq->rb_tree_root = RB_ROOT_CACHED;
@@ -144,6 +166,8 @@ static void drm_sched_rq_init(struct drm_gpu_scheduler *sched,
void drm_sched_rq_add_entity(struct drm_sched_rq *rq,
struct drm_sched_entity *entity)
{
+ WARN_ON(!!entity->single_sched);
+
if (!list_empty(&entity->list))
return;
@@ -166,6 +190,8 @@ void drm_sched_rq_add_entity(struct drm_sched_rq *rq,
void drm_sched_rq_remove_entity(struct drm_sched_rq *rq,
struct drm_sched_entity *entity)
{
+ WARN_ON(!!entity->single_sched);
+
if (list_empty(&entity->list))
return;
@@ -641,7 +667,7 @@ int drm_sched_job_init(struct drm_sched_job *job,
struct drm_sched_entity *entity,
void *owner)
{
- if (!entity->rq)
+ if (!entity->rq && !entity->single_sched)
return -ENOENT;
job->entity = entity;
@@ -674,13 +700,16 @@ void drm_sched_job_arm(struct drm_sched_job *job)
{
struct drm_gpu_scheduler *sched;
struct drm_sched_entity *entity = job->entity;
+ bool single_entity = !!entity->single_sched;
BUG_ON(!entity);
- drm_sched_entity_select_rq(entity);
- sched = entity->rq->sched;
+ if (!single_entity)
+ drm_sched_entity_select_rq(entity);
+ sched = drm_sched_entity_to_scheduler(entity);
job->sched = sched;
- job->s_priority = entity->rq - sched->sched_rq;
+ if (!single_entity)
+ job->s_priority = entity->rq - sched->sched_rq;
job->id = atomic64_inc_return(&sched->job_id_count);
drm_sched_fence_init(job->s_fence, job->entity);
@@ -896,6 +925,13 @@ drm_sched_select_entity(struct drm_gpu_scheduler *sched)
if (!drm_sched_can_queue(sched))
return NULL;
+ if (sched->single_entity) {
+ if (drm_sched_entity_is_ready(sched->single_entity))
+ return sched->single_entity;
+
+ return NULL;
+ }
+
/* Kernel run queue has higher priority than normal run queue*/
for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {
entity = sched->sched_policy == DRM_SCHED_POLICY_FIFO ?
@@ -1091,6 +1127,7 @@ int drm_sched_init(struct drm_gpu_scheduler *sched,
return -EINVAL;
sched->ops = ops;
+ sched->single_entity = NULL;
sched->hw_submission_limit = hw_submission;
sched->name = name;
sched->submit_wq = submit_wq ? : system_wq;
@@ -1103,7 +1140,9 @@ int drm_sched_init(struct drm_gpu_scheduler *sched,
sched->sched_policy = default_drm_sched_policy;
else
sched->sched_policy = sched_policy;
- for (i = DRM_SCHED_PRIORITY_MIN; i < DRM_SCHED_PRIORITY_COUNT; i++)
+ for (i = DRM_SCHED_PRIORITY_MIN; sched_policy !=
+ DRM_SCHED_POLICY_SINGLE_ENTITY && i < DRM_SCHED_PRIORITY_COUNT;
+ i++)
drm_sched_rq_init(sched, &sched->sched_rq[i]);
init_waitqueue_head(&sched->job_scheduled);
@@ -1135,7 +1174,15 @@ void drm_sched_fini(struct drm_gpu_scheduler *sched)
drm_sched_submit_stop(sched);
- for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {
+ if (sched->single_entity) {
+ spin_lock(&sched->single_entity->rq_lock);
+ sched->single_entity->stopped = true;
+ spin_unlock(&sched->single_entity->rq_lock);
+ }
+
+ for (i = DRM_SCHED_PRIORITY_COUNT - 1; sched->sched_policy !=
+ DRM_SCHED_POLICY_SINGLE_ENTITY && i >= DRM_SCHED_PRIORITY_MIN;
+ i--) {
struct drm_sched_rq *rq = &sched->sched_rq[i];
spin_lock(&rq->lock);
@@ -1176,6 +1223,8 @@ void drm_sched_increase_karma(struct drm_sched_job *bad)
struct drm_sched_entity *entity;
struct drm_gpu_scheduler *sched = bad->sched;
+ WARN_ON(sched->sched_policy == DRM_SCHED_POLICY_SINGLE_ENTITY);
+
/* don't change @bad's karma if it's from KERNEL RQ,
* because sometimes GPU hang would cause kernel jobs (like VM updating jobs)
* corrupt but keep in mind that kernel jobs always considered good.
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index 897d52a4ff4f..04eec2d7635f 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -79,6 +79,7 @@ enum drm_sched_policy {
DRM_SCHED_POLICY_DEFAULT,
DRM_SCHED_POLICY_RR,
DRM_SCHED_POLICY_FIFO,
+ DRM_SCHED_POLICY_SINGLE_ENTITY,
DRM_SCHED_POLICY_COUNT,
};
@@ -112,6 +113,9 @@ struct drm_sched_entity {
*/
struct drm_sched_rq *rq;
+ /** @single_sched: Single scheduler */
+ struct drm_gpu_scheduler *single_sched;
+
/**
* @sched_list:
*
@@ -473,6 +477,7 @@ struct drm_sched_backend_ops {
* struct drm_gpu_scheduler - scheduler instance-specific data
*
* @ops: backend operations provided by the driver.
+ * @single_entity: Single entity for the scheduler
* @hw_submission_limit: the max size of the hardware queue.
* @timeout: the time after which a job is removed from the scheduler.
* @name: name of the ring for which this scheduler is being used.
@@ -503,6 +508,7 @@ struct drm_sched_backend_ops {
*/
struct drm_gpu_scheduler {
const struct drm_sched_backend_ops *ops;
+ struct drm_sched_entity *single_entity;
uint32_t hw_submission_limit;
long timeout;
const char *name;
@@ -585,6 +591,8 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
struct drm_gpu_scheduler **sched_list,
unsigned int num_sched_list,
atomic_t *guilty);
+struct drm_gpu_scheduler *
+drm_sched_entity_to_scheduler(struct drm_sched_entity *entity);
long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout);
void drm_sched_entity_fini(struct drm_sched_entity *entity);
void drm_sched_entity_destroy(struct drm_sched_entity *entity);
--
2.34.1
WARNING: multiple messages have this Message-ID (diff)
From: Matthew Brost <matthew.brost@intel.com>
To: dri-devel@lists.freedesktop.org, intel-xe@lists.freedesktop.org
Cc: robdclark@chromium.org, thomas.hellstrom@linux.intel.com,
Matthew Brost <matthew.brost@intel.com>,
sarah.walker@imgtec.com, ketil.johnsen@arm.com,
Liviu.Dudau@arm.com, luben.tuikov@amd.com, lina@asahilina.net,
donald.robson@imgtec.com, boris.brezillon@collabora.com,
christian.koenig@amd.com, faith.ekstrand@collabora.com
Subject: [PATCH v2 3/9] drm/sched: Add DRM_SCHED_POLICY_SINGLE_ENTITY scheduling policy
Date: Thu, 10 Aug 2023 19:31:31 -0700 [thread overview]
Message-ID: <20230811023137.659037-4-matthew.brost@intel.com> (raw)
In-Reply-To: <20230811023137.659037-1-matthew.brost@intel.com>
DRM_SCHED_POLICY_SINGLE_ENTITY creates a 1 to 1 relationship between
scheduler and entity. No priorities or run queue used in this mode.
Intended for devices with firmware schedulers.
v2:
- Drop sched / rq union (Luben)
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
---
drivers/gpu/drm/scheduler/sched_entity.c | 69 ++++++++++++++++++------
drivers/gpu/drm/scheduler/sched_fence.c | 2 +-
drivers/gpu/drm/scheduler/sched_main.c | 63 +++++++++++++++++++---
include/drm/gpu_scheduler.h | 8 +++
4 files changed, 119 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
index 65a972b52eda..1dec97caaba3 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -83,6 +83,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
memset(entity, 0, sizeof(struct drm_sched_entity));
INIT_LIST_HEAD(&entity->list);
entity->rq = NULL;
+ entity->single_sched = NULL;
entity->guilty = guilty;
entity->num_sched_list = num_sched_list;
entity->priority = priority;
@@ -90,8 +91,17 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
RCU_INIT_POINTER(entity->last_scheduled, NULL);
RB_CLEAR_NODE(&entity->rb_tree_node);
- if(num_sched_list)
- entity->rq = &sched_list[0]->sched_rq[entity->priority];
+ if (num_sched_list) {
+ if (sched_list[0]->sched_policy !=
+ DRM_SCHED_POLICY_SINGLE_ENTITY) {
+ entity->rq = &sched_list[0]->sched_rq[entity->priority];
+ } else {
+ if (num_sched_list != 1 || sched_list[0]->single_entity)
+ return -EINVAL;
+ sched_list[0]->single_entity = entity;
+ entity->single_sched = sched_list[0];
+ }
+ }
init_completion(&entity->entity_idle);
@@ -124,7 +134,8 @@ void drm_sched_entity_modify_sched(struct drm_sched_entity *entity,
struct drm_gpu_scheduler **sched_list,
unsigned int num_sched_list)
{
- WARN_ON(!num_sched_list || !sched_list);
+ WARN_ON(!num_sched_list || !sched_list ||
+ !!entity->single_sched);
entity->sched_list = sched_list;
entity->num_sched_list = num_sched_list;
@@ -231,13 +242,15 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
{
struct drm_sched_job *job;
struct dma_fence *prev;
+ bool single_entity = !!entity->single_sched;
- if (!entity->rq)
+ if (!entity->rq && !single_entity)
return;
spin_lock(&entity->rq_lock);
entity->stopped = true;
- drm_sched_rq_remove_entity(entity->rq, entity);
+ if (!single_entity)
+ drm_sched_rq_remove_entity(entity->rq, entity);
spin_unlock(&entity->rq_lock);
/* Make sure this entity is not used by the scheduler at the moment */
@@ -259,6 +272,20 @@ static void drm_sched_entity_kill(struct drm_sched_entity *entity)
dma_fence_put(prev);
}
+/**
+ * drm_sched_entity_to_scheduler - Schedule entity to GPU scheduler
+ * @entity: scheduler entity
+ *
+ * Returns GPU scheduler for the entity
+ */
+struct drm_gpu_scheduler *
+drm_sched_entity_to_scheduler(struct drm_sched_entity *entity)
+{
+ bool single_entity = !!entity->single_sched;
+
+ return single_entity ? entity->single_sched : entity->rq->sched;
+}
+
/**
* drm_sched_entity_flush - Flush a context entity
*
@@ -276,11 +303,12 @@ long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout)
struct drm_gpu_scheduler *sched;
struct task_struct *last_user;
long ret = timeout;
+ bool single_entity = !!entity->single_sched;
- if (!entity->rq)
+ if (!entity->rq && !single_entity)
return 0;
- sched = entity->rq->sched;
+ sched = drm_sched_entity_to_scheduler(entity);
/**
* The client will not queue more IBs during this fini, consume existing
* queued IBs or discard them on SIGKILL
@@ -373,7 +401,7 @@ static void drm_sched_entity_wakeup(struct dma_fence *f,
container_of(cb, struct drm_sched_entity, cb);
drm_sched_entity_clear_dep(f, cb);
- drm_sched_wakeup_if_can_queue(entity->rq->sched);
+ drm_sched_wakeup_if_can_queue(drm_sched_entity_to_scheduler(entity));
}
/**
@@ -387,6 +415,8 @@ static void drm_sched_entity_wakeup(struct dma_fence *f,
void drm_sched_entity_set_priority(struct drm_sched_entity *entity,
enum drm_sched_priority priority)
{
+ WARN_ON(!!entity->single_sched);
+
spin_lock(&entity->rq_lock);
entity->priority = priority;
spin_unlock(&entity->rq_lock);
@@ -399,7 +429,7 @@ EXPORT_SYMBOL(drm_sched_entity_set_priority);
*/
static bool drm_sched_entity_add_dependency_cb(struct drm_sched_entity *entity)
{
- struct drm_gpu_scheduler *sched = entity->rq->sched;
+ struct drm_gpu_scheduler *sched = drm_sched_entity_to_scheduler(entity);
struct dma_fence *fence = entity->dependency;
struct drm_sched_fence *s_fence;
@@ -501,7 +531,8 @@ struct drm_sched_job *drm_sched_entity_pop_job(struct drm_sched_entity *entity)
* Update the entity's location in the min heap according to
* the timestamp of the next job, if any.
*/
- if (entity->rq->sched->sched_policy == DRM_SCHED_POLICY_FIFO) {
+ if (drm_sched_entity_to_scheduler(entity)->sched_policy ==
+ DRM_SCHED_POLICY_FIFO) {
struct drm_sched_job *next;
next = to_drm_sched_job(spsc_queue_peek(&entity->job_queue));
@@ -524,6 +555,8 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
struct drm_gpu_scheduler *sched;
struct drm_sched_rq *rq;
+ WARN_ON(!!entity->single_sched);
+
/* single possible engine and already selected */
if (!entity->sched_list)
return;
@@ -573,12 +606,13 @@ void drm_sched_entity_select_rq(struct drm_sched_entity *entity)
void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
{
struct drm_sched_entity *entity = sched_job->entity;
- bool first, fifo = entity->rq->sched->sched_policy ==
- DRM_SCHED_POLICY_FIFO;
+ bool single_entity = !!entity->single_sched;
+ bool first;
ktime_t submit_ts;
trace_drm_sched_job(sched_job, entity);
- atomic_inc(entity->rq->sched->score);
+ if (!single_entity)
+ atomic_inc(entity->rq->sched->score);
WRITE_ONCE(entity->last_user, current->group_leader);
/*
@@ -591,6 +625,10 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
/* first job wakes up scheduler */
if (first) {
+ struct drm_gpu_scheduler *sched =
+ drm_sched_entity_to_scheduler(entity);
+ bool fifo = sched->sched_policy == DRM_SCHED_POLICY_FIFO;
+
/* Add the entity to the run queue */
spin_lock(&entity->rq_lock);
if (entity->stopped) {
@@ -600,13 +638,14 @@ void drm_sched_entity_push_job(struct drm_sched_job *sched_job)
return;
}
- drm_sched_rq_add_entity(entity->rq, entity);
+ if (!single_entity)
+ drm_sched_rq_add_entity(entity->rq, entity);
spin_unlock(&entity->rq_lock);
if (fifo)
drm_sched_rq_update_fifo(entity, submit_ts);
- drm_sched_wakeup_if_can_queue(entity->rq->sched);
+ drm_sched_wakeup_if_can_queue(sched);
}
}
EXPORT_SYMBOL(drm_sched_entity_push_job);
diff --git a/drivers/gpu/drm/scheduler/sched_fence.c b/drivers/gpu/drm/scheduler/sched_fence.c
index 06cedfe4b486..f6b926f5e188 100644
--- a/drivers/gpu/drm/scheduler/sched_fence.c
+++ b/drivers/gpu/drm/scheduler/sched_fence.c
@@ -225,7 +225,7 @@ void drm_sched_fence_init(struct drm_sched_fence *fence,
{
unsigned seq;
- fence->sched = entity->rq->sched;
+ fence->sched = drm_sched_entity_to_scheduler(entity);
seq = atomic_inc_return(&entity->fence_seq);
dma_fence_init(&fence->scheduled, &drm_sched_fence_ops_scheduled,
&fence->lock, entity->fence_context, seq);
diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
index 545d5298c086..cede47afc800 100644
--- a/drivers/gpu/drm/scheduler/sched_main.c
+++ b/drivers/gpu/drm/scheduler/sched_main.c
@@ -32,7 +32,8 @@
* backend operations to the scheduler like submitting a job to hardware run queue,
* returning the dependencies of a job etc.
*
- * The organisation of the scheduler is the following:
+ * The organisation of the scheduler is the following for scheduling policies
+ * DRM_SCHED_POLICY_RR and DRM_SCHED_POLICY_FIFO:
*
* 1. Each hw run queue has one scheduler
* 2. Each scheduler has multiple run queues with different priorities
@@ -43,6 +44,23 @@
*
* The jobs in a entity are always scheduled in the order that they were pushed.
*
+ * The organisation of the scheduler is the following for scheduling policy
+ * DRM_SCHED_POLICY_SINGLE_ENTITY:
+ *
+ * 1. One to one relationship between scheduler and entity
+ * 2. No priorities implemented per scheduler (single job queue)
+ * 3. No run queues in scheduler rather jobs are directly dequeued from entity
+ * 4. The entity maintains a queue of jobs that will be scheduled on the
+ * hardware
+ *
+ * The jobs in a entity are always scheduled in the order that they were pushed
+ * regardless of scheduling policy.
+ *
+ * A policy of DRM_SCHED_POLICY_RR or DRM_SCHED_POLICY_FIFO is expected to used
+ * when the KMD is scheduling directly on the hardware while a scheduling policy
+ * of DRM_SCHED_POLICY_SINGLE_ENTITY is expected to be used when there is a
+ * firmware scheduler.
+ *
* Note that once a job was taken from the entities queue and pushed to the
* hardware, i.e. the pending queue, the entity must not be referenced anymore
* through the jobs entity pointer.
@@ -96,6 +114,8 @@ static inline void drm_sched_rq_remove_fifo_locked(struct drm_sched_entity *enti
void drm_sched_rq_update_fifo(struct drm_sched_entity *entity, ktime_t ts)
{
+ WARN_ON(!!entity->single_sched);
+
/*
* Both locks need to be grabbed, one to protect from entity->rq change
* for entity from within concurrent drm_sched_entity_select_rq and the
@@ -126,6 +146,8 @@ void drm_sched_rq_update_fifo(struct drm_sched_entity *entity, ktime_t ts)
static void drm_sched_rq_init(struct drm_gpu_scheduler *sched,
struct drm_sched_rq *rq)
{
+ WARN_ON(sched->sched_policy == DRM_SCHED_POLICY_SINGLE_ENTITY);
+
spin_lock_init(&rq->lock);
INIT_LIST_HEAD(&rq->entities);
rq->rb_tree_root = RB_ROOT_CACHED;
@@ -144,6 +166,8 @@ static void drm_sched_rq_init(struct drm_gpu_scheduler *sched,
void drm_sched_rq_add_entity(struct drm_sched_rq *rq,
struct drm_sched_entity *entity)
{
+ WARN_ON(!!entity->single_sched);
+
if (!list_empty(&entity->list))
return;
@@ -166,6 +190,8 @@ void drm_sched_rq_add_entity(struct drm_sched_rq *rq,
void drm_sched_rq_remove_entity(struct drm_sched_rq *rq,
struct drm_sched_entity *entity)
{
+ WARN_ON(!!entity->single_sched);
+
if (list_empty(&entity->list))
return;
@@ -641,7 +667,7 @@ int drm_sched_job_init(struct drm_sched_job *job,
struct drm_sched_entity *entity,
void *owner)
{
- if (!entity->rq)
+ if (!entity->rq && !entity->single_sched)
return -ENOENT;
job->entity = entity;
@@ -674,13 +700,16 @@ void drm_sched_job_arm(struct drm_sched_job *job)
{
struct drm_gpu_scheduler *sched;
struct drm_sched_entity *entity = job->entity;
+ bool single_entity = !!entity->single_sched;
BUG_ON(!entity);
- drm_sched_entity_select_rq(entity);
- sched = entity->rq->sched;
+ if (!single_entity)
+ drm_sched_entity_select_rq(entity);
+ sched = drm_sched_entity_to_scheduler(entity);
job->sched = sched;
- job->s_priority = entity->rq - sched->sched_rq;
+ if (!single_entity)
+ job->s_priority = entity->rq - sched->sched_rq;
job->id = atomic64_inc_return(&sched->job_id_count);
drm_sched_fence_init(job->s_fence, job->entity);
@@ -896,6 +925,13 @@ drm_sched_select_entity(struct drm_gpu_scheduler *sched)
if (!drm_sched_can_queue(sched))
return NULL;
+ if (sched->single_entity) {
+ if (drm_sched_entity_is_ready(sched->single_entity))
+ return sched->single_entity;
+
+ return NULL;
+ }
+
/* Kernel run queue has higher priority than normal run queue*/
for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {
entity = sched->sched_policy == DRM_SCHED_POLICY_FIFO ?
@@ -1091,6 +1127,7 @@ int drm_sched_init(struct drm_gpu_scheduler *sched,
return -EINVAL;
sched->ops = ops;
+ sched->single_entity = NULL;
sched->hw_submission_limit = hw_submission;
sched->name = name;
sched->submit_wq = submit_wq ? : system_wq;
@@ -1103,7 +1140,9 @@ int drm_sched_init(struct drm_gpu_scheduler *sched,
sched->sched_policy = default_drm_sched_policy;
else
sched->sched_policy = sched_policy;
- for (i = DRM_SCHED_PRIORITY_MIN; i < DRM_SCHED_PRIORITY_COUNT; i++)
+ for (i = DRM_SCHED_PRIORITY_MIN; sched_policy !=
+ DRM_SCHED_POLICY_SINGLE_ENTITY && i < DRM_SCHED_PRIORITY_COUNT;
+ i++)
drm_sched_rq_init(sched, &sched->sched_rq[i]);
init_waitqueue_head(&sched->job_scheduled);
@@ -1135,7 +1174,15 @@ void drm_sched_fini(struct drm_gpu_scheduler *sched)
drm_sched_submit_stop(sched);
- for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) {
+ if (sched->single_entity) {
+ spin_lock(&sched->single_entity->rq_lock);
+ sched->single_entity->stopped = true;
+ spin_unlock(&sched->single_entity->rq_lock);
+ }
+
+ for (i = DRM_SCHED_PRIORITY_COUNT - 1; sched->sched_policy !=
+ DRM_SCHED_POLICY_SINGLE_ENTITY && i >= DRM_SCHED_PRIORITY_MIN;
+ i--) {
struct drm_sched_rq *rq = &sched->sched_rq[i];
spin_lock(&rq->lock);
@@ -1176,6 +1223,8 @@ void drm_sched_increase_karma(struct drm_sched_job *bad)
struct drm_sched_entity *entity;
struct drm_gpu_scheduler *sched = bad->sched;
+ WARN_ON(sched->sched_policy == DRM_SCHED_POLICY_SINGLE_ENTITY);
+
/* don't change @bad's karma if it's from KERNEL RQ,
* because sometimes GPU hang would cause kernel jobs (like VM updating jobs)
* corrupt but keep in mind that kernel jobs always considered good.
diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
index 897d52a4ff4f..04eec2d7635f 100644
--- a/include/drm/gpu_scheduler.h
+++ b/include/drm/gpu_scheduler.h
@@ -79,6 +79,7 @@ enum drm_sched_policy {
DRM_SCHED_POLICY_DEFAULT,
DRM_SCHED_POLICY_RR,
DRM_SCHED_POLICY_FIFO,
+ DRM_SCHED_POLICY_SINGLE_ENTITY,
DRM_SCHED_POLICY_COUNT,
};
@@ -112,6 +113,9 @@ struct drm_sched_entity {
*/
struct drm_sched_rq *rq;
+ /** @single_sched: Single scheduler */
+ struct drm_gpu_scheduler *single_sched;
+
/**
* @sched_list:
*
@@ -473,6 +477,7 @@ struct drm_sched_backend_ops {
* struct drm_gpu_scheduler - scheduler instance-specific data
*
* @ops: backend operations provided by the driver.
+ * @single_entity: Single entity for the scheduler
* @hw_submission_limit: the max size of the hardware queue.
* @timeout: the time after which a job is removed from the scheduler.
* @name: name of the ring for which this scheduler is being used.
@@ -503,6 +508,7 @@ struct drm_sched_backend_ops {
*/
struct drm_gpu_scheduler {
const struct drm_sched_backend_ops *ops;
+ struct drm_sched_entity *single_entity;
uint32_t hw_submission_limit;
long timeout;
const char *name;
@@ -585,6 +591,8 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
struct drm_gpu_scheduler **sched_list,
unsigned int num_sched_list,
atomic_t *guilty);
+struct drm_gpu_scheduler *
+drm_sched_entity_to_scheduler(struct drm_sched_entity *entity);
long drm_sched_entity_flush(struct drm_sched_entity *entity, long timeout);
void drm_sched_entity_fini(struct drm_sched_entity *entity);
void drm_sched_entity_destroy(struct drm_sched_entity *entity);
--
2.34.1
next prev parent reply other threads:[~2023-08-11 2:31 UTC|newest]
Thread overview: 163+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-11 2:31 [Intel-xe] [PATCH v2 0/9] DRM scheduler changes for Xe Matthew Brost
2023-08-11 2:31 ` Matthew Brost
2023-08-11 2:31 ` [Intel-xe] [PATCH v2 1/9] drm/sched: Convert drm scheduler to use a work queue rather than kthread Matthew Brost
2023-08-11 2:31 ` Matthew Brost
2023-08-16 11:30 ` [Intel-xe] " Danilo Krummrich
2023-08-16 11:30 ` Danilo Krummrich
2023-08-16 14:05 ` [Intel-xe] " Christian König
2023-08-16 14:05 ` Christian König
2023-08-16 12:30 ` [Intel-xe] " Danilo Krummrich
2023-08-16 12:30 ` Danilo Krummrich
2023-08-16 14:38 ` [Intel-xe] " Matthew Brost
2023-08-16 14:38 ` Matthew Brost
2023-08-16 15:40 ` [Intel-xe] " Danilo Krummrich
2023-08-16 15:40 ` Danilo Krummrich
2023-08-16 14:59 ` [Intel-xe] " Christian König
2023-08-16 14:59 ` Christian König
2023-08-16 16:33 ` [Intel-xe] " Danilo Krummrich
2023-08-16 16:33 ` Danilo Krummrich
2023-08-17 5:33 ` [Intel-xe] " Christian König
2023-08-17 5:33 ` Christian König
2023-08-17 11:13 ` [Intel-xe] " Danilo Krummrich
2023-08-17 11:13 ` Danilo Krummrich
2023-08-17 13:35 ` [Intel-xe] " Christian König
2023-08-17 13:35 ` Christian König
2023-08-17 12:48 ` [Intel-xe] " Danilo Krummrich
2023-08-17 12:48 ` Danilo Krummrich
2023-08-17 16:17 ` [Intel-xe] " Christian König
2023-08-17 16:17 ` Christian König
2023-08-18 11:58 ` [Intel-xe] " Danilo Krummrich
2023-08-18 11:58 ` Danilo Krummrich
2023-08-21 14:07 ` [Intel-xe] " Christian König
2023-08-21 14:07 ` Christian König
2023-08-21 18:01 ` [Intel-xe] " Danilo Krummrich
2023-08-21 18:01 ` Danilo Krummrich
2023-08-21 18:12 ` [Intel-xe] " Christian König
2023-08-21 18:12 ` Christian König
2023-08-21 19:07 ` [Intel-xe] " Danilo Krummrich
2023-08-21 19:07 ` Danilo Krummrich
2023-08-22 9:35 ` [Intel-xe] " Christian König
2023-08-22 9:35 ` Christian König
2023-08-21 19:46 ` [Intel-xe] " Faith Ekstrand
2023-08-21 19:46 ` Faith Ekstrand
2023-08-22 9:51 ` [Intel-xe] " Christian König
2023-08-22 9:51 ` Christian König
2023-08-22 16:55 ` [Intel-xe] " Faith Ekstrand
2023-08-22 16:55 ` Faith Ekstrand
2023-08-24 11:50 ` [Intel-xe] " Bas Nieuwenhuizen
2023-08-24 11:50 ` Bas Nieuwenhuizen
2023-08-18 3:08 ` [Intel-xe] " Matthew Brost
2023-08-18 3:08 ` Matthew Brost
2023-08-18 5:40 ` [Intel-xe] " Christian König
2023-08-18 5:40 ` Christian König
2023-08-18 12:49 ` [Intel-xe] " Matthew Brost
2023-08-18 12:49 ` Matthew Brost
2023-08-18 12:06 ` [Intel-xe] " Danilo Krummrich
2023-08-18 12:06 ` Danilo Krummrich
2023-09-12 14:28 ` [Intel-xe] " Boris Brezillon
2023-09-12 14:28 ` Boris Brezillon
2023-09-12 14:33 ` [Intel-xe] " Danilo Krummrich
2023-09-12 14:33 ` Danilo Krummrich
2023-09-12 14:49 ` [Intel-xe] " Boris Brezillon
2023-09-12 14:49 ` Boris Brezillon
2023-09-12 15:13 ` [Intel-xe] " Boris Brezillon
2023-09-12 15:13 ` Boris Brezillon
2023-09-12 16:58 ` [Intel-xe] " Danilo Krummrich
2023-09-12 16:58 ` Danilo Krummrich
2023-09-12 16:52 ` [Intel-xe] " Danilo Krummrich
2023-09-12 16:52 ` Danilo Krummrich
2023-08-11 2:31 ` [Intel-xe] [PATCH v2 2/9] drm/sched: Move schedule policy to scheduler / entity Matthew Brost
2023-08-11 2:31 ` Matthew Brost
2023-08-11 21:43 ` [Intel-xe] " Maira Canal
2023-08-11 21:43 ` Maira Canal
2023-08-12 3:20 ` [Intel-xe] " Matthew Brost
2023-08-12 3:20 ` Matthew Brost
2023-08-11 2:31 ` Matthew Brost [this message]
2023-08-11 2:31 ` [PATCH v2 3/9] drm/sched: Add DRM_SCHED_POLICY_SINGLE_ENTITY scheduling policy Matthew Brost
2023-08-29 17:37 ` [Intel-xe] " Danilo Krummrich
2023-08-29 17:37 ` Danilo Krummrich
2023-09-05 11:10 ` [Intel-xe] " Danilo Krummrich
2023-09-05 11:10 ` Danilo Krummrich
2023-09-11 19:44 ` [Intel-xe] " Matthew Brost
2023-09-11 19:44 ` Matthew Brost
2023-08-11 2:31 ` [Intel-xe] [PATCH v2 4/9] drm/sched: Split free_job into own work item Matthew Brost
2023-08-11 2:31 ` Matthew Brost
2023-08-17 13:39 ` [Intel-xe] " Christian König
2023-08-17 13:39 ` Christian König
2023-08-17 17:54 ` [Intel-xe] " Matthew Brost
2023-08-17 17:54 ` Matthew Brost
2023-08-18 5:27 ` [Intel-xe] " Christian König
2023-08-18 5:27 ` Christian König
2023-08-18 13:13 ` [Intel-xe] " Matthew Brost
2023-08-18 13:13 ` Matthew Brost
2023-08-21 13:17 ` [Intel-xe] " Christian König
2023-08-21 13:17 ` Christian König
2023-08-23 3:27 ` [Intel-xe] " Matthew Brost
2023-08-23 3:27 ` Matthew Brost
2023-08-23 7:10 ` [Intel-xe] " Christian König
2023-08-23 7:10 ` Christian König
2023-08-23 15:24 ` [Intel-xe] " Matthew Brost
2023-08-23 15:24 ` Matthew Brost
2023-08-23 15:41 ` [Intel-xe] " Alex Deucher
2023-08-23 15:41 ` Alex Deucher
2023-08-23 17:26 ` [Intel-xe] " Rodrigo Vivi
2023-08-23 17:26 ` Rodrigo Vivi
2023-08-23 23:12 ` Matthew Brost
2023-08-23 23:12 ` Matthew Brost
2023-08-24 11:44 ` Christian König
2023-08-24 11:44 ` Christian König
2023-08-24 14:30 ` Matthew Brost
2023-08-24 14:30 ` Matthew Brost
2023-08-24 23:04 ` Danilo Krummrich
2023-08-24 23:04 ` Danilo Krummrich
2023-08-25 2:58 ` [Intel-xe] " Matthew Brost
2023-08-25 2:58 ` Matthew Brost
2023-08-25 8:02 ` [Intel-xe] " Christian König
2023-08-25 8:02 ` Christian König
2023-08-25 13:36 ` [Intel-xe] " Matthew Brost
2023-08-25 13:36 ` Matthew Brost
2023-08-25 13:45 ` [Intel-xe] " Christian König
2023-08-25 13:45 ` Christian König
2023-09-12 10:13 ` [Intel-xe] " Boris Brezillon
2023-09-12 10:13 ` Boris Brezillon
2023-09-12 10:46 ` [Intel-xe] " Danilo Krummrich
2023-09-12 10:46 ` Danilo Krummrich
2023-09-12 12:18 ` [Intel-xe] " Boris Brezillon
2023-09-12 12:18 ` Boris Brezillon
2023-09-12 12:56 ` [Intel-xe] " Danilo Krummrich
2023-09-12 12:56 ` Danilo Krummrich
2023-09-12 13:52 ` [Intel-xe] " Boris Brezillon
2023-09-12 13:52 ` Boris Brezillon
2023-09-12 14:10 ` [Intel-xe] " Danilo Krummrich
2023-09-12 14:10 ` Danilo Krummrich
2023-09-12 13:27 ` [Intel-xe] " Boris Brezillon
2023-09-12 13:27 ` Boris Brezillon
2023-09-12 13:34 ` [Intel-xe] " Danilo Krummrich
2023-09-12 13:34 ` Danilo Krummrich
2023-09-12 13:53 ` [Intel-xe] " Boris Brezillon
2023-09-12 13:53 ` Boris Brezillon
2023-08-28 18:04 ` [Intel-xe] " Danilo Krummrich
2023-08-28 18:04 ` Danilo Krummrich
2023-08-28 18:41 ` [Intel-xe] " Matthew Brost
2023-08-28 18:41 ` Matthew Brost
2023-08-29 1:20 ` [Intel-xe] " Danilo Krummrich
2023-08-29 1:20 ` Danilo Krummrich
2023-08-11 2:31 ` [Intel-xe] [PATCH v2 5/9] drm/sched: Add generic scheduler message interface Matthew Brost
2023-08-11 2:31 ` Matthew Brost
2023-08-11 2:31 ` [Intel-xe] [PATCH v2 6/9] drm/sched: Add drm_sched_start_timeout_unlocked helper Matthew Brost
2023-08-11 2:31 ` Matthew Brost
2023-08-11 2:31 ` [Intel-xe] [PATCH v2 7/9] drm/sched: Start run wq before TDR in drm_sched_start Matthew Brost
2023-08-11 2:31 ` Matthew Brost
2023-08-11 2:31 ` [Intel-xe] [PATCH v2 8/9] drm/sched: Submit job before starting TDR Matthew Brost
2023-08-11 2:31 ` Matthew Brost
2023-08-11 2:31 ` [Intel-xe] [PATCH v2 9/9] drm/sched: Add helper to set TDR timeout Matthew Brost
2023-08-11 2:31 ` Matthew Brost
2023-08-11 2:34 ` [Intel-xe] ✗ CI.Patch_applied: failure for DRM scheduler changes for Xe (rev2) Patchwork
2023-08-24 0:08 ` [Intel-xe] [PATCH v2 0/9] DRM scheduler changes for Xe Danilo Krummrich
2023-08-24 0:08 ` Danilo Krummrich
2023-08-24 3:23 ` [Intel-xe] " Matthew Brost
2023-08-24 3:23 ` Matthew Brost
2023-08-24 14:51 ` [Intel-xe] " Danilo Krummrich
2023-08-24 14:51 ` Danilo Krummrich
2023-08-25 3:01 ` [Intel-xe] ✗ CI.Patch_applied: failure for DRM scheduler changes for Xe (rev3) Patchwork
2023-09-05 11:13 ` [Intel-xe] ✗ CI.Patch_applied: failure for DRM scheduler changes for Xe (rev4) Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230811023137.659037-4-matthew.brost@intel.com \
--to=matthew.brost@intel.com \
--cc=Liviu.Dudau@arm.com \
--cc=airlied@gmail.com \
--cc=boris.brezillon@collabora.com \
--cc=christian.koenig@amd.com \
--cc=daniel@ffwll.ch \
--cc=donald.robson@imgtec.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=faith.ekstrand@collabora.com \
--cc=frank.binns@imgtec.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=ketil.johnsen@arm.com \
--cc=lina@asahilina.net \
--cc=luben.tuikov@amd.com \
--cc=robdclark@chromium.org \
--cc=sarah.walker@imgtec.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.