During checking for an available_idle_cpu, if the vCPU is yielded then check if it will be scheduled instantly by hypervisor or not. From guestOS, use H_IDLE_HINT hcall to ask for this hint from the hypverisor, and consider the yielded vCPU as target for wakeups iff it is hinted to be scheduled instantly.
Signed-off-by: Parth Shah <[email protected]> --- arch/powerpc/include/asm/paravirt.h | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/paravirt.h b/arch/powerpc/include/asm/paravirt.h index edc08f04aef7..c7dd0368e1a4 100644 --- a/arch/powerpc/include/asm/paravirt.h +++ b/arch/powerpc/include/asm/paravirt.h @@ -41,6 +41,15 @@ static inline void yield_to_any(void) { plpar_hcall_norets(H_CONFER, -1, 0); } + +/* Find if the previous physical CPU of this vcpu is available_idle or not */ +static inline void pcpu_available_instantly(int vcpu, unsigned long *is_idle) +{ + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + + if (plpar_hcall(H_IDLE_HINT, retbuf, vcpu) == H_SUCCESS) + *is_idle = retbuf[0]; +} #else static inline bool is_shared_processor(void) { @@ -75,6 +84,8 @@ static inline void prod_cpu(int cpu) #define vcpu_is_preempted vcpu_is_preempted static inline bool vcpu_is_preempted(int cpu) { + unsigned long is_idle = 0; + if (!is_shared_processor()) return false; @@ -92,8 +103,14 @@ static inline bool vcpu_is_preempted(int cpu) } #endif - if (yield_count_of(cpu) & 1) - return true; + if (yield_count_of(cpu) & 1) { +#ifdef CONFIG_PPC_SPLPAR + pcpu_available_instantly(cpu, &is_idle); +#endif + + if (!is_idle) + return true; + } return false; } -- 2.26.2
