aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/book3s_hv.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2015-03-27 23:21:06 -0400
committerAlexander Graf <agraf@suse.de>2015-04-21 09:21:32 -0400
commit5d5b99cd6818bdbea287d23ef055bba1a8a9e648 (patch)
tree1696dcf7ad7f1e566611093e18a387711c80aab7 /arch/powerpc/kvm/book3s_hv.c
parent25fedfca94cfbf2461314c6c34ef58e74a31b025 (diff)
KVM: PPC: Book3S HV: Get rid of vcore nap_count and n_woken
We can tell when a secondary thread has finished running a guest by the fact that it clears its kvm_hstate.kvm_vcpu pointer, so there is no real need for the nap_count field in the kvmppc_vcore struct. This changes kvmppc_wait_for_nap to poll the kvm_hstate.kvm_vcpu pointers of the secondary threads rather than polling vc->nap_count. Besides reducing the size of the kvmppc_vcore struct by 8 bytes, this also means that we can tell which secondary threads have got stuck and thus print a more informative error message. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kvm/book3s_hv.c')
-rw-r--r--arch/powerpc/kvm/book3s_hv.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index fb4f16628a51..7c1335dca4a5 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1729,8 +1729,10 @@ static int kvmppc_grab_hwthread(int cpu)
1729 tpaca = &paca[cpu]; 1729 tpaca = &paca[cpu];
1730 1730
1731 /* Ensure the thread won't go into the kernel if it wakes */ 1731 /* Ensure the thread won't go into the kernel if it wakes */
1732 tpaca->kvm_hstate.hwthread_req = 1;
1733 tpaca->kvm_hstate.kvm_vcpu = NULL; 1732 tpaca->kvm_hstate.kvm_vcpu = NULL;
1733 tpaca->kvm_hstate.napping = 0;
1734 smp_wmb();
1735 tpaca->kvm_hstate.hwthread_req = 1;
1734 1736
1735 /* 1737 /*
1736 * If the thread is already executing in the kernel (e.g. handling 1738 * If the thread is already executing in the kernel (e.g. handling
@@ -1773,35 +1775,43 @@ static void kvmppc_start_thread(struct kvm_vcpu *vcpu)
1773 } 1775 }
1774 cpu = vc->pcpu + vcpu->arch.ptid; 1776 cpu = vc->pcpu + vcpu->arch.ptid;
1775 tpaca = &paca[cpu]; 1777 tpaca = &paca[cpu];
1776 tpaca->kvm_hstate.kvm_vcpu = vcpu;
1777 tpaca->kvm_hstate.kvm_vcore = vc; 1778 tpaca->kvm_hstate.kvm_vcore = vc;
1778 tpaca->kvm_hstate.ptid = vcpu->arch.ptid; 1779 tpaca->kvm_hstate.ptid = vcpu->arch.ptid;
1779 vcpu->cpu = vc->pcpu; 1780 vcpu->cpu = vc->pcpu;
1781 /* Order stores to hstate.kvm_vcore etc. before store to kvm_vcpu */
1780 smp_wmb(); 1782 smp_wmb();
1783 tpaca->kvm_hstate.kvm_vcpu = vcpu;
1781#if defined(CONFIG_PPC_ICP_NATIVE) && defined(CONFIG_SMP) 1784#if defined(CONFIG_PPC_ICP_NATIVE) && defined(CONFIG_SMP)
1782 if (cpu != smp_processor_id()) { 1785 if (cpu != smp_processor_id())
1783 xics_wake_cpu(cpu); 1786 xics_wake_cpu(cpu);
1784 if (vcpu->arch.ptid)
1785 ++vc->n_woken;
1786 }
1787#endif 1787#endif
1788} 1788}
1789 1789
1790static void kvmppc_wait_for_nap(struct kvmppc_vcore *vc) 1790static void kvmppc_wait_for_nap(void)
1791{ 1791{
1792 int i; 1792 int cpu = smp_processor_id();
1793 int i, loops;
1793 1794
1794 HMT_low(); 1795 for (loops = 0; loops < 1000000; ++loops) {
1795 i = 0; 1796 /*
1796 while (vc->nap_count < vc->n_woken) { 1797 * Check if all threads are finished.
1797 if (++i >= 1000000) { 1798 * We set the vcpu pointer when starting a thread
1798 pr_err("kvmppc_wait_for_nap timeout %d %d\n", 1799 * and the thread clears it when finished, so we look
1799 vc->nap_count, vc->n_woken); 1800 * for any threads that still have a non-NULL vcpu ptr.
1800 break; 1801 */
1802 for (i = 1; i < threads_per_subcore; ++i)
1803 if (paca[cpu + i].kvm_hstate.kvm_vcpu)
1804 break;
1805 if (i == threads_per_subcore) {
1806 HMT_medium();
1807 return;
1801 } 1808 }
1802 cpu_relax(); 1809 HMT_low();
1803 } 1810 }
1804 HMT_medium(); 1811 HMT_medium();
1812 for (i = 1; i < threads_per_subcore; ++i)
1813 if (paca[cpu + i].kvm_hstate.kvm_vcpu)
1814 pr_err("KVM: CPU %d seems to be stuck\n", cpu + i);
1805} 1815}
1806 1816
1807/* 1817/*
@@ -1942,8 +1952,6 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc)
1942 /* 1952 /*
1943 * Initialize *vc. 1953 * Initialize *vc.
1944 */ 1954 */
1945 vc->n_woken = 0;
1946 vc->nap_count = 0;
1947 vc->entry_exit_count = 0; 1955 vc->entry_exit_count = 0;
1948 vc->preempt_tb = TB_NIL; 1956 vc->preempt_tb = TB_NIL;
1949 vc->in_guest = 0; 1957 vc->in_guest = 0;
@@ -2002,8 +2010,7 @@ static void kvmppc_run_core(struct kvmppc_vcore *vc)
2002 list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list) 2010 list_for_each_entry(vcpu, &vc->runnable_threads, arch.run_list)
2003 vcpu->cpu = -1; 2011 vcpu->cpu = -1;
2004 /* wait for secondary threads to finish writing their state to memory */ 2012 /* wait for secondary threads to finish writing their state to memory */
2005 if (vc->nap_count < vc->n_woken) 2013 kvmppc_wait_for_nap();
2006 kvmppc_wait_for_nap(vc);
2007 for (i = 0; i < threads_per_subcore; ++i) 2014 for (i = 0; i < threads_per_subcore; ++i)
2008 kvmppc_release_hwthread(vc->pcpu + i); 2015 kvmppc_release_hwthread(vc->pcpu + i);
2009 /* prevent other vcpu threads from doing kvmppc_start_thread() now */ 2016 /* prevent other vcpu threads from doing kvmppc_start_thread() now */