From patchwork Thu Feb 16 18:38:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 728871 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vPQ6S5pM8z9s0g for ; Fri, 17 Feb 2017 05:44:00 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="qI7OBJ12"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3vPQ6S4mk5zDqGh for ; Fri, 17 Feb 2017 05:44:00 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="qI7OBJ12"; dkim-atps=neutral X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Received: from mail-pg0-x244.google.com (mail-pg0-x244.google.com [IPv6:2607:f8b0:400e:c05::244]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3vPQ1342GHzDq60 for ; Fri, 17 Feb 2017 05:39:19 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="qI7OBJ12"; dkim-atps=neutral Received: by mail-pg0-x244.google.com with SMTP id y6so1542829pgy.2 for ; Thu, 16 Feb 2017 10:39:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Wf1jFevR96Llc4pbqfZSq58OBRzMHthkkw//xYLHERA=; b=qI7OBJ12eQf57MMyMv/eZHah9DluTm2FPmN8WyRIpLA4o5ztMTVXgFCpffKeEdycH0 Ea+A69lAnKpfEW57zhW9do06b4OXfTPHiJI+Tfj2eeyBGGiOM6rDPrG37QEvMCf/KWIJ cLqEczdMSZMUE30gU0t0KhyPwhQ34CBjmPKxuLhhcfhDL55gYs8ygj3irNYxzR9H2goT wkYxFKnRUe2f72bQTmewSGbCPvqIv9bFXLE4blKfAEzCAJFCd4MJwA2F7iZl0WMiE7Ik Cr7UJpipgzKQPiNTwhs/WVJ7ropt01HL9ewT/tP0ZCvAuM3kscs1qwl+J6bxO/iIeUx2 cu5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Wf1jFevR96Llc4pbqfZSq58OBRzMHthkkw//xYLHERA=; b=VXB5+Ch7/+VfeiTGMtc1r0G5rHH7gJdbFjjY3TnXG1pxS6/jo1Rmg0lxDRWusmH0ru tefkIoIB7Sqic0v7AzBl70+L0DX1aBtkmVFlj/Qj1OsqMPtTB0iCuEjQB8W6GmswjSJS PUF782HjOCTDH+meLn3qFdxnVstqumxsLP0HyfLclhXi9ofkOm0Sxzxtxa7kfiAa60Jt XDcTIXIWNj7ng3NGOUKHLhA3NPhbTnL/ga18cjE4sV4ImbkCZmA0R73oCgn9syDAZ5Ow l/4zG20tDA9670puUDNoq5NPLFZVqkc3UEW83rxerG1cYoahIGQzS6nZw9/TPGjuSXtd CLWA== X-Gm-Message-State: AMke39kCYuTeJjuqamYTW/v+OFsPSNI68CIN2bcTsgX3fNnA6PJ1bW3rrDqSaTHcjDxTfA== X-Received: by 10.99.45.3 with SMTP id t3mr4692344pgt.162.1487270357824; Thu, 16 Feb 2017 10:39:17 -0800 (PST) Received: from roar.local0.net ([61.68.126.103]) by smtp.gmail.com with ESMTPSA id 67sm14933494pfd.120.2017.02.16.10.39.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 16 Feb 2017 10:39:16 -0800 (PST) From: Nicholas Piggin To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH 2/5] powerpc/64: stop using bit in HSPRG0 to test winkle Date: Fri, 17 Feb 2017 04:38:58 +1000 Message-Id: <20170216183901.28611-3-npiggin@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170216183901.28611-1-npiggin@gmail.com> References: <20170216183901.28611-1-npiggin@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Nicholas Piggin Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" The POWER8 idle code has a neat trick of programming the power on engine to restore a low bit into HSPRG0, so idle wakeup code can test and see if it has been programmed this way and therefore lost all state. Restore time can be reduced if winkle has not been reached. However this messes with our r13 PACA pointer, and requires HSPRG0 to be written to. It also optimizes the slowest and most uncommon case at the expense of another SPR write in the common nap state wakeup. Remove this complexity and assume winkle sleeps always require a state restore. This speedup could be made entirely contained within the winkle idle code by counting per-core winkles and setting a thread bitmap when all have gone to winkle. Signed-off-by: Nicholas Piggin --- arch/powerpc/include/asm/exception-64s.h | 18 ++---------------- arch/powerpc/kernel/exceptions-64s.S | 23 ++++------------------- arch/powerpc/kernel/idle_book3s.S | 30 ++++++++++-------------------- arch/powerpc/platforms/powernv/idle.c | 13 ------------- 4 files changed, 16 insertions(+), 68 deletions(-) diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 8ad1cf5c4edf..8f7154a4234f 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -158,17 +158,14 @@ BEGIN_FTR_SECTION_NESTED(943) \ std ra,offset(r13); \ END_FTR_SECTION_NESTED(ftr,ftr,943) -#define EXCEPTION_PROLOG_0_PACA(area) \ +#define EXCEPTION_PROLOG_0(area) \ + GET_PACA(r13); \ std r9,area+EX_R9(r13); /* save r9 */ \ OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR); \ HMT_MEDIUM; \ std r10,area+EX_R10(r13); /* save r10 - r12 */ \ OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR) -#define EXCEPTION_PROLOG_0(area) \ - GET_PACA(r13); \ - EXCEPTION_PROLOG_0_PACA(area) - #define __EXCEPTION_PROLOG_1(area, extra, vec) \ OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR); \ OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR); \ @@ -220,17 +217,6 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) EXCEPTION_PROLOG_1(area, extra, vec); \ EXCEPTION_PROLOG_PSERIES_1_NORI(label, h); -/* Have the PACA in r13 already */ -#define EXCEPTION_PROLOG_PSERIES_PACA(area, label, h, extra, vec) \ - EXCEPTION_PROLOG_0_PACA(area); \ - EXCEPTION_PROLOG_1(area, extra, vec); \ - EXCEPTION_PROLOG_PSERIES_1(label, h); - -#define EXCEPTION_PROLOG_PSERIES_PACA_NORI(area, label, h, extra, vec) \ - EXCEPTION_PROLOG_0_PACA(area); \ - EXCEPTION_PROLOG_1(area, extra, vec); \ - EXCEPTION_PROLOG_PSERIES_1_NORI(label, h); - #define __KVMTEST(h, n) \ lbz r10,HSTATE_IN_GUEST(r13); \ cmpwi r10,0; \ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index d0d89047befe..5f775783f744 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -116,14 +116,12 @@ EXC_VIRT_NONE(0x4000, 0x4100) EXC_REAL_BEGIN(system_reset, 0x100, 0x200) SET_SCRATCH0(r13) - GET_PACA(r13) - clrrdi r13,r13,1 /* Last bit of HSPRG0 is set if waking from winkle */ /* * MSR_RI is not enabled, because PACA_EXNMI and nmi stack is * being used, so a nested NMI exception would corrupt it. */ - EXCEPTION_PROLOG_PSERIES_PACA_NORI(PACA_EXNMI, system_reset_common, - EXC_STD, IDLETEST, 0x100) + EXCEPTION_PROLOG_PSERIES_NORI(PACA_EXNMI, system_reset_common, + EXC_STD, IDLETEST, 0x100) EXC_REAL_END(system_reset, 0x100, 0x200) EXC_VIRT_NONE(0x4100, 0x4200) @@ -180,14 +178,6 @@ EXC_REAL_BEGIN(machine_check, 0x200, 0x300) * vector */ SET_SCRATCH0(r13) /* save r13 */ - /* - * Running native on arch 2.06 or later, we may wakeup from winkle - * inside machine check. If yes, then last bit of HSPRG0 would be set - * to 1. Hence clear it unconditionally. - */ - GET_PACA(r13) - clrrdi r13,r13,1 - SET_PACA(r13) EXCEPTION_PROLOG_0(PACA_EXMC) BEGIN_FTR_SECTION b machine_check_powernv_early @@ -362,7 +352,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early) * Go back to nap/sleep/winkle mode again if (b) is true. */ rlwinm. r11,r12,47-31,30,31 /* Was it in power saving mode? */ - beq 4f /* No, it wasn;t */ + beq 4f /* No, it wasn't */ /* Thread was in power saving mode. Go back to nap again. */ cmpwi r11,2 blt 3f @@ -392,13 +382,8 @@ EXC_COMMON_BEGIN(machine_check_handle_early) /* * Go back to winkle. Please note that this thread was woken up in * machine check from winkle and have not restored the per-subcore - * state. Hence before going back to winkle, set last bit of HSPRG0 - * to 1. This will make sure that if this thread gets woken up - * again at reset vector 0x100 then it will get chance to restore - * the subcore state. + * state. */ - ori r13,r13,1 - SET_PACA(r13) IDLE_STATE_ENTER_SEQ(PPC_WINKLE) /* No return */ 4: diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index ea3562f83c57..1271344e5523 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S @@ -366,11 +366,12 @@ _GLOBAL(power9_idle_stop) b pnv_powersave_common /* No return */ +/* + * Called from reset vector for powersave wakeups. + * cr3 - set to gt if waking up with partial/complete hypervisor state loss + */ .global pnv_powersave_wakeup pnv_powersave_wakeup: -BEGIN_FTR_SECTION - GET_PACA(r13) /* Restore HSPRG0 to get the winkle bit in r13 */ -END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) bl pnv_restore_hyp_resource li r0,PNV_THREAD_RUNNING @@ -394,16 +395,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) b pnv_wakeup_loss /* - * Called from reset vector. Check whether we have woken up with - * hypervisor state loss. If yes, restore hypervisor state and return - * back to reset vector. - * - * r13 - Contents of HSPRG0 - * cr3 - set to gt if waking up with partial/complete hypervisor state loss + * Check whether we have woken up with hypervisor state loss. If yes, + * restore hypervisor state and return back to reset vector. */ pnv_restore_hyp_resource: -BEGIN_FTR_SECTION ld r2,PACATOC(r13); + +BEGIN_FTR_SECTION /* * POWER ISA 3. Use PSSCR to determine if we * are waking up from deep idle state @@ -429,19 +427,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) /* * POWER ISA 2.07 or less. - * Check if last bit of HSPGR0 is set. This indicates whether we are - * waking up from winkle. + * Check if we slept with winkle. */ - clrldi r5,r13,63 - clrrdi r13,r13,1 - - /* Now that we are sure r13 is corrected, load TOC */ - ld r2,PACATOC(r13); - cmpwi cr4,r5,1 - mtspr SPRN_HSPRG0,r13 - lbz r0,PACA_THREAD_IDLE_STATE(r13) cmpwi cr2,r0,PNV_THREAD_NAP + cmpwi cr4,r0,PNV_THREAD_WINKLE bgt cr2,pnv_wakeup_tb_loss /* Either sleep or Winkle */ /* diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index 479c25601612..59dc81a58444 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -53,19 +53,6 @@ static int pnv_save_sprs_for_deep_states(void) uint64_t pir = get_hard_smp_processor_id(cpu); uint64_t hsprg0_val = (uint64_t)&paca[cpu]; - if (!cpu_has_feature(CPU_FTR_ARCH_300)) { - /* - * HSPRG0 is used to store the cpu's pointer to paca. - * Hence last 3 bits are guaranteed to be 0. Program - * slw to restore HSPRG0 with 63rd bit set, so that - * when a thread wakes up at 0x100 we can use this bit - * to distinguish between fastsleep and deep winkle. - * This is not necessary with stop/psscr since PLS - * field of psscr indicates which state we are waking - * up from. - */ - hsprg0_val |= 1; - } rc = opal_slw_set_reg(pir, SPRN_HSPRG0, hsprg0_val); if (rc != 0) return rc;