linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Michael Ellerman <mpe@ellerman.id.au>
To: Michael Bringmann <mwb@linux.vnet.ibm.com>,
	linuxppc-dev@lists.ozlabs.org, Juliet Kim <minkim@us.ibm.com>,
	Tyrel Datwyler <tyreld@linux.vnet.ibm.com>,
	Thomas Falcon <tlfalcon@linux.vnet.ibm.com>,
	Nathan Lynch <nathanl@linux.vnet.ibm.com>,
	Gustavo Walbon <gwalbon@linux.vnet.ibm.com>,
	mwb@linux.vnet.ibm.com
Subject: Re: [PATCH v02] powerpc/pseries: Check for ceded CPU's during LPAR migration
Date: Thu, 31 Jan 2019 16:38:51 +1100	[thread overview]
Message-ID: <8736p9pes4.fsf@concordia.ellerman.id.au> (raw)
In-Reply-To: <20190130212220.11315.76901.stgit@ltcalpine2-lp20.aus.stglabs.ibm.com>

Michael Bringmann <mwb@linux.vnet.ibm.com> writes:
> This patch is to check for cede'ed CPUs during LPM.  Some extreme
> tests encountered a problem ehere Linux has put some threads to
> sleep (possibly to save energy or something), LPM was attempted,
> and the Linux kernel didn't awaken the sleeping threads, but issued
> the H_JOIN for the active threads.  Since the sleeping threads
> are not awake, they can not issue the expected H_JOIN, and the
> partition would never suspend.  This patch wakes the sleeping
> threads back up.

I'm don't think this is the right solution.

Just after your for loop we do an on_each_cpu() call, which sends an IPI
to every CPU, and that should wake all CPUs up from CEDE.

If that's not happening then there is a bug somewhere, and we need to
work out where.


> diff --git a/arch/powerpc/include/asm/plpar_wrappers.h b/arch/powerpc/include/asm/plpar_wrappers.h
> index cff5a41..8292eff 100644
> --- a/arch/powerpc/include/asm/plpar_wrappers.h
> +++ b/arch/powerpc/include/asm/plpar_wrappers.h
> @@ -26,10 +26,8 @@ static inline void set_cede_latency_hint(u8 latency_hint)
>  	get_lppaca()->cede_latency_hint = latency_hint;
>  }
>  
> -static inline long cede_processor(void)
> -{
> -	return plpar_hcall_norets(H_CEDE);
> -}
> +int cpu_is_ceded(int cpu);
> +long cede_processor(void);
>  
>  static inline long extended_cede_processor(unsigned long latency_hint)
>  {
> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> index de35bd8f..fea3d21 100644
> --- a/arch/powerpc/kernel/rtas.c
> +++ b/arch/powerpc/kernel/rtas.c
> @@ -44,6 +44,7 @@
>  #include <asm/time.h>
>  #include <asm/mmu.h>
>  #include <asm/topology.h>
> +#include <asm/plpar_wrappers.h>
>  
>  /* This is here deliberately so it's only used in this file */
>  void enter_rtas(unsigned long);
> @@ -942,7 +943,7 @@ int rtas_ibm_suspend_me(u64 handle)
>  	struct rtas_suspend_me_data data;
>  	DECLARE_COMPLETION_ONSTACK(done);
>  	cpumask_var_t offline_mask;
> -	int cpuret;
> +	int cpuret, cpu;
>  
>  	if (!rtas_service_present("ibm,suspend-me"))
>  		return -ENOSYS;
> @@ -991,6 +992,11 @@ int rtas_ibm_suspend_me(u64 handle)
>  		goto out_hotplug_enable;
>  	}
>  
> +	for_each_present_cpu(cpu) {
> +		if (cpu_is_ceded(cpu))
> +			plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu));
> +	}

There's a race condition here, there's nothing to prevent the CPUs you
just PROD'ed from going back into CEDE before you do the on_each_cpu()
call below.

>  	/* Call function on all CPUs.  One of us will make the
>  	 * rtas call
>  	 */
> diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
> index 41f62ca2..48ae6d4 100644
> --- a/arch/powerpc/platforms/pseries/setup.c
> +++ b/arch/powerpc/platforms/pseries/setup.c
> @@ -331,6 +331,24 @@ static int alloc_dispatch_log_kmem_cache(void)
>  }
>  machine_early_initcall(pseries, alloc_dispatch_log_kmem_cache);
>  
> +static DEFINE_PER_CPU(int, cpu_ceded);
> +
> +int cpu_is_ceded(int cpu)
> +{
> +	return per_cpu(cpu_ceded, cpu);
> +}
> +
> +long cede_processor(void)
> +{
> +	long rc;
> +
> +	per_cpu(cpu_ceded, raw_smp_processor_id()) = 1;

And there's also a race condition here. From the other CPU's perspective
the store to cpu_ceded is not necessarily ordered vs the hcall below.
Which means the other CPU can see cpu_ceded = 0, and therefore not prod
us, but this CPU has already called H_CEDE.

> +	rc = plpar_hcall_norets(H_CEDE);
> +	per_cpu(cpu_ceded, raw_smp_processor_id()) = 0;
> +
> +	return rc;
> +}
> +
>  static void pseries_lpar_idle(void)
>  {
>  	/*

cheers

  reply	other threads:[~2019-01-31  5:40 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-30 21:23 [PATCH v02] powerpc/pseries: Check for ceded CPU's during LPAR migration Michael Bringmann
2019-01-31  5:38 ` Michael Ellerman [this message]
2019-01-31 21:53   ` Michael Bringmann
2019-01-31 22:21     ` Tyrel Datwyler
2019-01-31 22:30       ` Michael Bringmann
2019-01-31 22:34       ` Tyrel Datwyler
2019-02-05 10:05         ` Michael Ellerman
2019-02-01 14:14     ` Michael Bringmann
2019-02-05 10:24       ` Michael Ellerman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8736p9pes4.fsf@concordia.ellerman.id.au \
    --to=mpe@ellerman.id.au \
    --cc=gwalbon@linux.vnet.ibm.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=minkim@us.ibm.com \
    --cc=mwb@linux.vnet.ibm.com \
    --cc=nathanl@linux.vnet.ibm.com \
    --cc=tlfalcon@linux.vnet.ibm.com \
    --cc=tyreld@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).