.. | .. |
---|
8 | 8 | #define _I915_SCHEDULER_H_ |
---|
9 | 9 | |
---|
10 | 10 | #include <linux/bitops.h> |
---|
| 11 | +#include <linux/list.h> |
---|
| 12 | +#include <linux/kernel.h> |
---|
11 | 13 | |
---|
12 | | -#include <uapi/drm/i915_drm.h> |
---|
| 14 | +#include "i915_scheduler_types.h" |
---|
13 | 15 | |
---|
14 | | -enum { |
---|
15 | | - I915_PRIORITY_MIN = I915_CONTEXT_MIN_USER_PRIORITY - 1, |
---|
16 | | - I915_PRIORITY_NORMAL = I915_CONTEXT_DEFAULT_PRIORITY, |
---|
17 | | - I915_PRIORITY_MAX = I915_CONTEXT_MAX_USER_PRIORITY + 1, |
---|
| 16 | +#define priolist_for_each_request(it, plist, idx) \ |
---|
| 17 | + for (idx = 0; idx < ARRAY_SIZE((plist)->requests); idx++) \ |
---|
| 18 | + list_for_each_entry(it, &(plist)->requests[idx], sched.link) |
---|
18 | 19 | |
---|
19 | | - I915_PRIORITY_INVALID = INT_MIN |
---|
20 | | -}; |
---|
| 20 | +#define priolist_for_each_request_consume(it, n, plist, idx) \ |
---|
| 21 | + for (; \ |
---|
| 22 | + (plist)->used ? (idx = __ffs((plist)->used)), 1 : 0; \ |
---|
| 23 | + (plist)->used &= ~BIT(idx)) \ |
---|
| 24 | + list_for_each_entry_safe(it, n, \ |
---|
| 25 | + &(plist)->requests[idx], \ |
---|
| 26 | + sched.link) |
---|
21 | 27 | |
---|
22 | | -struct i915_sched_attr { |
---|
23 | | - /** |
---|
24 | | - * @priority: execution and service priority |
---|
25 | | - * |
---|
26 | | - * All clients are equal, but some are more equal than others! |
---|
27 | | - * |
---|
28 | | - * Requests from a context with a greater (more positive) value of |
---|
29 | | - * @priority will be executed before those with a lower @priority |
---|
30 | | - * value, forming a simple QoS. |
---|
31 | | - * |
---|
32 | | - * The &drm_i915_private.kernel_context is assigned the lowest priority. |
---|
33 | | - */ |
---|
34 | | - int priority; |
---|
35 | | -}; |
---|
| 28 | +void i915_sched_node_init(struct i915_sched_node *node); |
---|
| 29 | +void i915_sched_node_reinit(struct i915_sched_node *node); |
---|
36 | 30 | |
---|
37 | | -/* |
---|
38 | | - * "People assume that time is a strict progression of cause to effect, but |
---|
39 | | - * actually, from a nonlinear, non-subjective viewpoint, it's more like a big |
---|
40 | | - * ball of wibbly-wobbly, timey-wimey ... stuff." -The Doctor, 2015 |
---|
41 | | - * |
---|
42 | | - * Requests exist in a complex web of interdependencies. Each request |
---|
43 | | - * has to wait for some other request to complete before it is ready to be run |
---|
44 | | - * (e.g. we have to wait until the pixels have been rendering into a texture |
---|
45 | | - * before we can copy from it). We track the readiness of a request in terms |
---|
46 | | - * of fences, but we also need to keep the dependency tree for the lifetime |
---|
47 | | - * of the request (beyond the life of an individual fence). We use the tree |
---|
48 | | - * at various points to reorder the requests whilst keeping the requests |
---|
49 | | - * in order with respect to their various dependencies. |
---|
50 | | - * |
---|
51 | | - * There is no active component to the "scheduler". As we know the dependency |
---|
52 | | - * DAG of each request, we are able to insert it into a sorted queue when it |
---|
53 | | - * is ready, and are able to reorder its portion of the graph to accommodate |
---|
54 | | - * dynamic priority changes. |
---|
55 | | - */ |
---|
56 | | -struct i915_sched_node { |
---|
57 | | - struct list_head signalers_list; /* those before us, we depend upon */ |
---|
58 | | - struct list_head waiters_list; /* those after us, they depend upon us */ |
---|
59 | | - struct list_head link; |
---|
60 | | - struct i915_sched_attr attr; |
---|
61 | | -}; |
---|
| 31 | +bool __i915_sched_node_add_dependency(struct i915_sched_node *node, |
---|
| 32 | + struct i915_sched_node *signal, |
---|
| 33 | + struct i915_dependency *dep, |
---|
| 34 | + unsigned long flags); |
---|
62 | 35 | |
---|
63 | | -struct i915_dependency { |
---|
64 | | - struct i915_sched_node *signaler; |
---|
65 | | - struct list_head signal_link; |
---|
66 | | - struct list_head wait_link; |
---|
67 | | - struct list_head dfs_link; |
---|
68 | | - unsigned long flags; |
---|
69 | | -#define I915_DEPENDENCY_ALLOC BIT(0) |
---|
70 | | -}; |
---|
| 36 | +int i915_sched_node_add_dependency(struct i915_sched_node *node, |
---|
| 37 | + struct i915_sched_node *signal, |
---|
| 38 | + unsigned long flags); |
---|
| 39 | + |
---|
| 40 | +void i915_sched_node_fini(struct i915_sched_node *node); |
---|
| 41 | + |
---|
| 42 | +void i915_schedule(struct i915_request *request, |
---|
| 43 | + const struct i915_sched_attr *attr); |
---|
| 44 | + |
---|
| 45 | +void i915_schedule_bump_priority(struct i915_request *rq, unsigned int bump); |
---|
| 46 | + |
---|
| 47 | +struct list_head * |
---|
| 48 | +i915_sched_lookup_priolist(struct intel_engine_cs *engine, int prio); |
---|
| 49 | + |
---|
| 50 | +void __i915_priolist_free(struct i915_priolist *p); |
---|
| 51 | +static inline void i915_priolist_free(struct i915_priolist *p) |
---|
| 52 | +{ |
---|
| 53 | + if (p->priority != I915_PRIORITY_NORMAL) |
---|
| 54 | + __i915_priolist_free(p); |
---|
| 55 | +} |
---|
71 | 56 | |
---|
72 | 57 | #endif /* _I915_SCHEDULER_H_ */ |
---|