Received: by 10.223.185.116 with SMTP id b49csp6685803wrg; Wed, 28 Feb 2018 13:42:24 -0800 (PST) X-Google-Smtp-Source: AH8x227FDEf0SBIgzV89R7YtLsUOVkvXbMseeYEHfb9iT3QRdrw0mXDHuJdmTiItx3Yzmf9jzSoB X-Received: by 10.99.175.8 with SMTP id w8mr14682287pge.390.1519854144397; Wed, 28 Feb 2018 13:42:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519854144; cv=none; d=google.com; s=arc-20160816; b=F7qafIvhObmN8iDkjFD+bt1OAz60IH8VWS1n7nDUj+R07G5NZIVyVJ0ThZCsUzo7QH xhA8ZKGcdfO0590k55EVaiCvPknr0o1KNfMOJuS9eJC4zX+fuXsJ17F47/yINW9K6iZv uz1vKIoMd5wzc+hAUndjrrKWR2WVrLuL5E7bPhkbCNUXYkz+YoABozuCirpDahIACo3b TalZBfvp3thAzlOVV7NPCGzi+tx7N6OtSkkz+75+Y4WQ5GX/A7sGwB96/mzs402LlaeY sGlxgJJZ2N9nfEpuWPUaaPvn+8za8MJl8xycsWDAif4EaGM5MJCCXe/c7iuosJU7EQW+ z/dQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:content-transfer-encoding :mime-version:organization:references:in-reply-to:date:cc:to :reply-to:from:subject:arc-authentication-results; bh=dLJxa9MLOO4nGlnSuvdAOahl42CJqWG26WBjJK9V4Z8=; b=08ZmL+jGAw4jTs3/5Twl58y9xEvxCS6cRvDq3dACgvF9UrHzdq+gxDx4C2I02w3V7v Zq6BlthkNWyWszWT1U+b0SZtkUjO9ablkWSKgC99kjE24/DPcYTahTkX4NN9pvEXMC/Y NZBG+yteEjRsM4Yj2yyDURiAX9Q+9BNEWLXH+nM67bq3gnonKL/j+NWkviFrx9W7BmBa oZdYWwIJypQtgZpVcEc9dS2oW9+sJ/IY1FiJEc3Z32hUP4uLraY8anVYRF76/AaKvgJN nmJ2QFr0axefFgVpmlDvPKptM3bWijAi7cn2T8kWcEBSHkr8CtPfRSu6xIrFUg/F3q7U L8Dw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d19-v6si1829448pls.822.2018.02.28.13.42.09; Wed, 28 Feb 2018 13:42:24 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935198AbeB1Vki (ORCPT + 99 others); Wed, 28 Feb 2018 16:40:38 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:53372 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935177AbeB1Vke (ORCPT ); Wed, 28 Feb 2018 16:40:34 -0500 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w1SLYaw9008025 for ; Wed, 28 Feb 2018 16:40:33 -0500 Received: from e06smtp12.uk.ibm.com (e06smtp12.uk.ibm.com [195.75.94.108]) by mx0a-001b2d01.pphosted.com with ESMTP id 2ge39xk51s-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 28 Feb 2018 16:40:32 -0500 Received: from localhost by e06smtp12.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 28 Feb 2018 21:40:29 -0000 Received: from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198) by e06smtp12.uk.ibm.com (192.168.101.142) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 28 Feb 2018 21:40:26 -0000 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w1SLeQwc48300068; Wed, 28 Feb 2018 21:40:26 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E3DAF4C04A; Wed, 28 Feb 2018 21:33:54 +0000 (GMT) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 498434C046; Wed, 28 Feb 2018 21:33:54 +0000 (GMT) Received: from ozlabs.au.ibm.com (unknown [9.192.253.14]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Wed, 28 Feb 2018 21:33:54 +0000 (GMT) Received: from pasglop (unknown [9.192.160.12]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.au.ibm.com (Postfix) with ESMTPSA id A1D4AA01FB; Thu, 1 Mar 2018 08:40:23 +1100 (AEDT) Subject: Re: [RESEND][PATCH] cpuidle/powernv : Restore different PSSCR for idle and hotplug From: Benjamin Herrenschmidt Reply-To: benh@au1.ibm.com To: Akshay Adiga , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Cc: stable@vger.kernel.org, npiggin@gmail.com Date: Thu, 01 Mar 2018 08:40:22 +1100 In-Reply-To: <1519846389-29414-1-git-send-email-akshay.adiga@linux.vnet.ibm.com> References: <1519846389-29414-1-git-send-email-akshay.adiga@linux.vnet.ibm.com> Organization: IBM Australia Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.26.5 (3.26.5-1.fc27) Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-TM-AS-GCONF: 00 x-cbid: 18022821-0008-0000-0000-000004D6288C X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18022821-0009-0000-0000-00001E6929F4 Message-Id: <1519854022.2520.12.camel@au1.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2018-02-28_12:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1011 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1802280262 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, 2018-03-01 at 01:03 +0530, Akshay Adiga wrote: > commit 1e1601b38e6e ("powerpc/powernv/idle: Restore SPRs for deep idle > states via stop API.") uses stop-api provided by the firmware to restore > PSSCR. PSSCR restore is required for handling special wakeup. When special > wakeup is completed, the core enters stop state based on restored PSSCR. > > Currently PSSCR is restored to deepest available stop state, causing > a idle cpu to enter deeper stop state on a special wakeup, which causes > the cpu to hang on wakeup. > > A "sensors" command which reads temperature (through DTS sensors) on idle > cpu can trigger special wakeup. > > Failed Scenario : > Request restore of PSSCR with RL = 11 > cpu enters idle state (stop5) > user triggers "sensors" command > Assert special wakeup on cpu > Restores PSSCR with RL = 11 <---- Done by firmware > Read DTS sensor > Deassert special wakeup > cpu enters idle state (stop11) <-- Instead of stop5 > > Cpu hang is caused because cpu ended up in a deeper state than it requested > > This patch fixes instability caused by special wakeup when stop11 is > enabled. Requests restore of PSSCR to deepest stop state used by cpuidle. > Only when offlining cpu, request restore of PSSCR to deepest stop state. > On onlining cpu, request restore of PSSCR to deepest stop state used by > cpuidle. So if we chose a stop state, but somebody else does a special wakeup, we'll end up going back into a *deeper* one than the one we came from ? I still think this is broken by design. The chip should automatically go back to the state it went to after special wakeup, thus the PPE controlling the state should override the PSSCR value accordingly rather than relying on those SW hoops. > > Cc: # v4.14+ > Fixes : 1e1601b38e6e ("powerpc/powernv/idle: Restore SPRs for deep idle > states via stop API.") > Reported-by: Pridhiviraj Paidipeddi > Signed-off-by: Akshay Adiga > --- > arch/powerpc/include/asm/cpuidle.h | 2 ++ > arch/powerpc/platforms/powernv/idle.c | 46 ++++++++++++++++++++++++++++++++--- > drivers/cpuidle/cpuidle-powernv.c | 1 - > 3 files changed, 45 insertions(+), 4 deletions(-) > > diff --git a/arch/powerpc/include/asm/cpuidle.h b/arch/powerpc/include/asm/cpuidle.h > index e210a83..f52e9f1 100644 > --- a/arch/powerpc/include/asm/cpuidle.h > +++ b/arch/powerpc/include/asm/cpuidle.h > @@ -67,6 +67,8 @@ > #define ERR_EC_ESL_MISMATCH -1 > #define ERR_DEEP_STATE_ESL_MISMATCH -2 > > +#define POWERNV_THRESHOLD_LATENCY_NS 200000 > + > #ifndef __ASSEMBLY__ > /* Additional SPRs that need to be saved/restored during stop */ > struct stop_sprs { > diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c > index 443d5ca..4b0c7d24 100644 > --- a/arch/powerpc/platforms/powernv/idle.c > +++ b/arch/powerpc/platforms/powernv/idle.c > @@ -56,8 +56,11 @@ u64 pnv_first_deep_stop_state = MAX_STOP_STATE; > */ > static u64 pnv_deepest_stop_psscr_val; > static u64 pnv_deepest_stop_psscr_mask; > +static u64 pnv_deepest_cpuidle_psscr_val; > +static u64 pnv_deepest_cpuidle_psscr_mask; > static u64 pnv_deepest_stop_flag; > static bool deepest_stop_found; > +static bool deepest_cpuidle_found; > > static int pnv_save_sprs_for_deep_states(void) > { > @@ -76,7 +79,14 @@ static int pnv_save_sprs_for_deep_states(void) > uint64_t hid5_val = mfspr(SPRN_HID5); > uint64_t hmeer_val = mfspr(SPRN_HMEER); > uint64_t msr_val = MSR_IDLE; > - uint64_t psscr_val = pnv_deepest_stop_psscr_val; > + > + /* > + * Pick deepest cpuidle psscr as the value to be > + * restored through wakeup engine. > + * We will request a deeper state to be restored > + * in hotplug path > + */ > + uint64_t psscr_val = pnv_deepest_cpuidle_psscr_val; > > for_each_possible_cpu(cpu) { > uint64_t pir = get_hard_smp_processor_id(cpu); > @@ -409,7 +419,7 @@ static void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 lpcr_val) > */ > unsigned long pnv_cpu_offline(unsigned int cpu) > { > - unsigned long srr1; > + u64 srr1; > u32 idle_states = pnv_get_supported_cpuidle_states(); > u64 lpcr_val; > > @@ -429,12 +439,18 @@ unsigned long pnv_cpu_offline(unsigned int cpu) > __ppc64_runlatch_off(); > > if (cpu_has_feature(CPU_FTR_ARCH_300) && deepest_stop_found) { > - unsigned long psscr; > + u64 psscr; > + u64 pir = get_hard_smp_processor_id(cpu); > > psscr = mfspr(SPRN_PSSCR); > psscr = (psscr & ~pnv_deepest_stop_psscr_mask) | > pnv_deepest_stop_psscr_val; > + if (pnv_deepest_stop_psscr_val != pnv_deepest_cpuidle_psscr_val) > + opal_slw_set_reg(pir, P9_STOP_SPR_PSSCR, psscr); > srr1 = power9_idle_stop(psscr); > + psscr = (psscr & ~pnv_deepest_cpuidle_psscr_mask) | > + pnv_deepest_cpuidle_psscr_val; > + opal_slw_set_reg(pir, P9_STOP_SPR_PSSCR, psscr); > > } else if ((idle_states & OPAL_PM_WINKLE_ENABLED) && > (idle_states & OPAL_PM_LOSE_FULL_CONTEXT)) { > @@ -555,6 +571,7 @@ static int __init pnv_power9_idle_init(struct device_node *np, u32 *flags, > u64 *psscr_val = NULL; > u64 *psscr_mask = NULL; > u32 *residency_ns = NULL; > + u32 *latency_ns = NULL; > u64 max_residency_ns = 0; > int rc = 0, i; > > @@ -562,6 +579,8 @@ static int __init pnv_power9_idle_init(struct device_node *np, u32 *flags, > psscr_mask = kcalloc(dt_idle_states, sizeof(*psscr_mask), GFP_KERNEL); > residency_ns = kcalloc(dt_idle_states, sizeof(*residency_ns), > GFP_KERNEL); > + latency_ns = kcalloc(dt_idle_states, sizeof(*latency_ns), > + GFP_KERNEL); > > if (!psscr_val || !psscr_mask || !residency_ns) { > rc = -1; > @@ -591,6 +610,13 @@ static int __init pnv_power9_idle_init(struct device_node *np, u32 *flags, > rc = -1; > goto out; > } > + if (of_property_read_u32_array(np, > + "ibm,cpu-idle-state-latencies-ns", > + latency_ns, dt_idle_states)) { > + pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-latency-ns in DT\n"); > + rc = -1; > + goto out; > + } > > /* > * Set pnv_first_deep_stop_state, pnv_deepest_stop_psscr_{val,mask}, > @@ -621,6 +647,12 @@ static int __init pnv_power9_idle_init(struct device_node *np, u32 *flags, > continue; > } > > + if (latency_ns[i] <= POWERNV_THRESHOLD_LATENCY_NS) { > + pnv_deepest_cpuidle_psscr_val = psscr_val[i]; > + pnv_deepest_cpuidle_psscr_mask = psscr_mask[i]; > + deepest_cpuidle_found = true; > + } > + > if (max_residency_ns < residency_ns[i]) { > max_residency_ns = residency_ns[i]; > pnv_deepest_stop_psscr_val = psscr_val[i]; > @@ -653,6 +685,14 @@ static int __init pnv_power9_idle_init(struct device_node *np, u32 *flags, > pnv_deepest_stop_psscr_mask); > } > > + if (unlikely(!deepest_cpuidle_found)) { > + pr_warn("cpuidle-powernv: No suitable deepest CPU-idle state found"); > + } else { > + pr_info("cpuidle-powernv: Deepest cpuidle: psscr = 0x%016llx,mask=0x%016llx\n", > + pnv_deepest_cpuidle_psscr_val, > + pnv_deepest_cpuidle_psscr_mask); > + } > + > pr_info("cpuidle-powernv: Requested Level (RL) value of first deep stop = 0x%llx\n", > pnv_first_deep_stop_state); > out: > diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c > index 1a8234e..620765d 100644 > --- a/drivers/cpuidle/cpuidle-powernv.c > +++ b/drivers/cpuidle/cpuidle-powernv.c > @@ -26,7 +26,6 @@ > * Expose only those Hardware idle states via the cpuidle framework > * that have latency value below POWERNV_THRESHOLD_LATENCY_NS. > */ > -#define POWERNV_THRESHOLD_LATENCY_NS 200000 > > static struct cpuidle_driver powernv_idle_driver = { > .name = "powernv_idle",