1 /* 2 * Copyright (C) 2018-2022 Intel Corporation. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef SCHEDULE_H 8 #define SCHEDULE_H 9 #include <asm/lib/spinlock.h> 10 #include <lib/list.h> 11 #include <timer.h> 12 13 #define NEED_RESCHEDULE (1U) 14 15 #define DEL_MODE_INIT (1U) 16 #define DEL_MODE_IPI (2U) 17 18 #define IDLE_MODE_PAUSE (1U) 19 #define IDLE_MODE_HLT (2U) 20 21 #define THREAD_DATA_SIZE (256U) 22 23 enum thread_object_state { 24 THREAD_STS_RUNNING = 1, 25 THREAD_STS_RUNNABLE, 26 THREAD_STS_BLOCKED 27 }; 28 29 /* Tools can configure a VM to use PRIO_LOW or PRIO_HIGH */ 30 enum thread_priority { 31 PRIO_IDLE = 0, 32 PRIO_LOW, 33 PRIO_HIGH, 34 PRIO_MAX 35 }; 36 37 /* 38 * For now, we just have several parameters for all the schedulers. So we 39 * put them together here for simplicity. TODO When this structure grows big 40 * enough, we need to replace it with a union of parameters of different 41 * schedulers. 42 */ 43 struct sched_params { 44 uint32_t prio; /* The priority of a thread */ 45 46 /* per thread parameters for bvt scheduler */ 47 uint8_t bvt_weight; /* the weight of a thread */ 48 int32_t bvt_warp_value; /* the warp reduce effective VT to boost priority */ 49 uint32_t bvt_warp_limit; /* max time in one warp */ 50 uint32_t bvt_unwarp_period; /* min unwarp time after a warp */ 51 }; 52 53 struct thread_object; 54 typedef void (*thread_entry_t)(struct thread_object *obj); 55 typedef void (*switch_t)(struct thread_object *obj); 56 struct thread_object { 57 char name[16]; 58 uint16_t pcpu_id; 59 struct sched_control *sched_ctl; 60 thread_entry_t thread_entry; 61 volatile enum thread_object_state status; 62 bool be_blocking; 63 64 uint64_t host_sp; 65 switch_t switch_out; 66 switch_t switch_in; 67 68 uint8_t data[THREAD_DATA_SIZE]; 69 }; 70 71 struct sched_control { 72 uint16_t pcpu_id; 73 uint64_t flags; 74 struct thread_object *curr_obj; 75 spinlock_t scheduler_lock; /* to protect sched_control and thread_object */ 76 struct acrn_scheduler *scheduler; 77 void *priv; 78 }; 79 80 #define SCHEDULER_MAX_NUMBER 4U 81 struct acrn_scheduler { 82 char name[16]; 83 84 /* init scheduler */ 85 int32_t (*init)(struct sched_control *ctl); 86 /* init private data of scheduler */ 87 void (*init_data)(struct thread_object *obj, struct sched_params *params); 88 /* pick the next thread object */ 89 struct thread_object* (*pick_next)(struct sched_control *ctl); 90 /* put thread object into sleep */ 91 void (*sleep)(struct thread_object *obj); 92 /* wake up thread object from sleep status */ 93 void (*wake)(struct thread_object *obj); 94 /* yield current thread object */ 95 void (*yield)(struct sched_control *ctl); 96 /* prioritize the thread object */ 97 void (*prioritize)(struct thread_object *obj); 98 /* deinit private data of scheduler */ 99 void (*deinit_data)(struct thread_object *obj); 100 /* deinit scheduler */ 101 void (*deinit)(struct sched_control *ctl); 102 /* suspend scheduler */ 103 void (*suspend)(struct sched_control *ctl); 104 /* resume scheduler */ 105 void (*resume)(struct sched_control *ctl); 106 }; 107 extern struct acrn_scheduler sched_noop; 108 extern struct acrn_scheduler sched_iorr; 109 110 struct sched_noop_control { 111 struct thread_object *noop_thread_obj; 112 }; 113 114 struct sched_iorr_control { 115 struct list_head runqueue; 116 struct hv_timer tick_timer; 117 }; 118 119 extern struct acrn_scheduler sched_bvt; 120 struct sched_bvt_control { 121 struct list_head runqueue; 122 struct hv_timer tick_timer; 123 /* The minimum AVT of any runnable threads */ 124 int64_t svt; 125 }; 126 127 extern struct acrn_scheduler sched_prio; 128 struct sched_prio_control { 129 struct list_head prio_queue; 130 }; 131 132 bool is_idle_thread(const struct thread_object *obj); 133 uint16_t sched_get_pcpuid(const struct thread_object *obj); 134 struct thread_object *sched_get_current(uint16_t pcpu_id); 135 136 void init_sched(uint16_t pcpu_id); 137 void deinit_sched(uint16_t pcpu_id); 138 void suspend_sched(void); 139 void resume_sched(void); 140 void obtain_schedule_lock(uint16_t pcpu_id, uint64_t *rflag); 141 void release_schedule_lock(uint16_t pcpu_id, uint64_t rflag); 142 143 void init_thread_data(struct thread_object *obj, struct sched_params *params); 144 void deinit_thread_data(struct thread_object *obj); 145 146 void make_reschedule_request(uint16_t pcpu_id); 147 bool need_reschedule(uint16_t pcpu_id); 148 149 void run_thread(struct thread_object *obj); 150 void sleep_thread(struct thread_object *obj); 151 void sleep_thread_sync(struct thread_object *obj); 152 void wake_thread(struct thread_object *obj); 153 void yield_current(void); 154 void schedule(void); 155 156 void arch_switch_to(void *prev_sp, void *next_sp); 157 void run_idle_thread(void); 158 #endif /* SCHEDULE_H */ 159 160