hv: use vcpu_affinity[] in vm_config to support vcpu assignment

Add this vcpu_affinity[] for each VM to indicate the assignment policy.
With it, pcpu_bitmap is not needed, so remove it from vm_config.
Instead, vcpu_affinity is a must for each VM.

This patch also add some sanitize check of vcpu_affinity[]. Here are
some rules:
  1) only one bit can be set for each vcpu_affinity of vcpu.
  2) two vcpus in same VM cannot be set with same vcpu_affinity.
  3) vcpu_affinity cannot be set to the pcpu which used by pre-launched VM.

v4: config SDC with CONFIG_MAX_KATA_VM_NUM
v5: config SDC with CONFIG_MAX_PCPU_NUM

Tracked-On: #3663
Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com>
Signed-off-by: Yu Wang <yu1.wang@intel.com>
Signed-off-by: Shuo A Liu <shuo.a.liu@intel.com>
This commit is contained in:
Shuo A Liu
2019-05-23 13:57:09 +08:00
committed by ACRN System Integration
parent ca2540fe8c
commit 1c526e6d16
14 changed files with 74 additions and 27 deletions

View File

@@ -69,23 +69,40 @@ static bool check_vm_uuid_collision(uint16_t vm_id)
bool sanitize_vm_config(void)
{
bool ret = true;
uint16_t vm_id;
uint64_t sos_pcpu_bitmap, pre_launch_pcpu_bitmap;
uint16_t vm_id, vcpu_id, nr;
uint64_t sos_pcpu_bitmap, pre_launch_pcpu_bitmap = 0U, vm_pcpu_bitmap;
struct acrn_vm_config *vm_config;
sos_pcpu_bitmap = (uint64_t)((((uint64_t)1U) << get_pcpu_nums()) - 1U);
pre_launch_pcpu_bitmap = 0U;
/* All physical CPUs except ocuppied by Pre-launched VMs are all
* belong to SOS_VM. i.e. The pcpu_bitmap of a SOS_VM is decided
* by pcpu_bitmap status in PRE_LAUNCHED_VMs.
* belong to SOS_VM. i.e. The vm_pcpu_bitmap of a SOS_VM is decided
* by vm_pcpu_bitmap status in PRE_LAUNCHED_VMs.
* We need to setup a rule, that the vm_configs[] array should follow
* the order of PRE_LAUNCHED_VM first, and then SOS_VM.
*/
for (vm_id = 0U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
vm_config = get_vm_config(vm_id);
vm_pcpu_bitmap = 0U;
if (vm_config->load_order != SOS_VM) {
for (vcpu_id = 0U; vcpu_id < vm_config->vcpu_num; vcpu_id++) {
if (bitmap_weight(vm_config->vcpu_affinity[vcpu_id]) != 1U) {
pr_err("%s: vm%u vcpu%u should have only one prefer pcpu!",
__func__, vm_id, vcpu_id);
ret = false;
break;
}
vm_pcpu_bitmap |= vm_config->vcpu_affinity[vcpu_id];
}
if ((bitmap_weight(vm_pcpu_bitmap) != vm_config->vcpu_num)) {
pr_err("%s: One VM cannot have multiple vcpus share one pcpu!", __func__);
ret = false;
}
}
switch (vm_config->load_order) {
case PRE_LAUNCHED_VM:
if (vm_config->pcpu_bitmap == 0U) {
if (vm_config->vcpu_num == 0U) {
ret = false;
/* GUEST_FLAG_RT must be set if we have GUEST_FLAG_LAPIC_PASSTHROUGH set in guest_flags */
} else if (((vm_config->guest_flags & GUEST_FLAG_LAPIC_PASSTHROUGH) != 0U)
@@ -94,7 +111,7 @@ bool sanitize_vm_config(void)
}else if (vm_config->epc.size != 0UL) {
ret = false;
} else {
pre_launch_pcpu_bitmap |= vm_config->pcpu_bitmap;
pre_launch_pcpu_bitmap |= vm_pcpu_bitmap;
}
break;
case SOS_VM:
@@ -103,12 +120,19 @@ bool sanitize_vm_config(void)
if ((sos_pcpu_bitmap == 0U) || ((vm_config->guest_flags & GUEST_FLAG_LAPIC_PASSTHROUGH) != 0U)) {
ret = false;
} else {
vm_config->pcpu_bitmap = sos_pcpu_bitmap;
vm_config->vcpu_num = bitmap_weight(sos_pcpu_bitmap);
for (vcpu_id = 0U; vcpu_id < vm_config->vcpu_num; vcpu_id++) {
nr = ffs64(sos_pcpu_bitmap);
vm_config->vcpu_affinity[vcpu_id] = 1U << nr;
bitmap_clear_nolock(nr, &sos_pcpu_bitmap);
}
}
break;
case POST_LAUNCHED_VM:
/* Nothing to do here for a POST_LAUNCHED_VM, break directly. */
if ((vm_pcpu_bitmap == 0U) || ((vm_pcpu_bitmap & pre_launch_pcpu_bitmap) != 0U)) {
pr_err("%s: Post-launch VM has no pcpus or share pcpu with Pre-launch VM!", __func__);
ret = false;
}
break;
default:
/* Nothing to do for a unknown VM, break directly. */

View File

@@ -187,7 +187,6 @@ static inline void wait_for_other_vm_shutdown(const struct acrn_vm *self_vm)
static inline void enter_s5(const struct acrn_vm *vm, uint32_t pm1a_cnt_val, uint32_t pm1b_cnt_val)
{
wait_for_other_vm_shutdown(vm);
pr_err("yfwyfw: before enter s5");
host_enter_s5(vm->pm.sx_state_data, pm1a_cnt_val, pm1b_cnt_val);
}

View File

@@ -177,7 +177,7 @@ static inline uint16_t get_vm_bsp_pcpu_id(const struct acrn_vm_config *vm_config
{
uint16_t cpu_id = INVALID_CPU_ID;
cpu_id = ffs64(vm_config->pcpu_bitmap);
cpu_id = ffs64(vm_config->vcpu_affinity[0]);
return (cpu_id < get_pcpu_nums()) ? cpu_id : INVALID_CPU_ID;
}
@@ -724,18 +724,17 @@ void resume_vm_from_s3(struct acrn_vm *vm, uint32_t wakeup_vec)
void prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config)
{
int32_t err = 0;
uint16_t i;
uint16_t i, pcpu_id;
struct acrn_vm *vm = NULL;
err = create_vm(vm_id, vm_config, &vm);
if (err == 0) {
for (i = 0U; i < get_pcpu_nums(); i++) {
if (bitmap_test(i, &vm_config->pcpu_bitmap)) {
err = prepare_vcpu(vm, i);
if (err != 0) {
break;
}
for (i = 0U; i < vm_config->vcpu_num; i++) {
pcpu_id = ffs64(vm_config->vcpu_affinity[i]);
err = prepare_vcpu(vm, pcpu_id);
if (err != 0) {
break;
}
}
}