mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-06 06:02:20 +00:00
hv: sched: Add sched_params struct for thread parameters
Abstract out schedulers config data for vCPU threads and other hypervisor threads to sched_params structure. And it's used to initialize per thread scheduler private data. The sched_params for vCPU threads come from vm_config generated by config tools while other hypervisor threads need give them explicitly. Tracked-On: #8500 Signed-off-by: Qiang Zhang <qiang4.zhang@intel.com>
This commit is contained in:
parent
c000a3f70b
commit
6a1d91c740
@ -986,8 +986,7 @@ int32_t prepare_vcpu(struct acrn_vm *vm, uint16_t pcpu_id)
|
|||||||
vcpu->thread_obj.host_sp = build_stack_frame(vcpu);
|
vcpu->thread_obj.host_sp = build_stack_frame(vcpu);
|
||||||
vcpu->thread_obj.switch_out = context_switch_out;
|
vcpu->thread_obj.switch_out = context_switch_out;
|
||||||
vcpu->thread_obj.switch_in = context_switch_in;
|
vcpu->thread_obj.switch_in = context_switch_in;
|
||||||
vcpu->thread_obj.priority = get_vm_config(vm->vm_id)->vm_prio;
|
init_thread_data(&vcpu->thread_obj, &get_vm_config(vm->vm_id)->sched_params);
|
||||||
init_thread_data(&vcpu->thread_obj);
|
|
||||||
for (i = 0; i < VCPU_EVENT_NUM; i++) {
|
for (i = 0; i < VCPU_EVENT_NUM; i++) {
|
||||||
init_event(&vcpu->events[i]);
|
init_event(&vcpu->events[i]);
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,7 @@ void run_idle_thread(void)
|
|||||||
{
|
{
|
||||||
uint16_t pcpu_id = get_pcpu_id();
|
uint16_t pcpu_id = get_pcpu_id();
|
||||||
struct thread_object *idle = &per_cpu(idle, pcpu_id);
|
struct thread_object *idle = &per_cpu(idle, pcpu_id);
|
||||||
|
struct sched_params idle_params = {0};
|
||||||
char idle_name[16];
|
char idle_name[16];
|
||||||
|
|
||||||
snprintf(idle_name, 16U, "idle%hu", pcpu_id);
|
snprintf(idle_name, 16U, "idle%hu", pcpu_id);
|
||||||
@ -103,7 +104,8 @@ void run_idle_thread(void)
|
|||||||
idle->thread_entry = default_idle;
|
idle->thread_entry = default_idle;
|
||||||
idle->switch_out = NULL;
|
idle->switch_out = NULL;
|
||||||
idle->switch_in = NULL;
|
idle->switch_in = NULL;
|
||||||
idle->priority = PRIO_IDLE;
|
idle_params.prio = PRIO_IDLE;
|
||||||
|
init_thread_data(idle, &idle_params);
|
||||||
|
|
||||||
run_thread(idle);
|
run_thread(idle);
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ static void sched_bvt_deinit(struct sched_control *ctl)
|
|||||||
del_timer(&bvt_ctl->tick_timer);
|
del_timer(&bvt_ctl->tick_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sched_bvt_init_data(struct thread_object *obj)
|
static void sched_bvt_init_data(struct thread_object *obj, __unused struct sched_params * params)
|
||||||
{
|
{
|
||||||
struct sched_bvt_data *data;
|
struct sched_bvt_data *data;
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ void sched_iorr_deinit(struct sched_control *ctl)
|
|||||||
del_timer(&iorr_ctl->tick_timer);
|
del_timer(&iorr_ctl->tick_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sched_iorr_init_data(struct thread_object *obj)
|
void sched_iorr_init_data(struct thread_object *obj, __unused struct sched_params * params)
|
||||||
{
|
{
|
||||||
struct sched_iorr_data *data;
|
struct sched_iorr_data *data;
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
struct sched_prio_data {
|
struct sched_prio_data {
|
||||||
/* keep list as the first item */
|
/* keep list as the first item */
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
int priority;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int sched_prio_init(struct sched_control *ctl)
|
static int sched_prio_init(struct sched_control *ctl)
|
||||||
@ -25,12 +26,13 @@ static int sched_prio_init(struct sched_control *ctl)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sched_prio_init_data(struct thread_object *obj)
|
static void sched_prio_init_data(struct thread_object *obj, struct sched_params *params)
|
||||||
{
|
{
|
||||||
struct sched_prio_data *data;
|
struct sched_prio_data *data;
|
||||||
|
|
||||||
data = (struct sched_prio_data *)obj->data;
|
data = (struct sched_prio_data *)obj->data;
|
||||||
INIT_LIST_HEAD(&data->list);
|
INIT_LIST_HEAD(&data->list);
|
||||||
|
data->priority = params->priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct thread_object *sched_prio_pick_next(struct sched_control *ctl)
|
static struct thread_object *sched_prio_pick_next(struct sched_control *ctl)
|
||||||
@ -52,15 +54,15 @@ static void prio_queue_add(struct thread_object *obj)
|
|||||||
struct sched_prio_control *prio_ctl =
|
struct sched_prio_control *prio_ctl =
|
||||||
(struct sched_prio_control *)obj->sched_ctl->priv;
|
(struct sched_prio_control *)obj->sched_ctl->priv;
|
||||||
struct sched_prio_data *data = (struct sched_prio_data *)obj->data;
|
struct sched_prio_data *data = (struct sched_prio_data *)obj->data;
|
||||||
struct thread_object *iter_obj;
|
struct sched_prio_data *iter_data;
|
||||||
struct list_head *pos;
|
struct list_head *pos;
|
||||||
|
|
||||||
if (list_empty(&prio_ctl->prio_queue)) {
|
if (list_empty(&prio_ctl->prio_queue)) {
|
||||||
list_add(&data->list, &prio_ctl->prio_queue);
|
list_add(&data->list, &prio_ctl->prio_queue);
|
||||||
} else {
|
} else {
|
||||||
list_for_each(pos, &prio_ctl->prio_queue) {
|
list_for_each(pos, &prio_ctl->prio_queue) {
|
||||||
iter_obj = container_of(pos, struct thread_object, data);
|
iter_data = container_of(pos, struct sched_prio_data, list);
|
||||||
if (iter_obj->priority < obj->priority) {
|
if (iter_data->priority < data->priority) {
|
||||||
list_add_node(&data->list, pos->prev, pos);
|
list_add_node(&data->list, pos->prev, pos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -98,14 +98,14 @@ void deinit_sched(uint16_t pcpu_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_thread_data(struct thread_object *obj)
|
void init_thread_data(struct thread_object *obj, struct sched_params *params)
|
||||||
{
|
{
|
||||||
struct acrn_scheduler *scheduler = get_scheduler(obj->pcpu_id);
|
struct acrn_scheduler *scheduler = get_scheduler(obj->pcpu_id);
|
||||||
uint64_t rflag;
|
uint64_t rflag;
|
||||||
|
|
||||||
obtain_schedule_lock(obj->pcpu_id, &rflag);
|
obtain_schedule_lock(obj->pcpu_id, &rflag);
|
||||||
if (scheduler->init_data != NULL) {
|
if (scheduler->init_data != NULL) {
|
||||||
scheduler->init_data(obj);
|
scheduler->init_data(obj, params);
|
||||||
}
|
}
|
||||||
/* initial as BLOCKED status, so we can wake it up to run */
|
/* initial as BLOCKED status, so we can wake it up to run */
|
||||||
set_thread_status(obj, THREAD_STS_BLOCKED);
|
set_thread_status(obj, THREAD_STS_BLOCKED);
|
||||||
@ -241,7 +241,6 @@ void run_thread(struct thread_object *obj)
|
|||||||
{
|
{
|
||||||
uint64_t rflag;
|
uint64_t rflag;
|
||||||
|
|
||||||
init_thread_data(obj);
|
|
||||||
obtain_schedule_lock(obj->pcpu_id, &rflag);
|
obtain_schedule_lock(obj->pcpu_id, &rflag);
|
||||||
get_cpu_var(sched_ctl).curr_obj = obj;
|
get_cpu_var(sched_ctl).curr_obj = obj;
|
||||||
set_thread_status(obj, THREAD_STS_RUNNING);
|
set_thread_status(obj, THREAD_STS_RUNNING);
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <vm_configurations.h>
|
#include <vm_configurations.h>
|
||||||
#include <asm/sgx.h>
|
#include <asm/sgx.h>
|
||||||
#include <acrn_hv_defs.h>
|
#include <acrn_hv_defs.h>
|
||||||
|
#include <schedule.h>
|
||||||
|
|
||||||
#define AFFINITY_CPU(n) (1UL << (n))
|
#define AFFINITY_CPU(n) (1UL << (n))
|
||||||
#define MAX_VCPUS_PER_VM MAX_PCPU_NUM
|
#define MAX_VCPUS_PER_VM MAX_PCPU_NUM
|
||||||
@ -170,7 +171,7 @@ struct acrn_vm_config {
|
|||||||
* GUEST_FLAG_LAPIC_PASSTHROUGH
|
* GUEST_FLAG_LAPIC_PASSTHROUGH
|
||||||
* We could add more guest flags in future;
|
* We could add more guest flags in future;
|
||||||
*/
|
*/
|
||||||
uint32_t vm_prio; /* The priority for VM vCPU scheduling */
|
struct sched_params sched_params; /* Scheduler params for vCPUs of this VM */
|
||||||
uint16_t companion_vm_id; /* The companion VM id for this VM */
|
uint16_t companion_vm_id; /* The companion VM id for this VM */
|
||||||
struct acrn_vm_mem_config memory; /* memory configuration of VM */
|
struct acrn_vm_mem_config memory; /* memory configuration of VM */
|
||||||
struct epc_section epc; /* EPC memory configuration of VM */
|
struct epc_section epc; /* EPC memory configuration of VM */
|
||||||
|
@ -34,6 +34,16 @@ enum thread_priority {
|
|||||||
PRIO_MAX
|
PRIO_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For now, we just have several parameters for all the schedulers. So we
|
||||||
|
* put them together here for simplicity. TODO When this structure grows big
|
||||||
|
* enough, we need to replace it with a union of parameters of different
|
||||||
|
* schedulers.
|
||||||
|
*/
|
||||||
|
struct sched_params {
|
||||||
|
uint32_t prio; /* The priority of a thread */
|
||||||
|
};
|
||||||
|
|
||||||
struct thread_object;
|
struct thread_object;
|
||||||
typedef void (*thread_entry_t)(struct thread_object *obj);
|
typedef void (*thread_entry_t)(struct thread_object *obj);
|
||||||
typedef void (*switch_t)(struct thread_object *obj);
|
typedef void (*switch_t)(struct thread_object *obj);
|
||||||
@ -49,8 +59,6 @@ struct thread_object {
|
|||||||
switch_t switch_out;
|
switch_t switch_out;
|
||||||
switch_t switch_in;
|
switch_t switch_in;
|
||||||
|
|
||||||
int priority;
|
|
||||||
|
|
||||||
uint8_t data[THREAD_DATA_SIZE];
|
uint8_t data[THREAD_DATA_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,7 +78,7 @@ struct acrn_scheduler {
|
|||||||
/* init scheduler */
|
/* init scheduler */
|
||||||
int32_t (*init)(struct sched_control *ctl);
|
int32_t (*init)(struct sched_control *ctl);
|
||||||
/* init private data of scheduler */
|
/* init private data of scheduler */
|
||||||
void (*init_data)(struct thread_object *obj);
|
void (*init_data)(struct thread_object *obj, struct sched_params *params);
|
||||||
/* pick the next thread object */
|
/* pick the next thread object */
|
||||||
struct thread_object* (*pick_next)(struct sched_control *ctl);
|
struct thread_object* (*pick_next)(struct sched_control *ctl);
|
||||||
/* put thread object into sleep */
|
/* put thread object into sleep */
|
||||||
@ -120,7 +128,7 @@ void deinit_sched(uint16_t pcpu_id);
|
|||||||
void obtain_schedule_lock(uint16_t pcpu_id, uint64_t *rflag);
|
void obtain_schedule_lock(uint16_t pcpu_id, uint64_t *rflag);
|
||||||
void release_schedule_lock(uint16_t pcpu_id, uint64_t rflag);
|
void release_schedule_lock(uint16_t pcpu_id, uint64_t rflag);
|
||||||
|
|
||||||
void init_thread_data(struct thread_object *obj);
|
void init_thread_data(struct thread_object *obj, struct sched_params *params);
|
||||||
void deinit_thread_data(struct thread_object *obj);
|
void deinit_thread_data(struct thread_object *obj);
|
||||||
|
|
||||||
void make_reschedule_request(uint16_t pcpu_id);
|
void make_reschedule_request(uint16_t pcpu_id);
|
||||||
|
@ -22,7 +22,10 @@ struct acrn_vm_config
|
|||||||
/* Static configured VM0 */
|
/* Static configured VM0 */
|
||||||
CONFIG_PRE_STD_VM,
|
CONFIG_PRE_STD_VM,
|
||||||
.name = "SAFETY_VM0",
|
.name = "SAFETY_VM0",
|
||||||
.vm_prio = PRIO_LOW,
|
.sched_params =
|
||||||
|
{
|
||||||
|
.prio = PRIO_LOW,
|
||||||
|
},
|
||||||
.companion_vm_id = 65535U,
|
.companion_vm_id = 65535U,
|
||||||
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
||||||
.cpu_affinity = VM0_CONFIG_CPU_AFFINITY,
|
.cpu_affinity = VM0_CONFIG_CPU_AFFINITY,
|
||||||
@ -106,7 +109,10 @@ struct acrn_vm_config
|
|||||||
CONFIG_SERVICE_VM,
|
CONFIG_SERVICE_VM,
|
||||||
.name = "ACRN_Service_VM",
|
.name = "ACRN_Service_VM",
|
||||||
/* Allow Service VM to reboot the system since it is the highest priority VM. */
|
/* Allow Service VM to reboot the system since it is the highest priority VM. */
|
||||||
.vm_prio = PRIO_LOW,
|
.sched_params =
|
||||||
|
{
|
||||||
|
.prio = PRIO_LOW,
|
||||||
|
},
|
||||||
.companion_vm_id = 65535U,
|
.companion_vm_id = 65535U,
|
||||||
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
||||||
.cpu_affinity = SERVICE_VM_CONFIG_CPU_AFFINITY,
|
.cpu_affinity = SERVICE_VM_CONFIG_CPU_AFFINITY,
|
||||||
@ -163,7 +169,10 @@ struct acrn_vm_config
|
|||||||
/* Static configured VM2 */
|
/* Static configured VM2 */
|
||||||
CONFIG_POST_STD_VM,
|
CONFIG_POST_STD_VM,
|
||||||
.name = "POST_STD_VM1",
|
.name = "POST_STD_VM1",
|
||||||
.vm_prio = PRIO_LOW,
|
.sched_params =
|
||||||
|
{
|
||||||
|
.prio = PRIO_LOW,
|
||||||
|
},
|
||||||
.companion_vm_id = 65535U,
|
.companion_vm_id = 65535U,
|
||||||
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
||||||
.cpu_affinity = VM2_CONFIG_CPU_AFFINITY,
|
.cpu_affinity = VM2_CONFIG_CPU_AFFINITY,
|
||||||
@ -186,7 +195,10 @@ struct acrn_vm_config
|
|||||||
/* Static configured VM3 */
|
/* Static configured VM3 */
|
||||||
CONFIG_POST_STD_VM,
|
CONFIG_POST_STD_VM,
|
||||||
.name = "POST_STD_VM2",
|
.name = "POST_STD_VM2",
|
||||||
.vm_prio = PRIO_LOW,
|
.sched_params =
|
||||||
|
{
|
||||||
|
.prio = PRIO_LOW,
|
||||||
|
},
|
||||||
.companion_vm_id = 65535U,
|
.companion_vm_id = 65535U,
|
||||||
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
||||||
.cpu_affinity = VM3_CONFIG_CPU_AFFINITY,
|
.cpu_affinity = VM3_CONFIG_CPU_AFFINITY,
|
||||||
|
@ -25,7 +25,10 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
|
|||||||
/* Static configured VM0 */
|
/* Static configured VM0 */
|
||||||
CONFIG_PRE_STD_VM,
|
CONFIG_PRE_STD_VM,
|
||||||
.name = "PRE_STD_VM0",
|
.name = "PRE_STD_VM0",
|
||||||
.vm_prio = PRIO_LOW,
|
.sched_params =
|
||||||
|
{
|
||||||
|
.prio = PRIO_LOW,
|
||||||
|
},
|
||||||
.companion_vm_id = 65535U,
|
.companion_vm_id = 65535U,
|
||||||
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
||||||
.cpu_affinity = VM0_CONFIG_CPU_AFFINITY,
|
.cpu_affinity = VM0_CONFIG_CPU_AFFINITY,
|
||||||
@ -102,7 +105,10 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
|
|||||||
/* Static configured VM1 */
|
/* Static configured VM1 */
|
||||||
CONFIG_PRE_STD_VM,
|
CONFIG_PRE_STD_VM,
|
||||||
.name = "PRE_STD_VM1",
|
.name = "PRE_STD_VM1",
|
||||||
.vm_prio = PRIO_LOW,
|
.sched_params =
|
||||||
|
{
|
||||||
|
.prio = PRIO_LOW,
|
||||||
|
},
|
||||||
.companion_vm_id = 65535U,
|
.companion_vm_id = 65535U,
|
||||||
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
||||||
.cpu_affinity = VM1_CONFIG_CPU_AFFINITY,
|
.cpu_affinity = VM1_CONFIG_CPU_AFFINITY,
|
||||||
|
@ -17,7 +17,10 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
|
|||||||
CONFIG_SERVICE_VM,
|
CONFIG_SERVICE_VM,
|
||||||
.name = "ACRN_Service_VM",
|
.name = "ACRN_Service_VM",
|
||||||
/* Allow Service VM to reboot the system since it is the highest priority VM. */
|
/* Allow Service VM to reboot the system since it is the highest priority VM. */
|
||||||
.vm_prio = PRIO_LOW,
|
.sched_params =
|
||||||
|
{
|
||||||
|
.prio = PRIO_LOW,
|
||||||
|
},
|
||||||
.companion_vm_id = 65535U,
|
.companion_vm_id = 65535U,
|
||||||
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
||||||
.cpu_affinity = SERVICE_VM_CONFIG_CPU_AFFINITY,
|
.cpu_affinity = SERVICE_VM_CONFIG_CPU_AFFINITY,
|
||||||
@ -74,7 +77,10 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
|
|||||||
/* Static configured VM1 */
|
/* Static configured VM1 */
|
||||||
CONFIG_POST_STD_VM,
|
CONFIG_POST_STD_VM,
|
||||||
.name = "POST_STD_VM1",
|
.name = "POST_STD_VM1",
|
||||||
.vm_prio = PRIO_LOW,
|
.sched_params =
|
||||||
|
{
|
||||||
|
.prio = PRIO_LOW,
|
||||||
|
},
|
||||||
.companion_vm_id = 65535U,
|
.companion_vm_id = 65535U,
|
||||||
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
.guest_flags = (GUEST_FLAG_STATIC_VM),
|
||||||
.cpu_affinity = VM1_CONFIG_CPU_AFFINITY,
|
.cpu_affinity = VM1_CONFIG_CPU_AFFINITY,
|
||||||
@ -105,7 +111,10 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
|
|||||||
/* Static configured VM2 */
|
/* Static configured VM2 */
|
||||||
CONFIG_POST_RT_VM,
|
CONFIG_POST_RT_VM,
|
||||||
.name = "POST_RT_VM1",
|
.name = "POST_RT_VM1",
|
||||||
.vm_prio = PRIO_LOW,
|
.sched_params =
|
||||||
|
{
|
||||||
|
.prio = PRIO_LOW,
|
||||||
|
},
|
||||||
.companion_vm_id = 65535U,
|
.companion_vm_id = 65535U,
|
||||||
.guest_flags = (GUEST_FLAG_LAPIC_PASSTHROUGH | GUEST_FLAG_RT | GUEST_FLAG_STATIC_VM),
|
.guest_flags = (GUEST_FLAG_LAPIC_PASSTHROUGH | GUEST_FLAG_RT | GUEST_FLAG_STATIC_VM),
|
||||||
.cpu_affinity = VM2_CONFIG_CPU_AFFINITY,
|
.cpu_affinity = VM2_CONFIG_CPU_AFFINITY,
|
||||||
|
@ -110,7 +110,10 @@
|
|||||||
<xsl:value-of select="acrn:comment('Allow Service VM to reboot the system since it is the highest priority VM.')" />
|
<xsl:value-of select="acrn:comment('Allow Service VM to reboot the system since it is the highest priority VM.')" />
|
||||||
<xsl:value-of select="$newline" />
|
<xsl:value-of select="$newline" />
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
<xsl:value-of select="acrn:initializer('vm_prio', priority)" />
|
<xsl:value-of select="acrn:initializer('sched_params', '{', true())" />
|
||||||
|
<xsl:value-of select="acrn:initializer('prio', priority)" />
|
||||||
|
<xsl:text>},</xsl:text>
|
||||||
|
<xsl:value-of select="$newline" />
|
||||||
<xsl:value-of select="acrn:initializer('companion_vm_id', concat(companion_vmid, 'U'))" />
|
<xsl:value-of select="acrn:initializer('companion_vm_id', concat(companion_vmid, 'U'))" />
|
||||||
<xsl:call-template name="guest_flags" />
|
<xsl:call-template name="guest_flags" />
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user