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