From a7563cb9bdbef457e2c7df1b0300e876b0d9ed6b Mon Sep 17 00:00:00 2001 From: Conghui Chen Date: Wed, 5 Feb 2020 14:51:43 +0000 Subject: [PATCH] hv: sched_bvt: add BVT scheduler BVT (Borrowed virtual time) scheduler is used to schedule vCPUs on pCPU. It has the concept of virtual time, vCPU with earliset virtual time is dispatched first. Main concepts: tick timer: a period tick is used to measure the physcial time in units of MCU (minimum charing unit). runqueue: thread in the runqueue is ordered by virtual time. weight: each thread receives a share of the pCPU in proportion to its weight. context switch allowance: the physcial time by which the current thread is allowed to advance beyond the next runnable thread. warp: a thread with warp enabled will have a change to minus a value (Wi) from virtual time to achieve higher priority. virtual time: AVT: actual virtual time, advance in proportional to weight. EVT: effective virtual time. EVT <- AVT - ( warp ? Wi : 0 ) SVT: scheduler virtual time, the minimum AVT in the runqueue. Tracked-On: #4410 Signed-off-by: Conghui Chen Signed-off-by: Shuo A Liu Acked-by: Eddie Dong --- hypervisor/Makefile | 3 ++ hypervisor/arch/x86/Kconfig | 9 ++++ hypervisor/common/sched_bvt.c | 67 +++++++++++++++++++++++++++ hypervisor/common/schedule.c | 3 ++ hypervisor/include/arch/x86/per_cpu.h | 1 + hypervisor/include/common/schedule.h | 6 +++ 6 files changed, 89 insertions(+) create mode 100644 hypervisor/common/sched_bvt.c diff --git a/hypervisor/Makefile b/hypervisor/Makefile index 25e956369..a802dc35a 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -227,6 +227,9 @@ endif ifeq ($(CONFIG_SCHED_IORR),y) HW_C_SRCS += common/sched_iorr.c endif +ifeq ($(CONFIG_SCHED_BVT),y) +HW_C_SRCS += common/sched_bvt.c +endif HW_C_SRCS += hw/pci.c HW_C_SRCS += arch/x86/configs/vm_config.c HW_C_SRCS += arch/x86/configs/$(CONFIG_BOARD)/board.c diff --git a/hypervisor/arch/x86/Kconfig b/hypervisor/arch/x86/Kconfig index 2696ff718..7e46f8964 100644 --- a/hypervisor/arch/x86/Kconfig +++ b/hypervisor/arch/x86/Kconfig @@ -55,6 +55,15 @@ config SCHED_IORR IORR (IO sensitive Round Robin) scheduler supports multipule vCPUs running on on one pCPU, and they will be scheduled by a IO sensitive round robin policy. +config SCHED_BVT + bool "BVT scheduler" + help + BVT (Borrowed Virtual time) is virtual time based scheduling algorithm, it + dispatching the runnable thread with the earliest effective virtual time. + TODO: BVT scheduler will be built on top of prioritized scheduling mechanism, + i.e. higher priority threads get scheduled first, and same priority tasks are + scheduled per BVT. + endchoice diff --git a/hypervisor/common/sched_bvt.c b/hypervisor/common/sched_bvt.c new file mode 100644 index 000000000..6f7a0b677 --- /dev/null +++ b/hypervisor/common/sched_bvt.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2020 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#define BVT_MCU_MS 1U +/* context switch allowance */ +#define BVT_CSA_MCU 5U +struct sched_bvt_data { + /* keep list as the first item */ + struct list_head list; + /* minimum charging unit in cycles */ + uint64_t mcu; + /* a thread receives a share of cpu in proportion to its weight */ + uint16_t weight; + /* virtual time advance variable, proportional to 1 / weight */ + uint64_t vt_ratio; + /* the count down number of mcu until reschedule should take place */ + uint64_t run_countdown; + /* actual virtual time in units of mcu */ + int64_t avt; + /* effective virtual time in units of mcu */ + int64_t evt; + + uint64_t start_tsc; +}; + +static int sched_bvt_init(__unused struct sched_control *ctl) +{ + return 0; +} + +static void sched_bvt_deinit(__unused struct sched_control *ctl) +{ +} + +static void sched_bvt_init_data(__unused struct thread_object *obj) +{ +} + +static struct thread_object *sched_bvt_pick_next(__unused struct sched_control *ctl) +{ + return NULL; +} + +static void sched_bvt_sleep(__unused struct thread_object *obj) +{ +} + +static void sched_bvt_wake(__unused struct thread_object *obj) +{ +} + +struct acrn_scheduler sched_bvt = { + .name = "sched_bvt", + .init = sched_bvt_init, + .init_data = sched_bvt_init_data, + .pick_next = sched_bvt_pick_next, + .sleep = sched_bvt_sleep, + .wake = sched_bvt_wake, + .deinit = sched_bvt_deinit, +}; diff --git a/hypervisor/common/schedule.c b/hypervisor/common/schedule.c index 9a7599c08..74c75338b 100644 --- a/hypervisor/common/schedule.c +++ b/hypervisor/common/schedule.c @@ -78,6 +78,9 @@ void init_sched(uint16_t pcpu_id) #endif #ifdef CONFIG_SCHED_IORR ctl->scheduler = &sched_iorr; +#endif +#ifdef CONFIG_SCHED_BVT + ctl->scheduler = &sched_bvt; #endif if (ctl->scheduler->init != NULL) { ctl->scheduler->init(ctl); diff --git a/hypervisor/include/arch/x86/per_cpu.h b/hypervisor/include/arch/x86/per_cpu.h index 02f780176..7760c986c 100644 --- a/hypervisor/include/arch/x86/per_cpu.h +++ b/hypervisor/include/arch/x86/per_cpu.h @@ -39,6 +39,7 @@ struct per_cpu_region { struct sched_control sched_ctl; struct sched_noop_control sched_noop_ctl; struct sched_iorr_control sched_iorr_ctl; + struct sched_bvt_control sched_bvt_ctl; struct thread_object idle; struct host_gdt gdt; struct tss_64 tss; diff --git a/hypervisor/include/common/schedule.h b/hypervisor/include/common/schedule.h index 15268658a..6786fce10 100644 --- a/hypervisor/include/common/schedule.h +++ b/hypervisor/include/common/schedule.h @@ -90,6 +90,12 @@ struct sched_iorr_control { struct hv_timer tick_timer; }; +extern struct acrn_scheduler sched_bvt; +struct sched_bvt_control { + struct list_head runqueue; + struct hv_timer tick_timer; +}; + bool is_idle_thread(const struct thread_object *obj); uint16_t sched_get_pcpuid(const struct thread_object *obj); struct thread_object *sched_get_current(uint16_t pcpu_id);