From 5f8e7a6cb7e1d55c7c169804be7c7d292fd1fb9c Mon Sep 17 00:00:00 2001 From: Shuo A Liu Date: Tue, 18 Jun 2019 17:49:56 +0800 Subject: [PATCH] hv: sched: add kick_thread to support notification kick means to notify one thread_object. If the target thread object is running, send a IPI to notify it; if the target thread object is runnable, make reschedule on it. Also add kick_vcpu API in vcpu layer to notify vcpu. Tracked-On: #3813 Signed-off-by: Jason Chen CJ Signed-off-by: Yu Wang Signed-off-by: Shuo A Liu Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/vcpu.c | 5 +++++ hypervisor/arch/x86/guest/virq.c | 15 +-------------- hypervisor/common/schedule.c | 18 ++++++++++++++++++ hypervisor/include/arch/x86/guest/vcpu.h | 11 +++++++++++ hypervisor/include/common/schedule.h | 1 + 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/hypervisor/arch/x86/guest/vcpu.c b/hypervisor/arch/x86/guest/vcpu.c index 9980cd907..b86f53347 100644 --- a/hypervisor/arch/x86/guest/vcpu.c +++ b/hypervisor/arch/x86/guest/vcpu.c @@ -598,6 +598,11 @@ void offline_vcpu(struct acrn_vcpu *vcpu) vcpu->state = VCPU_OFFLINE; } +void kick_vcpu(const struct acrn_vcpu *vcpu) +{ + kick_thread(&vcpu->thread_obj); +} + /* * @pre (&vcpu->stack[CONFIG_STACK_SIZE] & (CPU_STACK_ALIGN - 1UL)) == 0 */ diff --git a/hypervisor/arch/x86/guest/virq.c b/hypervisor/arch/x86/guest/virq.c index ee119c609..603585345 100644 --- a/hypervisor/arch/x86/guest/virq.c +++ b/hypervisor/arch/x86/guest/virq.c @@ -106,21 +106,8 @@ static bool is_guest_irq_enabled(struct acrn_vcpu *vcpu) void vcpu_make_request(struct acrn_vcpu *vcpu, uint16_t eventid) { - uint16_t pcpu_id = pcpuid_from_vcpu(vcpu); - bitmap_set_lock(eventid, &vcpu->arch.pending_req); - /* - * if current hostcpu is not the target vcpu's hostcpu, we need - * to invoke IPI to wake up target vcpu - * - * TODO: Here we just compare with cpuid, since cpuid currently is - * global under pCPU / vCPU 1:1 mapping. If later we enabled vcpu - * scheduling, we need change here to determine it target vcpu is - * VMX non-root or root mode - */ - if (get_pcpu_id() != pcpu_id) { - send_single_ipi(pcpu_id, VECTOR_NOTIFY_VCPU); - } + kick_vcpu(vcpu); } /* diff --git a/hypervisor/common/schedule.c b/hypervisor/common/schedule.c index e3addc3b0..847bafd03 100644 --- a/hypervisor/common/schedule.c +++ b/hypervisor/common/schedule.c @@ -222,6 +222,24 @@ void wake_thread(struct thread_object *obj) release_schedule_lock(pcpu_id, rflag); } +void kick_thread(const struct thread_object *obj) +{ + uint16_t pcpu_id = obj->pcpu_id; + uint64_t rflag; + + obtain_schedule_lock(pcpu_id, &rflag); + if (is_running(obj)) { + if (get_pcpu_id() != pcpu_id) { + send_single_ipi(pcpu_id, VECTOR_NOTIFY_VCPU); + } + } else if (is_runnable(obj)) { + make_reschedule_request(pcpu_id, DEL_MODE_IPI); + } else { + /* do nothing */ + } + release_schedule_lock(pcpu_id, rflag); +} + void run_thread(struct thread_object *obj) { uint64_t rflag; diff --git a/hypervisor/include/arch/x86/guest/vcpu.h b/hypervisor/include/arch/x86/guest/vcpu.h index cee27e0b7..3d5578f81 100644 --- a/hypervisor/include/arch/x86/guest/vcpu.h +++ b/hypervisor/include/arch/x86/guest/vcpu.h @@ -636,6 +636,17 @@ void resume_vcpu(struct acrn_vcpu *vcpu); */ void launch_vcpu(struct acrn_vcpu *vcpu); +/** + * @brief kick the vcpu and let it handle pending events + * + * Kick a vCPU to handle the pending events. + * + * @param[in] vcpu pointer to vcpu data structure + * + * @return None + */ +void kick_vcpu(const struct acrn_vcpu *vcpu); + /** * @brief create a vcpu for the vm and mapped to the pcpu. * diff --git a/hypervisor/include/common/schedule.h b/hypervisor/include/common/schedule.h index 4a3b39f4d..808beacca 100644 --- a/hypervisor/include/common/schedule.h +++ b/hypervisor/include/common/schedule.h @@ -100,6 +100,7 @@ bool need_reschedule(uint16_t pcpu_id); void run_thread(struct thread_object *obj); void sleep_thread(struct thread_object *obj); void wake_thread(struct thread_object *obj); +void kick_thread(const struct thread_object *obj); void schedule(void); void arch_switch_to(void *prev_sp, void *next_sp);