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

Reply via email to