Home | History | Annotate | Line # | Download | only in i915
      1 /*	$NetBSD: i915_scheduler_types.h,v 1.2 2021/12/18 23:45:28 riastradh Exp $	*/
      2 
      3 /*
      4  * SPDX-License-Identifier: MIT
      5  *
      6  * Copyright  2018 Intel Corporation
      7  */
      8 
      9 #ifndef _I915_SCHEDULER_TYPES_H_
     10 #define _I915_SCHEDULER_TYPES_H_
     11 
     12 #include <linux/list.h>
     13 
     14 #include "gt/intel_engine_types.h"
     15 #include "i915_priolist_types.h"
     16 
     17 struct drm_i915_private;
     18 struct i915_request;
     19 struct intel_engine_cs;
     20 
     21 struct i915_sched_attr {
     22 	/**
     23 	 * @priority: execution and service priority
     24 	 *
     25 	 * All clients are equal, but some are more equal than others!
     26 	 *
     27 	 * Requests from a context with a greater (more positive) value of
     28 	 * @priority will be executed before those with a lower @priority
     29 	 * value, forming a simple QoS.
     30 	 *
     31 	 * The &drm_i915_private.kernel_context is assigned the lowest priority.
     32 	 */
     33 	int priority;
     34 };
     35 
     36 /*
     37  * "People assume that time is a strict progression of cause to effect, but
     38  * actually, from a nonlinear, non-subjective viewpoint, it's more like a big
     39  * ball of wibbly-wobbly, timey-wimey ... stuff." -The Doctor, 2015
     40  *
     41  * Requests exist in a complex web of interdependencies. Each request
     42  * has to wait for some other request to complete before it is ready to be run
     43  * (e.g. we have to wait until the pixels have been rendering into a texture
     44  * before we can copy from it). We track the readiness of a request in terms
     45  * of fences, but we also need to keep the dependency tree for the lifetime
     46  * of the request (beyond the life of an individual fence). We use the tree
     47  * at various points to reorder the requests whilst keeping the requests
     48  * in order with respect to their various dependencies.
     49  *
     50  * There is no active component to the "scheduler". As we know the dependency
     51  * DAG of each request, we are able to insert it into a sorted queue when it
     52  * is ready, and are able to reorder its portion of the graph to accommodate
     53  * dynamic priority changes.
     54  *
     55  * Ok, there is now one active element to the "scheduler" in the backends.
     56  * We let a new context run for a small amount of time before re-evaluating
     57  * the run order. As we re-evaluate, we maintain the strict ordering of
     58  * dependencies, but attempt to rotate the active contexts (the current context
     59  * is put to the back of its priority queue, then reshuffling its dependents).
     60  * This provides minimal timeslicing and prevents a userspace hog (e.g.
     61  * something waiting on a user semaphore [VkEvent]) from denying service to
     62  * others.
     63  */
     64 struct i915_sched_node {
     65 	struct list_head signalers_list; /* those before us, we depend upon */
     66 	struct list_head waiters_list; /* those after us, they depend upon us */
     67 	struct list_head link;
     68 	struct i915_sched_attr attr;
     69 	unsigned int flags;
     70 #define I915_SCHED_HAS_SEMAPHORE_CHAIN	BIT(0)
     71 	intel_engine_mask_t semaphores;
     72 };
     73 
     74 struct i915_dependency {
     75 	struct i915_sched_node *signaler;
     76 	struct i915_sched_node *waiter;
     77 	struct list_head signal_link;
     78 	struct list_head wait_link;
     79 	struct list_head dfs_link;
     80 	unsigned long flags;
     81 #define I915_DEPENDENCY_ALLOC		BIT(0)
     82 #define I915_DEPENDENCY_EXTERNAL	BIT(1)
     83 };
     84 
     85 #endif /* _I915_SCHEDULER_TYPES_H_ */
     86