
Eddie Dong
Reviewed-by: Eddie Dong <eddie.dong@...> Please get +1 from Wang Yu too.
toggle quoted message
Show quoted text
-----Original Message----- From: acrn-dev@... <acrn-dev@...> On Behalf Of Conghui Chen Sent: Wednesday, July 27, 2022 5:02 AM To: acrn-dev@... Cc: Li, Fei1 <fei1.li@...>; Chen, Conghui <conghui.chen@...> Subject: [acrn-dev] [PATCH] hv: sched: fix bug when reboot vm
BVT schedule rule: When a new thread is wakeup and added to runqueue, it will get the smallest avt (svt) from runqueue to initiate its avt. If the svt is smaller than it's avt, it will keep the original avt.
For the reboot issue, when the VM is reboot, it means a new vcpu thread is wakeup, but at this time, the Service VM's vcpu thread is blocked, and removed from the runqueue, and the runqueue is empty, so the svt is 0. The new vcpu thread will get avt=0. avt=0 means very high priority, and can run for a very long time until it catch up with other thread's avt in runqueue. At this time, when Service VM's vcpu thread wakeup, it will check the svt, but the svt is very small, so will not update it's avt according to the rule, thus has a very low priority and cannot be scheduled.
To fix it, add a variable in structure sched_bvt_control, which is shared by all thread objects in a pCPU. The variable is used to record the avt of the last thread object removed from runqueue. This value is used to update the svt when there is no object in runqueue.
Signed-off-by: Conghui <conghui.chen@...> --- hypervisor/common/sched_bvt.c | 17 ++++++++++++++++- hypervisor/include/common/schedule.h | 1 + 2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/hypervisor/common/sched_bvt.c b/hypervisor/common/sched_bvt.c index 8354b13d7..431a2cdf1 100644 --- a/hypervisor/common/sched_bvt.c +++ b/hypervisor/common/sched_bvt.c @@ -104,12 +104,14 @@ static int64_t get_svt(struct thread_object *obj) struct sched_bvt_control *bvt_ctl = (struct sched_bvt_control *)obj-
sched_ctl->priv; struct sched_bvt_data *obj_data; struct thread_object *tmp_obj; - int64_t svt = 0; + int64_t svt;
if (!list_empty(&bvt_ctl->runqueue)) { tmp_obj = get_first_item(&bvt_ctl->runqueue, struct thread_object, data); obj_data = (struct sched_bvt_data *)tmp_obj->data; svt = obj_data->avt; + } else { + svt = bvt_ctl->last_avt; } return svt; } @@ -156,6 +158,7 @@ static int sched_bvt_init(struct sched_control *ctl)
ctl->priv = bvt_ctl; INIT_LIST_HEAD(&bvt_ctl->runqueue); + bvt_ctl->last_avt = 0U;
/* The tick_timer is periodically */ initialize_timer(&bvt_ctl->tick_timer, sched_tick_handler, ctl, @@ - 270,9 +273,21 @@ static struct thread_object *sched_bvt_pick_next(struct sched_control *ctl) return next; }
+static void update_svt(struct thread_object *obj) { + struct sched_bvt_data *data; + struct sched_bvt_control *bvt_ctl = + (struct sched_bvt_control *)obj->sched_ctl->priv; + + data = (struct sched_bvt_data *)obj->data; + if (list_empty(&data->list)) + bvt_ctl->last_avt = data->avt; +} + static void sched_bvt_sleep(struct thread_object *obj) { runqueue_remove(obj); + update_svt(obj); }
static void sched_bvt_wake(struct thread_object *obj) diff --git a/hypervisor/include/common/schedule.h b/hypervisor/include/common/schedule.h index c4d34bbbb..8528aa4ed 100644 --- a/hypervisor/include/common/schedule.h +++ b/hypervisor/include/common/schedule.h @@ -105,6 +105,7 @@ extern struct acrn_scheduler sched_bvt; struct sched_bvt_control { struct list_head runqueue; struct hv_timer tick_timer; + int last_avt; };
extern struct acrn_scheduler sched_prio; -- 2.25.1
|