1  /*
2   * SPDX-License-Identifier: MIT
3   *
4   * Copyright © 2018 Intel Corporation
5   */
6  
7  #ifndef _I915_SCHEDULER_H_
8  #define _I915_SCHEDULER_H_
9  
10  #include <linux/bitops.h>
11  #include <linux/list.h>
12  #include <linux/kernel.h>
13  
14  #include "i915_scheduler_types.h"
15  #include "i915_tasklet.h"
16  
17  struct drm_printer;
18  
19  #define priolist_for_each_request(it, plist) \
20  	list_for_each_entry(it, &(plist)->requests, sched.link)
21  
22  #define priolist_for_each_request_consume(it, n, plist) \
23  	list_for_each_entry_safe(it, n, &(plist)->requests, sched.link)
24  
25  void i915_sched_node_init(struct i915_sched_node *node);
26  void i915_sched_node_reinit(struct i915_sched_node *node);
27  
28  bool __i915_sched_node_add_dependency(struct i915_sched_node *node,
29  				      struct i915_sched_node *signal,
30  				      struct i915_dependency *dep,
31  				      unsigned long flags);
32  
33  int i915_sched_node_add_dependency(struct i915_sched_node *node,
34  				   struct i915_sched_node *signal,
35  				   unsigned long flags);
36  
37  void i915_sched_node_fini(struct i915_sched_node *node);
38  
39  void i915_schedule(struct i915_request *request,
40  		   const struct i915_sched_attr *attr);
41  
42  struct list_head *
43  i915_sched_lookup_priolist(struct i915_sched_engine *sched_engine, int prio);
44  
45  void __i915_priolist_free(struct i915_priolist *p);
i915_priolist_free(struct i915_priolist * p)46  static inline void i915_priolist_free(struct i915_priolist *p)
47  {
48  	if (p->priority != I915_PRIORITY_NORMAL)
49  		__i915_priolist_free(p);
50  }
51  
52  struct i915_sched_engine *
53  i915_sched_engine_create(unsigned int subclass);
54  
55  static inline struct i915_sched_engine *
i915_sched_engine_get(struct i915_sched_engine * sched_engine)56  i915_sched_engine_get(struct i915_sched_engine *sched_engine)
57  {
58  	kref_get(&sched_engine->ref);
59  	return sched_engine;
60  }
61  
62  static inline void
i915_sched_engine_put(struct i915_sched_engine * sched_engine)63  i915_sched_engine_put(struct i915_sched_engine *sched_engine)
64  {
65  	kref_put(&sched_engine->ref, sched_engine->destroy);
66  }
67  
68  static inline bool
i915_sched_engine_is_empty(struct i915_sched_engine * sched_engine)69  i915_sched_engine_is_empty(struct i915_sched_engine *sched_engine)
70  {
71  	return RB_EMPTY_ROOT(&sched_engine->queue.rb_root);
72  }
73  
74  static inline void
i915_sched_engine_reset_on_empty(struct i915_sched_engine * sched_engine)75  i915_sched_engine_reset_on_empty(struct i915_sched_engine *sched_engine)
76  {
77  	if (i915_sched_engine_is_empty(sched_engine))
78  		sched_engine->no_priolist = false;
79  }
80  
81  static inline void
i915_sched_engine_active_lock_bh(struct i915_sched_engine * sched_engine)82  i915_sched_engine_active_lock_bh(struct i915_sched_engine *sched_engine)
83  {
84  	local_bh_disable(); /* prevent local softirq and lock recursion */
85  	tasklet_lock(&sched_engine->tasklet);
86  }
87  
88  static inline void
i915_sched_engine_active_unlock_bh(struct i915_sched_engine * sched_engine)89  i915_sched_engine_active_unlock_bh(struct i915_sched_engine *sched_engine)
90  {
91  	tasklet_unlock(&sched_engine->tasklet);
92  	local_bh_enable(); /* restore softirq, and kick ksoftirqd! */
93  }
94  
95  void i915_request_show_with_schedule(struct drm_printer *m,
96  				     const struct i915_request *rq,
97  				     const char *prefix,
98  				     int indent);
99  
100  static inline bool
i915_sched_engine_disabled(struct i915_sched_engine * sched_engine)101  i915_sched_engine_disabled(struct i915_sched_engine *sched_engine)
102  {
103  	return sched_engine->disabled(sched_engine);
104  }
105  
106  void i915_scheduler_module_exit(void);
107  int i915_scheduler_module_init(void);
108  
109  #endif /* _I915_SCHEDULER_H_ */
110