Re: [PATCH v2 3/9] hv: sched_iorr: add tick handler and runqueue operations


Shuo A Liu
 

On Thu 5.Dec'19 at 18:03:17 +0800, Dong, Eddie wrote:


-----Original Message-----
From: acrn-dev@... <acrn-dev@...> On
Behalf Of Shuo A Liu
Sent: Thursday, December 5, 2019 5:15 PM
To: acrn-dev@...
Cc: Wang, Yu1 <yu1.wang@...>; Chen, Jason CJ
<jason.cj.chen@...>; Chen, Conghui <conghui.chen@...>; Liu,
Shuo A <shuo.a.liu@...>
Subject: [acrn-dev] [PATCH v2 3/9] hv: sched_iorr: add tick handler and
runqueue operations

sched_control is per-pcpu, each sched_control has a tick timer running
periodically. Every period called a tick. In tick handler, we do
1) compute left timeslice of current thread_object if it's not the idle
2) make a schedule request if current thread_object run out of timeslice

For runqueue maintaining, we will keep objects which has timeslice in the
front of runqueue and the ones get new replenished in tail.

Signed-off-by: Jason Chen CJ <jason.cj.chen@...>
Signed-off-by: Yu Wang <yu1.wang@...>
Signed-off-by: Shuo A Liu <shuo.a.liu@...>
---
hypervisor/common/sched_iorr.c | 61
+++++++++++++++++++++++++++++++++++++++++-
1 file changed, 60 insertions(+), 1 deletion(-)

diff --git a/hypervisor/common/sched_iorr.c
b/hypervisor/common/sched_iorr.c index d0b5ce7..d6d0ad9 100644
--- a/hypervisor/common/sched_iorr.c
+++ b/hypervisor/common/sched_iorr.c
@@ -18,8 +18,67 @@ struct sched_iorr_data {
int64_t left_cycles;
};

-static void sched_tick_handler(__unused void *param)
+bool is_inqueue(struct thread_object *obj)
{
+ struct sched_iorr_data *data = (struct sched_iorr_data *)obj->data;
+ return !list_empty(&data->list);
+}
+
+void runqueue_add_head(struct thread_object *obj) {
+ struct sched_iorr_control *iorr_ctl = (struct sched_iorr_control
*)obj->sched_ctl->priv;
+ struct sched_iorr_data *data = (struct sched_iorr_data *)obj->data;
+
+ if (!is_inqueue(obj)) {
+ list_add(&data->list, &iorr_ctl->runqueue);
+ }
+}
+
+void runqueue_add_tail(struct thread_object *obj) {
Here we assume obj is already initialized with proper obj->sched_ctrl, and priv...
Add @pre ?
OK. Will add

@pre obj != NULL
@pre obj->sched_ctl != NULL
@pre obj->sched_ctl->priv != NULL


Same for other APIs?
Yes. Will revisit them and add the @pre.



+ struct sched_iorr_control *iorr_ctl = (struct sched_iorr_control
*)obj->sched_ctl->priv;
+ struct sched_iorr_data *data = (struct sched_iorr_data *)obj->data;
+
+ if (!is_inqueue(obj)) {
+ list_add_tail(&data->list, &iorr_ctl->runqueue);
+ }
+}
+
+void runqueue_remove(struct thread_object *obj) {
+ struct sched_iorr_data *data = (struct sched_iorr_data *)obj->data;
+ list_del_init(&data->list);
+}
+
+static void sched_tick_handler(void *param) {
+ struct sched_control *ctl = (struct sched_control *)param;
+ struct sched_iorr_control *iorr_ctl = (struct sched_iorr_control
*)ctl->priv;
+ struct sched_iorr_data *data;
+ struct thread_object *current;
+ uint16_t pcpu_id = get_pcpu_id();
+ uint64_t now = rdtsc();
+ uint64_t rflags;
+
+ obtain_schedule_lock(pcpu_id, &rflags);
+ current = ctl->curr_obj;
+
+ /* If no vCPU start scheduling, ignore this tick */
+ if (current == NULL || (is_idle_thread(current) &&
list_empty(&iorr_ctl->runqueue))) {
In which case, current may be NULL ? Can we assume we always have idle thread?
In the early stage, timer is started we havn't launch idle thread, it is
NULL. We need check it for such case.


+ release_schedule_lock(pcpu_id, rflags);
+ return;
Does MISRAC allow return here?
Will refine the code to satisfy MISRAC.


+ }
+ data = (struct sched_iorr_data *)current->data;
+ /* consume the left_cycles of current thread_object if it is not idle */
+ if (!is_idle_thread(current)) {
+ data->left_cycles -= now - data->last_cycles;
+ data->last_cycles = now;
+ }
+ /* make reschedule request if current ran out of its cycles */
+ if (is_idle_thread(current) || data->left_cycles <= 0) {
+ make_reschedule_request(pcpu_id, DEL_MODE_IPI);
+ }
+ release_schedule_lock(pcpu_id, rflags);
}

/*
--
2.8.3


Join acrn-dev@lists.projectacrn.org to automatically receive all group messages.