LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: Power Management issues in MPC8313 processor
From: Srivatsan Canchivaram @ 2012-10-28  0:46 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <1351297672.23094.13@snotra>

[-- Attachment #1: Type: text/plain, Size: 3596 bytes --]

Hello Scott,

I am using 2.6.27 - I am trying to add Power Management support to an older
product.

Thanks,
Srivatsan

On Fri, Oct 26, 2012 at 8:27 PM, Scott Wood <scottwood@freescale.com> wrote:

> On 10/25/2012 05:07:01 PM, Srivatsan Canchivaram wrote:
>
>> Hi,
>>
>>
>> I have a modem with a Freescale MPC8313E processor. I am trying to enable
>> power savings in the processor by placing it in Standby mode and resume
>> normal operation with a Wake-On-LAN magic packet.
>>
>>
>> Following the directions in the Freescale Power Management app note, I
>> enabled Power Management Support in the Linux kernel and device tree
>> configurations.
>>
>>
>> I ran the following command on the board:
>>
>> echo standby > /sys/power/state
>>
>>
>> This caused the console to hang and there was no further response to
>> keyboard inputs. I enabled ‘no_console_suspend’ in the kernel and when I
>> loaded the new build and enabled standby mode, I observed an Oops trace:
>>
>>
>>
>> RASCOM_QCU.7.0.0013 $ echo standby > /sys/power/state
>>
>> <6>PM: Syncing fFreezing user space processes ... ilesystems ... <7>PM:
>> Entering standby sleep
>>
>> Unable to handle kernel paging request for instruction fetch
>>
>> Faulting instruction address: 0x616d6570
>>
>> Oops: Kernel access of bad area, sig: 11 [#1]
>>
>> MPC831x RDB
>>
>> Modules linked in: dsp rcspi modem i2c_mpc thermal_sys lm92 hwmon [last
>> unloaded: modem]
>>
>> NIP: 616d6570 LR: c0165224 CTR: 616d6573
>>
>> REGS: cd087d30 TRAP: 0400   Not tainted  (2.6.27)
>>
>> MSR: 20001032 <ME,IR,DR>  CR: 28002024  XER: 20000000
>>
>> TASK = cc312400[1196] 'echo' THREAD: cd086000
>>
>> GPR00: 00000002 cd087de0 cc312400 cf821800 cd087de8 00000002 c06e0000
>> c06da4a0
>>
>> GPR08: c06da948 616d6573 00003fff c06c6308 28002022 10091248 0fffc000
>> 100050b8
>>
>> GPR16: 1008a270 10068810 100687c8 10068814 00000000 1008c284 1008c294
>> c0246180
>>
>> GPR24: c02ab9e4 c02ab9dc c06cc4f4 00000006 cd087e08 00000002 c06c595c
>> cf821808
>>
>> NIP [616d6570] 0x616d6570
>>
>> LR [c0165224] platform_pm_suspend_noirq+**0x84/0x88
>>
>
> What kernel are you using?  platform_pm_suspend_noirq was removed by this
> commit:
>
> commit 9b39e73d0c2b265a7f8748b0e9a9f0**9be84079a8
> Author: Rafael J. Wysocki <rjw@sisk.pl>
> Date:   Sun Dec 18 00:34:24 2011 +0100
>
>     PM / Sleep: Remove forward-only callbacks from platform bus type
>
>     The forward-only PM callbacks provided by the platform bus type are
>     not necessary any more, because the PM core executes driver callbacks
>     when the corresponding subsystem callbacks are not present, so drop
>     them.
>
>     Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
>
> It seems that a driver's pm ops are getting corrupted -- maybe used after
> freeing?  Have you tried enabling slab/slub debug?
>
> Can you instrument the code to see if there are any fields in the device
> struct that aren't corrupt, that could point out which device this is?
>
>
>  I found another thread that dealt with Power Management issues on the
>> Freescale MPC8313 processor:
>>
>> https://lists.ozlabs.org/**pipermail/linuxppc-dev/2012-**
>> January/095240.html<https://lists.ozlabs.org/pipermail/linuxppc-dev/2012-January/095240.html>
>>
>> The resolution of this issue seems to be related to the JTAG TRST pin
>> being
>> disabled. This is not relevant in my case as the TRST on my board is
>> already inactive.
>>
>
> If you were seeing that, you'd see a hang rather than an oops.
>
> -Scott
>

[-- Attachment #2: Type: text/html, Size: 4590 bytes --]

^ permalink raw reply

* [PATCH 0/3] powerpc/ptrace: hw breakpoint book3s repost and cleanups
From: Michael Neuling @ 2012-10-29  1:13 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev, Naveen N . Rao

This is a repost of K.Prasad hw breakpoint support for book3s and some
other junk I found along the way.

K.Prasad (1):
  powerpc/hw-breakpoint: Use generic hw-breakpoint interfaces for new
    PPC ptrace flags

Michael Neuling (2):
  powerpc/ptrace: Fix spelling mistake
  powerpc/ptrace: Remove unused addr parameter in ppc_del_hwdebug()

 Documentation/powerpc/ptrace.txt |   16 +++++++
 arch/powerpc/kernel/ptrace.c     |   86 ++++++++++++++++++++++++++++++++++----
 2 files changed, 94 insertions(+), 8 deletions(-)

-- 
1.7.9.5

^ permalink raw reply

* [PATCH 1/3] powerpc/hw-breakpoint: Use generic hw-breakpoint interfaces for new PPC ptrace flags
From: Michael Neuling @ 2012-10-29  1:13 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev, Naveen N . Rao, K.Prasad, Michael Neuling
In-Reply-To: <1351473197-27426-1-git-send-email-mikey@neuling.org>

From: "K.Prasad" <prasad@linux.vnet.ibm.com>

PPC_PTRACE_GETHWDBGINFO, PPC_PTRACE_SETHWDEBUG and PPC_PTRACE_DELHWDEBUG are
PowerPC specific ptrace flags that use the watchpoint register. While they are
targeted primarily towards BookE users, user-space applications such as GDB
have started using them for BookS too. This patch enables the use of generic
hardware breakpoint interfaces for these new flags.

Apart from the usual benefits of using generic hw-breakpoint interfaces, these
changes allow debuggers (such as GDB) to use a common set of ptrace flags for
their watchpoint needs and allow more precise breakpoint specification (length
of the variable can be specified).

Mikey added: rebased and added dbginfo.features around #ifdef
             CONFIG_HAVE_HW_BREAKPOINT

Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 Documentation/powerpc/ptrace.txt |   16 ++++++++
 arch/powerpc/kernel/ptrace.c     |   78 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 90 insertions(+), 4 deletions(-)

diff --git a/Documentation/powerpc/ptrace.txt b/Documentation/powerpc/ptrace.txt
index f4a5499..f2a7a39 100644
--- a/Documentation/powerpc/ptrace.txt
+++ b/Documentation/powerpc/ptrace.txt
@@ -127,6 +127,22 @@ Some examples of using the structure to:
   p.addr2           = (uint64_t) end_range;
   p.condition_value = 0;
 
+- set a watchpoint in server processors (BookS)
+
+  p.version         = 1;
+  p.trigger_type    = PPC_BREAKPOINT_TRIGGER_RW;
+  p.addr_mode       = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
+  or
+  p.addr_mode       = PPC_BREAKPOINT_MODE_EXACT;
+
+  p.condition_mode  = PPC_BREAKPOINT_CONDITION_NONE;
+  p.addr            = (uint64_t) begin_range;
+  /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where
+   * addr2 - addr <= 8 Bytes.
+   */
+  p.addr2           = (uint64_t) end_range;
+  p.condition_value = 0;
+
 3. PTRACE_DELHWDEBUG
 
 Takes an integer which identifies an existing breakpoint or watchpoint
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 79d8e56..140238a 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1338,6 +1338,12 @@ static int set_dac_range(struct task_struct *child,
 static long ppc_set_hwdebug(struct task_struct *child,
 		     struct ppc_hw_breakpoint *bp_info)
 {
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+	int len = 0;
+	struct thread_struct *thread = &(child->thread);
+	struct perf_event *bp;
+	struct perf_event_attr attr;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #ifndef CONFIG_PPC_ADV_DEBUG_REGS
 	unsigned long dabr;
 #endif
@@ -1381,13 +1387,9 @@ static long ppc_set_hwdebug(struct task_struct *child,
 	 */
 	if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 ||
 	    (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 ||
-	    bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT ||
 	    bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
 		return -EINVAL;
 
-	if (child->thread.dabr)
-		return -ENOSPC;
-
 	if ((unsigned long)bp_info->addr >= TASK_SIZE)
 		return -EIO;
 
@@ -1397,6 +1399,50 @@ static long ppc_set_hwdebug(struct task_struct *child,
 		dabr |= DABR_DATA_READ;
 	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
 		dabr |= DABR_DATA_WRITE;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+	if (ptrace_get_breakpoints(child) < 0)
+		return -ESRCH;
+
+	/*
+	 * Check if the request is for 'range' breakpoints. We can
+	 * support it if range < 8 bytes.
+	 */
+	if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) {
+		len = bp_info->addr2 - bp_info->addr;
+	} else if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) {
+		ptrace_put_breakpoints(child);
+		return -EINVAL;
+	}
+	bp = thread->ptrace_bps[0];
+	if (bp) {
+		ptrace_put_breakpoints(child);
+		return -ENOSPC;
+	}
+
+	/* Create a new breakpoint request if one doesn't exist already */
+	hw_breakpoint_init(&attr);
+	attr.bp_addr = (unsigned long)bp_info->addr & ~HW_BREAKPOINT_ALIGN;
+	attr.bp_len = len;
+	arch_bp_generic_fields(dabr & (DABR_DATA_WRITE | DABR_DATA_READ),
+								&attr.bp_type);
+
+	thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr,
+					       ptrace_triggered, NULL, child);
+	if (IS_ERR(bp)) {
+		thread->ptrace_bps[0] = NULL;
+		ptrace_put_breakpoints(child);
+		return PTR_ERR(bp);
+	}
+
+	ptrace_put_breakpoints(child);
+	return 1;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+
+	if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT)
+		return -EINVAL;
+
+	if (child->thread.dabr)
+		return -ENOSPC;
 
 	child->thread.dabr = dabr;
 	child->thread.dabrx = DABRX_ALL;
@@ -1407,6 +1453,11 @@ static long ppc_set_hwdebug(struct task_struct *child,
 
 static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
 {
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+	int ret = 0;
+	struct thread_struct *thread = &(child->thread);
+	struct perf_event *bp;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
 	int rc;
 
@@ -1426,10 +1477,25 @@ static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
 #else
 	if (data != 1)
 		return -EINVAL;
+
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+	if (ptrace_get_breakpoints(child) < 0)
+		return -ESRCH;
+
+	bp = thread->ptrace_bps[0];
+	if (bp) {
+		unregister_hw_breakpoint(bp);
+		thread->ptrace_bps[0] = NULL;
+	} else
+		ret = -ENOENT;
+	ptrace_put_breakpoints(child);
+	return ret;
+#else /* CONFIG_HAVE_HW_BREAKPOINT */
 	if (child->thread.dabr == 0)
 		return -ENOENT;
 
 	child->thread.dabr = 0;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 
 	return 0;
 #endif
@@ -1536,7 +1602,11 @@ long arch_ptrace(struct task_struct *child, long request,
 		dbginfo.data_bp_alignment = 4;
 #endif
 		dbginfo.sizeof_condition = 0;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+		dbginfo.features = PPC_DEBUG_FEATURE_DATA_BP_RANGE;
+#else
 		dbginfo.features = 0;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
 #endif /* CONFIG_PPC_ADV_DEBUG_REGS */
 
 		if (!access_ok(VERIFY_WRITE, datavp,
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 2/3] powerpc/ptrace: Fix spelling mistake
From: Michael Neuling @ 2012-10-29  1:13 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev, Naveen N . Rao
In-Reply-To: <1351473197-27426-1-git-send-email-mikey@neuling.org>

s/intruction/instruction/

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/kernel/ptrace.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 140238a..7dd32d1 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1037,7 +1037,7 @@ void ptrace_disable(struct task_struct *child)
 }
 
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
-static long set_intruction_bp(struct task_struct *child,
+static long set_instruction_bp(struct task_struct *child,
 			      struct ppc_hw_breakpoint *bp_info)
 {
 	int slot;
@@ -1371,7 +1371,7 @@ static long ppc_set_hwdebug(struct task_struct *child,
 		if ((bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_EXECUTE) ||
 		    (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE))
 			return -EINVAL;
-		return set_intruction_bp(child, bp_info);
+		return set_instruction_bp(child, bp_info);
 	}
 	if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT)
 		return set_dac(child, bp_info);
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 3/3] powerpc/ptrace: Remove unused addr parameter in ppc_del_hwdebug()
From: Michael Neuling @ 2012-10-29  1:13 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev, Naveen N . Rao
In-Reply-To: <1351473197-27426-1-git-send-email-mikey@neuling.org>


Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/kernel/ptrace.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 7dd32d1..817b411 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1451,7 +1451,7 @@ static long ppc_set_hwdebug(struct task_struct *child,
 #endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */
 }
 
-static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
+static long ppc_del_hwdebug(struct task_struct *child, long data)
 {
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 	int ret = 0;
@@ -1633,7 +1633,7 @@ long arch_ptrace(struct task_struct *child, long request,
 	}
 
 	case PPC_PTRACE_DELHWDEBUG: {
-		ret = ppc_del_hwdebug(child, addr, data);
+		ret = ppc_del_hwdebug(child, data);
 		break;
 	}
 
-- 
1.7.9.5

^ permalink raw reply related

* RE: [PATCH] powerpc/esdhc: enable the card insert/remove interrupt
From: Huang Changming-R66093 @ 2012-10-29  1:40 UTC (permalink / raw)
  To: Anton Vorontsov
  Cc: linuxppc-dev@lists.ozlabs.org, Chris Ball,
	linux-mmc@vger.kernel.org
In-Reply-To: <20121027011249.GB9152@lizard>

PiBIZWxsbyBIdWFuZywNCj4gDQo+IE9uIEZyaSwgT2N0IDI2LCAyMDEyIGF0IDAyOjQyOjM2QU0g
KzAwMDAsIEh1YW5nIENoYW5nbWluZy1SNjYwOTMgd3JvdGU6DQo+ID4gRm9yIHRoZSBjdXJyZW50
IHBvbGxpbmcgbW9kZSwgZHJpdmVyIHdpbGwgc2VuZCBDTUQxMyB0byBwb2xsIHRoZSBjYXJkDQo+
IHN0YXR1cyBwZXJpb2RpY2FsbHkgLCB3aGljaCB3aWxsIGNhdXNlIHRvbyBtYW55IGludGVycnVw
dHMuDQo+ID4gT25jZSBJIHNlbnQgcGF0Y2hlcyB0byBkZXRlY3QgdGhlIGNhcmQgd2hlbiB1c2lu
ZyBwb2xsaW5nIG1vZGUgbGFzdA0KPiB5ZWFyOiByZWFkIHRoZSBzdGF0ZSByZWdpc3RlciwgaW5z
dGVhZCBvZiBzZW5kIENNRDEzLiBCdXQsIHRoZXNlIHBhdGNoZXMNCj4gd2VyZSBub3QgYWNjZXB0
ZWQuIE5vdyBJIGF0dGFjaCB0aGVtIGZvciB5b3UuDQo+IA0KPiBXYXMgdGhlcmUgYW55IHNwZWNp
ZmljIHJlYXNvbiB3aHkgdGhlIHBhdGNoZXMgZGlkbid0IGdldCBhY2NlcHRlZD8NCj4gDQo+IEkg
dmVyeSBicmllZmx5IGxvb2tlZCBhdCB0aGVtLCBhbmQgdGhleSBzZWVtIHRvIGJlIE9LICh0aGVy
ZSBhcmUgYSBmZXcNCj4gY29zbWV0aWMgZGV0YWlscyBJJ2QgY29tbWVudCBvbiwgdGhvIC0tIGJ1
dCBwbGVhc2Ugc2VuZCB0aGVtIGluIGEgbm9ybWFsDQo+IHdheSAoaS5lLiBub3QgYXMgYXR0YWNo
bWVudHMpLg0KPiANCg0KVGhhbmtzLCBBbnRvbi4NCkkgZG9uJ3Qga25vdyB3aHkuDQpJIHdpbGwg
cmVzZW5kIHRoZXNlIHBhdGNoZXMgYmFzZWQgb24gbGF0ZXN0IGtlcm5lbC4NCg0K

^ permalink raw reply

* [PATCH] powermac/cpufreq_32: set non-infinite transition time for 7447A driver
From: Andreas Schwab @ 2012-10-29  9:15 UTC (permalink / raw)
  To: linuxppc-dev

The transition time for the 7447A is around 8ms which makes it possible
to use the ondemand governor.  This has been tested on the iBook G4
(PowerBook6,7).

Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
---
 arch/powerpc/platforms/powermac/cpufreq_32.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c
index 6417119..311b804 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_32.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -55,6 +55,7 @@ static unsigned int low_freq;
 static unsigned int hi_freq;
 static unsigned int cur_freq;
 static unsigned int sleep_freq;
+static unsigned long transition_latency;
 
 /*
  * Different models uses different mechanisms to switch the frequency
@@ -403,7 +404,7 @@ static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	if (policy->cpu != 0)
 		return -ENODEV;
 
-	policy->cpuinfo.transition_latency	= CPUFREQ_ETERNAL;
+	policy->cpuinfo.transition_latency	= transition_latency;
 	policy->cur = cur_freq;
 
 	cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
@@ -658,12 +659,14 @@ static int __init pmac_cpufreq_setup(void)
 	if (!value)
 		goto out;
 	cur_freq = (*value) / 1000;
+	transition_latency = CPUFREQ_ETERNAL;
 
 	/*  Check for 7447A based MacRISC3 */
 	if (of_machine_is_compatible("MacRISC3") &&
 	    of_get_property(cpunode, "dynamic-power-step", NULL) &&
 	    PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
 		pmac_cpufreq_init_7447A(cpunode);
+		transition_latency = 8000000;
 	/* Check for other MacRISC3 machines */
 	} else if (of_machine_is_compatible("PowerBook3,4") ||
 		   of_machine_is_compatible("PowerBook3,5") ||
-- 
1.8.0


-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply related

* Re: [PATCH v2 10/12] memory-hotplug: memory_hotplug: clear zone when removing the memory
From: Jianguo Wu @ 2012-10-29 15:34 UTC (permalink / raw)
  To: wency
  Cc: linux-s390, linux-ia64, len.brown, linux-acpi, linux-sh, x86,
	linux-kernel, cmetcalf, linux-mm, isimatu.yasuaki, paulus,
	minchan.kim, kosaki.motohiro, rientjes, sparclinux, cl,
	linuxppc-dev, akpm, liuj97
In-Reply-To: <1350988250-31294-11-git-send-email-wency@cn.fujitsu.com>

On 2012/10/23 18:30, wency@cn.fujitsu.com wrote:
> From: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
> 
> When a memory is added, we update zone's and pgdat's start_pfn and
> spanned_pages in the function __add_zone(). So we should revert them
> when the memory is removed.
> 
> The patch adds a new function __remove_zone() to do this.
> 
> CC: David Rientjes <rientjes@google.com>
> CC: Jiang Liu <liuj97@gmail.com>
> CC: Len Brown <len.brown@intel.com>
> CC: Christoph Lameter <cl@linux.com>
> Cc: Minchan Kim <minchan.kim@gmail.com>
> CC: Andrew Morton <akpm@linux-foundation.org>
> CC: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> ---
>  mm/memory_hotplug.c |  207 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 207 insertions(+), 0 deletions(-)
> 
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index 03153cf..55a228d 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -312,10 +312,213 @@ static int __meminit __add_section(int nid, struct zone *zone,
>  	return register_new_memory(nid, __pfn_to_section(phys_start_pfn));
>  }
>  
> +/* find the smallest valid pfn in the range [start_pfn, end_pfn) */
> +static int find_smallest_section_pfn(int nid, struct zone *zone,
> +				     unsigned long start_pfn,
> +				     unsigned long end_pfn)
> +{
> +	struct mem_section *ms;
> +
> +	for (; start_pfn < end_pfn; start_pfn += PAGES_PER_SECTION) {
> +		ms = __pfn_to_section(start_pfn);
> +
> +		if (unlikely(!valid_section(ms)))
> +			continue;
> +
> +		if (unlikely(pfn_to_nid(start_pfn)) != nid)

if (unlikely(pfn_to_nid(start_pfn) != nid))

> +			continue;
> +
> +		if (zone && zone != page_zone(pfn_to_page(start_pfn)))
> +			continue;
> +
> +		return start_pfn;
> +	}
> +
> +	return 0;
> +}
> +
> +/* find the biggest valid pfn in the range [start_pfn, end_pfn). */
> +static int find_biggest_section_pfn(int nid, struct zone *zone,
> +				    unsigned long start_pfn,
> +				    unsigned long end_pfn)
> +{
> +	struct mem_section *ms;
> +	unsigned long pfn;
> +
> +	/* pfn is the end pfn of a memory section. */
> +	pfn = end_pfn - 1;
> +	for (; pfn >= start_pfn; pfn -= PAGES_PER_SECTION) {
> +		ms = __pfn_to_section(pfn);
> +
> +		if (unlikely(!valid_section(ms)))
> +			continue;
> +
> +		if (unlikely(pfn_to_nid(pfn)) != nid)

if (unlikely(pfn_to_nid(pfn) != nid))

> +			continue;
> +
> +		if (zone && zone != page_zone(pfn_to_page(pfn)))
> +			continue;
> +
> +		return pfn;
> +	}
> +
> +	return 0;
> +}
> +
> +static void shrink_zone_span(struct zone *zone, unsigned long start_pfn,
> +			     unsigned long end_pfn)
> +{
> +	unsigned long zone_start_pfn =  zone->zone_start_pfn;
> +	unsigned long zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
> +	unsigned long pfn;
> +	struct mem_section *ms;
> +	int nid = zone_to_nid(zone);
> +
> +	zone_span_writelock(zone);
> +	if (zone_start_pfn == start_pfn) {
> +		/*
> +		 * If the section is smallest section in the zone, it need
> +		 * shrink zone->zone_start_pfn and zone->zone_spanned_pages.
> +		 * In this case, we find second smallest valid mem_section
> +		 * for shrinking zone.
> +		 */
> +		pfn = find_smallest_section_pfn(nid, zone, end_pfn,
> +						zone_end_pfn);
> +		if (pfn) {
> +			zone->zone_start_pfn = pfn;
> +			zone->spanned_pages = zone_end_pfn - pfn;
> +		}
> +	} else if (zone_end_pfn == end_pfn) {
> +		/*
> +		 * If the section is biggest section in the zone, it need
> +		 * shrink zone->spanned_pages.
> +		 * In this case, we find second biggest valid mem_section for
> +		 * shrinking zone.
> +		 */
> +		pfn = find_biggest_section_pfn(nid, zone, zone_start_pfn,
> +					       start_pfn);
> +		if (pfn)
> +			zone->spanned_pages = pfn - zone_start_pfn + 1;
> +	}
> +
> +	/*
> +	 * The section is not biggest or smallest mem_section in the zone, it
> +	 * only creates a hole in the zone. So in this case, we need not
> +	 * change the zone. But perhaps, the zone has only hole data. Thus
> +	 * it check the zone has only hole or not.
> +	 */
> +	pfn = zone_start_pfn;
> +	for (; pfn < zone_end_pfn; pfn += PAGES_PER_SECTION) {
> +		ms = __pfn_to_section(pfn);
> +
> +		if (unlikely(!valid_section(ms)))
> +			continue;
> +
> +		if (page_zone(pfn_to_page(pfn)) != zone)
> +			continue;
> +
> +		 /* If the section is current section, it continues the loop */
> +		if (start_pfn == pfn)
> +			continue;
> +
> +		/* If we find valid section, we have nothing to do */
> +		zone_span_writeunlock(zone);
> +		return;
> +	}
> +
> +	/* The zone has no valid section */
> +	zone->zone_start_pfn = 0;
> +	zone->spanned_pages = 0;
> +	zone_span_writeunlock(zone);
> +}
> +
> +static void shrink_pgdat_span(struct pglist_data *pgdat,
> +			      unsigned long start_pfn, unsigned long end_pfn)
> +{
> +	unsigned long pgdat_start_pfn =  pgdat->node_start_pfn;
> +	unsigned long pgdat_end_pfn =
> +		pgdat->node_start_pfn + pgdat->node_spanned_pages;
> +	unsigned long pfn;
> +	struct mem_section *ms;
> +	int nid = pgdat->node_id;
> +
> +	if (pgdat_start_pfn == start_pfn) {
> +		/*
> +		 * If the section is smallest section in the pgdat, it need
> +		 * shrink pgdat->node_start_pfn and pgdat->node_spanned_pages.
> +		 * In this case, we find second smallest valid mem_section
> +		 * for shrinking zone.
> +		 */
> +		pfn = find_smallest_section_pfn(nid, NULL, end_pfn,
> +						pgdat_end_pfn);
> +		if (pfn) {
> +			pgdat->node_start_pfn = pfn;
> +			pgdat->node_spanned_pages = pgdat_end_pfn - pfn;
> +		}
> +	} else if (pgdat_end_pfn == end_pfn) {
> +		/*
> +		 * If the section is biggest section in the pgdat, it need
> +		 * shrink pgdat->node_spanned_pages.
> +		 * In this case, we find second biggest valid mem_section for
> +		 * shrinking zone.
> +		 */
> +		pfn = find_biggest_section_pfn(nid, NULL, pgdat_start_pfn,
> +					       start_pfn);
> +		if (pfn)
> +			pgdat->node_spanned_pages = pfn - pgdat_start_pfn + 1;
> +	}
> +
> +	/*
> +	 * If the section is not biggest or smallest mem_section in the pgdat,
> +	 * it only creates a hole in the pgdat. So in this case, we need not
> +	 * change the pgdat.
> +	 * But perhaps, the pgdat has only hole data. Thus it check the pgdat
> +	 * has only hole or not.
> +	 */
> +	pfn = pgdat_start_pfn;
> +	for (; pfn < pgdat_end_pfn; pfn += PAGES_PER_SECTION) {
> +		ms = __pfn_to_section(pfn);
> +
> +		if (unlikely(!valid_section(ms)))
> +			continue;
> +
> +		if (pfn_to_nid(pfn) != nid)
> +			continue;
> +
> +		 /* If the section is current section, it continues the loop */
> +		if (start_pfn == pfn)
> +			continue;
> +
> +		/* If we find valid section, we have nothing to do */
> +		return;
> +	}
> +
> +	/* The pgdat has no valid section */
> +	pgdat->node_start_pfn = 0;
> +	pgdat->node_spanned_pages = 0;
> +}
> +
> +static void __remove_zone(struct zone *zone, unsigned long start_pfn)
> +{
> +	struct pglist_data *pgdat = zone->zone_pgdat;
> +	int nr_pages = PAGES_PER_SECTION;
> +	int zone_type;
> +	unsigned long flags;
> +
> +	zone_type = zone - pgdat->node_zones;
> +
> +	pgdat_resize_lock(zone->zone_pgdat, &flags);
> +	shrink_zone_span(zone, start_pfn, start_pfn + nr_pages);
> +	shrink_pgdat_span(pgdat, start_pfn, start_pfn + nr_pages);
> +	pgdat_resize_unlock(zone->zone_pgdat, &flags);
> +}
> +
>  static int __remove_section(struct zone *zone, struct mem_section *ms)
>  {
>  	unsigned long flags;
>  	struct pglist_data *pgdat = zone->zone_pgdat;
> +	unsigned long start_pfn;
> +	int scn_nr;
>  	int ret = -EINVAL;
>  
>  	if (!valid_section(ms))
> @@ -325,6 +528,10 @@ static int __remove_section(struct zone *zone, struct mem_section *ms)
>  	if (ret)
>  		return ret;
>  
> +	scn_nr = __section_nr(ms);
> +	start_pfn = section_nr_to_pfn(scn_nr);
> +	__remove_zone(zone, start_pfn);
> +
>  	pgdat_resize_lock(pgdat, &flags);
>  	sparse_remove_one_section(zone, ms);
>  	pgdat_resize_unlock(pgdat, &flags);
> 

^ permalink raw reply

* Re: [PATCH v2 10/12] memory-hotplug: memory_hotplug: clear zone when removing the memory
From: Wen Congyang @ 2012-10-30  1:50 UTC (permalink / raw)
  To: Jianguo Wu
  Cc: linux-s390, linux-ia64, len.brown, linux-acpi, linux-sh, x86,
	linux-kernel, cmetcalf, linux-mm, isimatu.yasuaki, paulus,
	minchan.kim, kosaki.motohiro, rientjes, sparclinux, cl,
	linuxppc-dev, akpm, liuj97
In-Reply-To: <508EA207.2060205@gmail.com>

At 10/29/2012 11:34 PM, Jianguo Wu Wrote:
> On 2012/10/23 18:30, wency@cn.fujitsu.com wrote:
>> From: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>>
>> When a memory is added, we update zone's and pgdat's start_pfn and
>> spanned_pages in the function __add_zone(). So we should revert them
>> when the memory is removed.
>>
>> The patch adds a new function __remove_zone() to do this.
>>
>> CC: David Rientjes <rientjes@google.com>
>> CC: Jiang Liu <liuj97@gmail.com>
>> CC: Len Brown <len.brown@intel.com>
>> CC: Christoph Lameter <cl@linux.com>
>> Cc: Minchan Kim <minchan.kim@gmail.com>
>> CC: Andrew Morton <akpm@linux-foundation.org>
>> CC: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
>> Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
>> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
>> ---
>>  mm/memory_hotplug.c |  207 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 files changed, 207 insertions(+), 0 deletions(-)
>>
>> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
>> index 03153cf..55a228d 100644
>> --- a/mm/memory_hotplug.c
>> +++ b/mm/memory_hotplug.c
>> @@ -312,10 +312,213 @@ static int __meminit __add_section(int nid, struct zone *zone,
>>  	return register_new_memory(nid, __pfn_to_section(phys_start_pfn));
>>  }
>>  
>> +/* find the smallest valid pfn in the range [start_pfn, end_pfn) */
>> +static int find_smallest_section_pfn(int nid, struct zone *zone,
>> +				     unsigned long start_pfn,
>> +				     unsigned long end_pfn)
>> +{
>> +	struct mem_section *ms;
>> +
>> +	for (; start_pfn < end_pfn; start_pfn += PAGES_PER_SECTION) {
>> +		ms = __pfn_to_section(start_pfn);
>> +
>> +		if (unlikely(!valid_section(ms)))
>> +			continue;
>> +
>> +		if (unlikely(pfn_to_nid(start_pfn)) != nid)
> 
> if (unlikely(pfn_to_nid(start_pfn) != nid))

Thanks for pointing it out. I will fix it soon.

Wen Congyang

> 
>> +			continue;
>> +
>> +		if (zone && zone != page_zone(pfn_to_page(start_pfn)))
>> +			continue;
>> +
>> +		return start_pfn;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +/* find the biggest valid pfn in the range [start_pfn, end_pfn). */
>> +static int find_biggest_section_pfn(int nid, struct zone *zone,
>> +				    unsigned long start_pfn,
>> +				    unsigned long end_pfn)
>> +{
>> +	struct mem_section *ms;
>> +	unsigned long pfn;
>> +
>> +	/* pfn is the end pfn of a memory section. */
>> +	pfn = end_pfn - 1;
>> +	for (; pfn >= start_pfn; pfn -= PAGES_PER_SECTION) {
>> +		ms = __pfn_to_section(pfn);
>> +
>> +		if (unlikely(!valid_section(ms)))
>> +			continue;
>> +
>> +		if (unlikely(pfn_to_nid(pfn)) != nid)
> 
> if (unlikely(pfn_to_nid(pfn) != nid))
> 
>> +			continue;
>> +
>> +		if (zone && zone != page_zone(pfn_to_page(pfn)))
>> +			continue;
>> +
>> +		return pfn;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static void shrink_zone_span(struct zone *zone, unsigned long start_pfn,
>> +			     unsigned long end_pfn)
>> +{
>> +	unsigned long zone_start_pfn =  zone->zone_start_pfn;
>> +	unsigned long zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
>> +	unsigned long pfn;
>> +	struct mem_section *ms;
>> +	int nid = zone_to_nid(zone);
>> +
>> +	zone_span_writelock(zone);
>> +	if (zone_start_pfn == start_pfn) {
>> +		/*
>> +		 * If the section is smallest section in the zone, it need
>> +		 * shrink zone->zone_start_pfn and zone->zone_spanned_pages.
>> +		 * In this case, we find second smallest valid mem_section
>> +		 * for shrinking zone.
>> +		 */
>> +		pfn = find_smallest_section_pfn(nid, zone, end_pfn,
>> +						zone_end_pfn);
>> +		if (pfn) {
>> +			zone->zone_start_pfn = pfn;
>> +			zone->spanned_pages = zone_end_pfn - pfn;
>> +		}
>> +	} else if (zone_end_pfn == end_pfn) {
>> +		/*
>> +		 * If the section is biggest section in the zone, it need
>> +		 * shrink zone->spanned_pages.
>> +		 * In this case, we find second biggest valid mem_section for
>> +		 * shrinking zone.
>> +		 */
>> +		pfn = find_biggest_section_pfn(nid, zone, zone_start_pfn,
>> +					       start_pfn);
>> +		if (pfn)
>> +			zone->spanned_pages = pfn - zone_start_pfn + 1;
>> +	}
>> +
>> +	/*
>> +	 * The section is not biggest or smallest mem_section in the zone, it
>> +	 * only creates a hole in the zone. So in this case, we need not
>> +	 * change the zone. But perhaps, the zone has only hole data. Thus
>> +	 * it check the zone has only hole or not.
>> +	 */
>> +	pfn = zone_start_pfn;
>> +	for (; pfn < zone_end_pfn; pfn += PAGES_PER_SECTION) {
>> +		ms = __pfn_to_section(pfn);
>> +
>> +		if (unlikely(!valid_section(ms)))
>> +			continue;
>> +
>> +		if (page_zone(pfn_to_page(pfn)) != zone)
>> +			continue;
>> +
>> +		 /* If the section is current section, it continues the loop */
>> +		if (start_pfn == pfn)
>> +			continue;
>> +
>> +		/* If we find valid section, we have nothing to do */
>> +		zone_span_writeunlock(zone);
>> +		return;
>> +	}
>> +
>> +	/* The zone has no valid section */
>> +	zone->zone_start_pfn = 0;
>> +	zone->spanned_pages = 0;
>> +	zone_span_writeunlock(zone);
>> +}
>> +
>> +static void shrink_pgdat_span(struct pglist_data *pgdat,
>> +			      unsigned long start_pfn, unsigned long end_pfn)
>> +{
>> +	unsigned long pgdat_start_pfn =  pgdat->node_start_pfn;
>> +	unsigned long pgdat_end_pfn =
>> +		pgdat->node_start_pfn + pgdat->node_spanned_pages;
>> +	unsigned long pfn;
>> +	struct mem_section *ms;
>> +	int nid = pgdat->node_id;
>> +
>> +	if (pgdat_start_pfn == start_pfn) {
>> +		/*
>> +		 * If the section is smallest section in the pgdat, it need
>> +		 * shrink pgdat->node_start_pfn and pgdat->node_spanned_pages.
>> +		 * In this case, we find second smallest valid mem_section
>> +		 * for shrinking zone.
>> +		 */
>> +		pfn = find_smallest_section_pfn(nid, NULL, end_pfn,
>> +						pgdat_end_pfn);
>> +		if (pfn) {
>> +			pgdat->node_start_pfn = pfn;
>> +			pgdat->node_spanned_pages = pgdat_end_pfn - pfn;
>> +		}
>> +	} else if (pgdat_end_pfn == end_pfn) {
>> +		/*
>> +		 * If the section is biggest section in the pgdat, it need
>> +		 * shrink pgdat->node_spanned_pages.
>> +		 * In this case, we find second biggest valid mem_section for
>> +		 * shrinking zone.
>> +		 */
>> +		pfn = find_biggest_section_pfn(nid, NULL, pgdat_start_pfn,
>> +					       start_pfn);
>> +		if (pfn)
>> +			pgdat->node_spanned_pages = pfn - pgdat_start_pfn + 1;
>> +	}
>> +
>> +	/*
>> +	 * If the section is not biggest or smallest mem_section in the pgdat,
>> +	 * it only creates a hole in the pgdat. So in this case, we need not
>> +	 * change the pgdat.
>> +	 * But perhaps, the pgdat has only hole data. Thus it check the pgdat
>> +	 * has only hole or not.
>> +	 */
>> +	pfn = pgdat_start_pfn;
>> +	for (; pfn < pgdat_end_pfn; pfn += PAGES_PER_SECTION) {
>> +		ms = __pfn_to_section(pfn);
>> +
>> +		if (unlikely(!valid_section(ms)))
>> +			continue;
>> +
>> +		if (pfn_to_nid(pfn) != nid)
>> +			continue;
>> +
>> +		 /* If the section is current section, it continues the loop */
>> +		if (start_pfn == pfn)
>> +			continue;
>> +
>> +		/* If we find valid section, we have nothing to do */
>> +		return;
>> +	}
>> +
>> +	/* The pgdat has no valid section */
>> +	pgdat->node_start_pfn = 0;
>> +	pgdat->node_spanned_pages = 0;
>> +}
>> +
>> +static void __remove_zone(struct zone *zone, unsigned long start_pfn)
>> +{
>> +	struct pglist_data *pgdat = zone->zone_pgdat;
>> +	int nr_pages = PAGES_PER_SECTION;
>> +	int zone_type;
>> +	unsigned long flags;
>> +
>> +	zone_type = zone - pgdat->node_zones;
>> +
>> +	pgdat_resize_lock(zone->zone_pgdat, &flags);
>> +	shrink_zone_span(zone, start_pfn, start_pfn + nr_pages);
>> +	shrink_pgdat_span(pgdat, start_pfn, start_pfn + nr_pages);
>> +	pgdat_resize_unlock(zone->zone_pgdat, &flags);
>> +}
>> +
>>  static int __remove_section(struct zone *zone, struct mem_section *ms)
>>  {
>>  	unsigned long flags;
>>  	struct pglist_data *pgdat = zone->zone_pgdat;
>> +	unsigned long start_pfn;
>> +	int scn_nr;
>>  	int ret = -EINVAL;
>>  
>>  	if (!valid_section(ms))
>> @@ -325,6 +528,10 @@ static int __remove_section(struct zone *zone, struct mem_section *ms)
>>  	if (ret)
>>  		return ret;
>>  
>> +	scn_nr = __section_nr(ms);
>> +	start_pfn = section_nr_to_pfn(scn_nr);
>> +	__remove_zone(zone, start_pfn);
>> +
>>  	pgdat_resize_lock(pgdat, &flags);
>>  	sparse_remove_one_section(zone, ms);
>>  	pgdat_resize_unlock(pgdat, &flags);
>>
> 
> 

^ permalink raw reply

* RE: [PATCH][V4] powerpc/fsl-pci: Add pci inbound/outbound PM support
From: Jia Hongtao-B38951 @ 2012-10-30  2:57 UTC (permalink / raw)
  To: Jia Hongtao-B38951, Kumar Gala
  Cc: Wood Scott-B07421, linuxppc-dev@lists.ozlabs.org, Li Yang-R58472
In-Reply-To: <412C8208B4A0464FA894C5F0C278CD5D01ADB25D@039-SN1MPN1-003.039d.mgd.msft.net>

Hi Kumar,

Since PCI controller PM support is inactive for a long while I'd
like to submit a new patch using re-setup atmu to restore PCI states.
Maybe the outbound IO issue during first bootup will be discussed
later when you have time.

- Hongtao.

> -----Original Message-----
> From: Jia Hongtao-B38951
> Sent: Wednesday, October 24, 2012 9:59 AM
> To: Jia Hongtao-B38951; Kumar Gala
> Cc: Wood Scott-B07421; linuxppc-dev@lists.ozlabs.org; Li Yang-R58472
> Subject: RE: [PATCH][V4] powerpc/fsl-pci: Add pci inbound/outbound PM
> support
>=20
> Hi Kumar,
>=20
> This PCI controller PM thing is pending for nearly a month without
> further discussion. Maybe it's time now to reach an agreement.
>=20
> - Hongtao.
>=20
>=20
>=20
> > -----Original Message-----
> > From: Jia Hongtao-B38951
> > Sent: Friday, October 19, 2012 12:15 PM
> > To: 'Kumar Gala'
> > Cc: Wood Scott-B07421; linuxppc-dev@lists.ozlabs.org; Li Yang-R58472
> > Subject: RE: [PATCH][V4] powerpc/fsl-pci: Add pci inbound/outbound PM
> > support
> >
> > > -----Original Message-----
> > > From: Kumar Gala [mailto:galak@kernel.crashing.org]
> > > Sent: Thursday, September 27, 2012 8:06 PM
> > > To: Jia Hongtao-B38951
> > > Cc: Wood Scott-B07421; linuxppc-dev@lists.ozlabs.org; Li Yang-R58472
> > > Subject: Re: [PATCH][V4] powerpc/fsl-pci: Add pci inbound/outbound
> > > PM support
> > >
> > > >>>>>>>>>>
> > > >>>>>>>>>> On Sep 17, 2012, at 9:10 PM, Jia Hongtao wrote:
> > > >>>>>>>>>>
> > > >>>>>>>>>>> Power supply for PCI inbound/outbound window registers
> > > >>>>>>>>>>> is off when system go to deep-sleep state. We save the
> > > >>>>>>>>>>> values of registers
> > > >>>>>>> before
> > > >>>>>>>>>>> suspend and restore to registers after resume.
> > > >>>>>>>>>>>
> > > >>>>>>>>>>> Signed-off-by: Jiang Yutang <b14898@freescale.com>
> > > >>>>>>>>>>> Signed-off-by: Jia Hongtao <B38951@freescale.com>
> > > >>>>>>>>>>> Signed-off-by: Li Yang <leoli@freescale.com>
> > > >>>>>>>>>>> ---
> > > >>>>>>>>>>> Changes for V4:
> > > >>>>>>>>>>> We just rebase the patch upon following patch:
> > > >>>>>>>>>>> powerpc/fsl-pci: Unify pci/pcie initialization code
> > > >>>>>>>>>>>
> > > >>>>>>>>>>> arch/powerpc/include/asm/pci-bridge.h |    2 +-
> > > >>>>>>>>>>> arch/powerpc/sysdev/fsl_pci.c         |  121
> > > >>>>>>>>>> +++++++++++++++++++++++++++++++++
> > > >>>>>>>>>>> 2 files changed, 122 insertions(+), 1 deletions(-)
> > > >>>>>>>>>>
> > > >>>>>>>>>> Did you ever compare this to just re-parsing device tree
> > > method?
> > > >>>>>>>>>>
> > > >>>>>>>>>> - k
> > > >>>>>>>>>
> > > >>>>>>>>> I tested the re-parsing way by using setup_pci_atmu() when
> > > >> resume.
> > > >>>>>>>>> And I found out that re-parsing will *change* outbound IO
> > > >>>>>>>>> translation address regitster.
> > > >>>>>>>>>
> > > >>>>>>>>> It seems that in the first bootup, after setup_atmu()
> > > >>>>>>>>> pcibios_setup_phb_resources() may update
> > > >>>>>>>>> hose->io_resource, but atmu is not updated according to
> > > >>>>>>>>> the new
> > > >>>>>>>>> hose->io_resource
> > > value.
> > > >>>>>>>>> In resume from sleep setup_atmu() will reset atmu
> > > >>>>>>>>> according to the new hose->io_resource value. So the
> > > >>>>>>>>> setup_atmu() will cause different result on outbound IO
> > > >>>>>>>>> register between first bootup and resume from sleep.
> > > >>>>>>>>>
> > > >>>>>>>>> So... There's a possibility that in the first bootup atmu
> > > >>>>>>>>> is not setup properly.
> > > >>>>>>>>
> > > >>>>>>>> [Are you seeing this happen in your testing?  If so its a
> > > >>>>>>>> bug we need
> > > >>>>>>> to look at fixing.]
> > > >>>>>>>>
> > > >>>>>>>> Yes, I see this in my testing.
> > > >>>>>>>> Also PCIe ethernet card works well after resuming from
> > > >>>>>>>> sleep in both
> > > >>>>>>> save/restore
> > > >>>>>>>> and re-parsing way. (Maybe PCIe ethernet card don't need
> > > >>>>>>>> outbound IO
> > > >>>>>>> resource)
> > > >>>>>>>> So, I guess the result of re-parsing (actually it's
> > > >>>>>>>> re-setup) is right
> > > >>>>>>> and ATMU is not setup
> > > >>>>>>>> properly at the first bootup.
> > > >>>>>>>
> > > >>>>>>> Are you seeing the following message - "PCI: I/O resource
> > > >>>>>>> not set for host bridge" ?
> > > >>>>>>
> > > >>>>>> No.
> > > >>>>>>
> > > >>>>>>>
> > > >>>>>>> Trying to understand why you'd hit the reassignment of
> > > io_resource.
> > > >>>>>>>
> > > >>>>>>> - k
> > > >>>>>>>
> > > >>>>>>
> > > >>>>>> I did some investigations and the conclusion is:
> > > >>>>>>
> > > >>>>>> io_resource.flags & IORESOURCE_IO are both positive but
> > > >>>>>> io_resource.start is 0 before pcibios_setup_phb_io_space() is
> > done.
> > > >>>>>>
> > > >>>>>> The sequence of related process listed below:
> > > >>>>>> fsl_add_bridge() -> setup_pci_atmu()
> > > >>>>>> pcibios_init() -> pcibios_scan_phb() ->
> > > >>>>>> pcibios_setup_phb_io_space()
> > > >>>>>>
> > > >>>>>> Because fsl_add_bridge() must be finished before
> > > >>>>>> pcibios_init() so ATMU is set when io_resource.start is 0.
> > > >>>>>> That means outbound IO regs are not set.
> > > >>>>>>
> > > >>>>>> If system re-setup ATMU the io_resource.start has already
> > > >>>>>> updated so outbound IO regs are set.
> > > >>>>>>
> > > >>>>>> My question is:
> > > >>>>>> Is there any problem if outbound IO regs are not set in first
> > > >> bootup?
> > > >>>
> > > >>> Yes, it means that IO transactions would not work.
> > > >>
> > > >> I agree.
> > > >>
> > > >>>
> > > >>>>> Please also provide the IO resource address range before and
> > > >>>>> after the pci scan.  Then we can evaluate if the range is
> > > >>>>> needed to be mapped
> > > >>> via
> > > >>>>> ATMU.
> > > >>>>>
> > > >>>>> Leo
> > > >>>>
> > > >>>> Since potar is set by out_be32(&pci->pow[j].potar, (hose-
> > > >>>> io_resource.start >> 12);  I provide the result of
> > > >>>> hose->io_resource.start >> 12 as follows:
> > > >>>>
> > > >>>> pcie@ffe09000:
> > > >>>> before pci scan: io_resource.start >> 12: 0 after pci scan :
> > > >>>> io_resource.start >> 12: ff7ed
> > > >>>>
> > > >>>> pcie@ffe0a000:
> > > >>>> before pci scan: io_resource.start >> 12: 0 after pci scan :
> > > >>>> io_resource.start >> 12: ff7db
> > > >>>>
> > > >>>> pcie@ffe0b000:
> > > >>>> before pci scan: io_resource.start >> 12: 0 after pci scan :
> > > >>>> io_resource.start >> 12: ff7c9
> > > >>>>
> > > >>>> Note that I tested on P1022DS.
> > > >>>>
> > > >>>> - Hongtao.
> > > >>>
> > > >>> 1. What's the device tree nodes for PCIe look like?
> > > >>> 2. Can you get the pr_debug() in setup_pci_atmu() to print and
> > > >>> report results (as well as full boot log)
> > > >>
> > > >> Please refer to the attached file.
> > > >> In the log file I also print the device tree.
> > > >>
> > > >> - Hongtao.
> > > >>
> > > >>>
> > > >>> However, I think the change of the io_resource.start is normal
> > > >>> and correct behavior.
> > > >>>
> > > >>> - k
> > > >>>
> > > >>
> > > >
> > > > Hi Kumar,
> > > > I have already sent the log.
> > > > Do you have any comment on it?
> > > >
> > > > Thanks.
> > > > - Hongtao.
> > > >
> > >
> > > Hongtao,
> > >
> > > You mentioned:
> > >
> > > > I tested the re-parsing way by using setup_pci_atmu() when resume.
> > > > And I found out that re-parsing will *change* outbound IO
> > > > translation address regitster.
> > >
> > > What do the values look like in both ATMU registers and io_resource
> > > if you reparse?
> > >
> > > - k
> >
> >
> > Hi Kumar,
> >
> > About this topic do you have any further comments?
> >
> > Thanks.
> > - Hongtao.

^ permalink raw reply

* [PATCH] powerpc/perf: Add missing L2 constraint handling in Power7 PMU
From: Michael Ellerman @ 2012-10-31  2:09 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Paul Mackerras

If we have two cache events that require different settings of the L2SEL
bits in MMCR1 then we can not schedule those events simultaneously. Add
logic to the constraint handling to express that.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/perf/power7-pmu.c |   17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c
index 441af08..2ee01e3 100644
--- a/arch/powerpc/perf/power7-pmu.c
+++ b/arch/powerpc/perf/power7-pmu.c
@@ -54,8 +54,10 @@
  * Layout of constraint bits:
  * 6666555555555544444444443333333333222222222211111111110000000000
  * 3210987654321098765432109876543210987654321098765432109876543210
- *                                                 [  ><><><><><><>
- *                                                  NC P6P5P4P3P2P1
+ *                                              < ><  ><><><><><><>
+ *                                              L2  NC P6P5P4P3P2P1
+ *
+ * L2 - 16-18 - Required L2SEL value (select field)
  *
  * NC - number of counters
  *     15: NC error 0x8000
@@ -72,7 +74,7 @@
 static int power7_get_constraint(u64 event, unsigned long *maskp,
 				 unsigned long *valp)
 {
-	int pmc, sh;
+	int pmc, sh, unit;
 	unsigned long mask = 0, value = 0;
 
 	pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
@@ -90,6 +92,15 @@ static int power7_get_constraint(u64 event, unsigned long *maskp,
 		mask  |= 0x8000;
 		value |= 0x1000;
 	}
+
+	unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK;
+	if (unit == 6) {
+		/* L2SEL must be identical across events */
+		int l2sel = (event >> PM_L2SEL_SH) & PM_L2SEL_MSK;
+		mask  |= 0x7 << 16;
+		value |= l2sel << 16;
+	}
+
 	*maskp = mask;
 	*valp = value;
 	return 0;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH] i2c-cpm: Fix to takeback i2c bus master-ship after a collision
From: sachin surendran @ 2012-10-31  3:00 UTC (permalink / raw)
  To: linuxppc-dev, jochen

[-- Attachment #1: Type: text/plain, Size: 1225 bytes --]

In case of collision on i2c bus the controller which lost bus mastership
stays as a slave
for all subsequent transfers. This results in the i2c controller never
writing to the bus
for future transactions, resulting in i2c transfer timeouts.
  This fix checks for a collision on last I2C transaction and sets the
I2COM_MASTER
bit for the new transaction.

Signed-off-by: Sachin Surendran <sachin.surendran@alliedtelesis.co.nz>
---
 drivers/i2c/busses/i2c-cpm.c |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
index c1e1096..bb94c6d 100644
--- a/drivers/i2c/busses/i2c-cpm.c
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -338,6 +338,14 @@ static int cpm_i2c_xfer(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num)
        tptr = 0;
        rptr = 0;

+       /*
+        * If there was a collision in the last i2c transaction,
+        * Set I2COM_MASTER as it was cleared during collision.
+        */
+       if (in_be16(&tbdf->cbd_sc) & BD_SC_CL) {
+               out_8(&cpm->i2c_reg->i2com, I2COM_MASTER);
+       }
+
        while (tptr < num) {
                pmsg = &msgs[tptr];
                dev_dbg(&adap->dev, "R: %d T: %d\n", rptr, tptr);

[-- Attachment #2: Type: text/html, Size: 1736 bytes --]

^ permalink raw reply related

* Re: [PATCH] powerpc/perf: Add missing L2 constraint handling in Power7 PMU
From: Paul Mackerras @ 2012-10-31  4:18 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev
In-Reply-To: <1351649396-31639-1-git-send-email-michael@ellerman.id.au>

On Wed, Oct 31, 2012 at 01:09:56PM +1100, Michael Ellerman wrote:
> If we have two cache events that require different settings of the L2SEL
> bits in MMCR1 then we can not schedule those events simultaneously. Add
> logic to the constraint handling to express that.
> 
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>

Acked-by: Paul Mackerras <paulus@samba.org>

^ permalink raw reply

* [PATCH 1/4] powerpc: make POWER7 setup code generic name
From: Michael Neuling @ 2012-10-31  5:34 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev

We are going to reuse this in POWER8 so make the name generic.

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/kernel/Makefile                       |    2 +-
 .../{cpu_setup_power7.S => cpu_setup_power.S}      |    0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename arch/powerpc/kernel/{cpu_setup_power7.S => cpu_setup_power.S} (100%)

diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index cde12f8..8f61934 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -38,7 +38,7 @@ obj-$(CONFIG_PPC64)		+= setup_64.o sys_ppc32.o \
 				   paca.o nvram_64.o firmware.o
 obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_ppc970.o cpu_setup_pa6t.o
-obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_power7.o
+obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_power.o
 obj64-$(CONFIG_RELOCATABLE)	+= reloc_64.o
 obj-$(CONFIG_PPC_BOOK3E_64)	+= exceptions-64e.o idle_book3e.o
 obj-$(CONFIG_PPC_A2)		+= cpu_setup_a2.o
diff --git a/arch/powerpc/kernel/cpu_setup_power7.S b/arch/powerpc/kernel/cpu_setup_power.S
similarity index 100%
rename from arch/powerpc/kernel/cpu_setup_power7.S
rename to arch/powerpc/kernel/cpu_setup_power.S
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 2/4] powerpc: Add POWER8 setup code
From: Michael Neuling @ 2012-10-31  5:34 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev
In-Reply-To: <1351661656-6986-1-git-send-email-mikey@neuling.org>

Just a copy of POWER7 for now.  Will update with new code later.

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/kernel/cpu_setup_power.S |   24 ++++++++++++++++++++++++
 arch/powerpc/kernel/cputable.c        |    2 ++
 2 files changed, 26 insertions(+)

diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S
index 76797c5..a92101d 100644
--- a/arch/powerpc/kernel/cpu_setup_power.S
+++ b/arch/powerpc/kernel/cpu_setup_power.S
@@ -44,6 +44,30 @@ _GLOBAL(__restore_cpu_power7)
 	mtlr	r11
 	blr
 
+_GLOBAL(__setup_cpu_power8)
+	mflr	r11
+	bl	__init_hvmode_206
+	mtlr	r11
+	beqlr
+	li	r0,0
+	mtspr	SPRN_LPID,r0
+	bl	__init_LPCR
+	bl	__init_TLB
+	mtlr	r11
+	blr
+
+_GLOBAL(__restore_cpu_power8)
+	mflr	r11
+	mfmsr	r3
+	rldicl.	r0,r3,4,63
+	beqlr
+	li	r0,0
+	mtspr	SPRN_LPID,r0
+	bl	__init_LPCR
+	bl	__init_TLB
+	mtlr	r11
+	blr
+
 __init_hvmode_206:
 	/* Disable CPU_FTR_HVMODE and exit if MSR:HV is not set */
 	mfmsr	r3
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 0514c21..361f6d9 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -68,6 +68,8 @@ extern void __restore_cpu_pa6t(void);
 extern void __restore_cpu_ppc970(void);
 extern void __setup_cpu_power7(unsigned long offset, struct cpu_spec* spec);
 extern void __restore_cpu_power7(void);
+extern void __setup_cpu_power8(unsigned long offset, struct cpu_spec* spec);
+extern void __restore_cpu_power8(void);
 extern void __restore_cpu_a2(void);
 #endif /* CONFIG_PPC64 */
 #if defined(CONFIG_E500)
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 3/4] powerpc: POWER8 cputable entry
From: Michael Neuling @ 2012-10-31  5:34 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev
In-Reply-To: <1351661656-6986-1-git-send-email-mikey@neuling.org>

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/include/asm/cputable.h |   12 ++++++++++--
 arch/powerpc/include/asm/mmu.h      |    1 +
 arch/powerpc/include/asm/reg.h      |    1 +
 arch/powerpc/kernel/cputable.c      |   21 +++++++++++++++++++++
 4 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 21a0687..76f81bd 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -401,6 +401,14 @@ extern const char *powerpc_base_platform;
 	    CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT | \
 	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
 	    CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY)
+#define CPU_FTRS_POWER8 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
+	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
+	    CPU_FTR_MMCRA | CPU_FTR_SMT | \
+	    CPU_FTR_COHERENT_ICACHE | \
+	    CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
+	    CPU_FTR_DSCR | CPU_FTR_SAO  | \
+	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
+	    CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY)
 #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -421,8 +429,8 @@ extern const char *powerpc_base_platform;
 #define CPU_FTRS_POSSIBLE	\
 	    (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 |	\
 	    CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 |	\
-	    CPU_FTRS_POWER7 | CPU_FTRS_CELL | CPU_FTRS_PA6T |		\
-	    CPU_FTR_VSX)
+	    CPU_FTRS_POWER7 | CPU_FTRS_POWER8 | CPU_FTRS_CELL |		\
+	    CPU_FTRS_PA6T | CPU_FTR_VSX)
 #endif
 #else
 enum {
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index 5e38eed..691fd8a 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -101,6 +101,7 @@
 #define MMU_FTRS_POWER5		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
 #define MMU_FTRS_POWER6		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
 #define MMU_FTRS_POWER7		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
+#define MMU_FTRS_POWER8		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
 #define MMU_FTRS_CELL		MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
 				MMU_FTR_CI_LARGE_PAGE
 #define MMU_FTRS_PA6T		MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index d24c141..7b44a6e 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -1029,6 +1029,7 @@
 #define PVR_970MP	0x0044
 #define PVR_970GX	0x0045
 #define PVR_POWER7p	0x004A
+#define PVR_POWER8	0x004B
 #define PVR_BE		0x0070
 #define PVR_PA6T	0x0090
 
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 361f6d9..216ff84 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -96,6 +96,10 @@ extern void __restore_cpu_e5500(void);
 				 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \
 				 PPC_FEATURE_TRUE_LE | \
 				 PPC_FEATURE_PSERIES_PERFMON_COMPAT)
+#define COMMON_USER_POWER8	(COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_06 |\
+				 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \
+				 PPC_FEATURE_TRUE_LE | \
+				 PPC_FEATURE_PSERIES_PERFMON_COMPAT)
 #define COMMON_USER_PA6T	(COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\
 				 PPC_FEATURE_TRUE_LE | \
 				 PPC_FEATURE_HAS_ALTIVEC_COMP)
@@ -465,6 +469,23 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.cpu_restore		= __restore_cpu_power7,
 		.platform		= "power7+",
 	},
+	{	/* Power8 */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x004b0000,
+		.cpu_name		= "POWER8 (raw)",
+		.cpu_features		= CPU_FTRS_POWER8,
+		.cpu_user_features	= COMMON_USER_POWER8,
+		.mmu_features		= MMU_FTRS_POWER8,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.num_pmcs		= 6,
+		.pmc_type		= PPC_PMC_IBM,
+		.oprofile_cpu_type	= "ppc64/power8",
+		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.cpu_setup		= __setup_cpu_power8,
+		.cpu_restore		= __restore_cpu_power8,
+		.platform		= "power8",
+	},
 	{	/* Cell Broadband Engine */
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x00700000,
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 4/4] powerpc/pseries: Update ibm, architecture.vec for PAPR 2.7/POWER8
From: Michael Neuling @ 2012-10-31  5:34 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Michael Neuling, linuxppc-dev
In-Reply-To: <1351661656-6986-1-git-send-email-mikey@neuling.org>

Update ibm,architecture.vec for Sub-Processor Representation Level.
Allows us to support more than one parition per core.

This is untested so far as we don't have pHyp

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 arch/powerpc/kernel/prom_init.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index cb6c123..09b1c7c 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -707,6 +707,7 @@ static void __init early_cmdline_parse(void)
 #define OV5_PFO_HW_RNG		0x80	/* PFO Random Number Generator */
 #define OV5_PFO_HW_842		0x40	/* PFO Compression Accelerator */
 #define OV5_PFO_HW_ENCR		0x20	/* PFO Encryption Accelerator */
+#define OV5_SUB_PROCESSORS	0x01    /* 1,2,or 4 Sub-Processors supported */
 
 /* Option Vector 6: IBM PAPR hints */
 #define OV6_LINUX		0x02	/* Linux is our OS */
@@ -755,7 +756,7 @@ static unsigned char ibm_architecture_vec[] = {
 	OV4_MIN_ENT_CAP,		/* minimum VP entitled capacity */
 
 	/* option vector 5: PAPR/OF options */
-	18 - 2,				/* length */
+	19 - 2,				/* length */
 	0,				/* don't ignore, don't halt */
 	OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
 	OV5_DONATE_DEDICATE_CPU | OV5_MSI,
@@ -776,6 +777,7 @@ static unsigned char ibm_architecture_vec[] = {
 	0,
 	0,
 	OV5_PFO_HW_RNG | OV5_PFO_HW_ENCR | OV5_PFO_HW_842,
+	OV5_SUB_PROCESSORS,
 	/* option vector 6: IBM PAPR hints */
 	4 - 2,				/* length */
 	0,
-- 
1.7.9.5

^ permalink raw reply related

* Re: [RFC][PATCH] perf: Add a few generic stalled-cycles events
From: Sukadev Bhattiprolu @ 2012-10-31  6:40 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Robert Richter, Anton Blanchard, linux-kernel, eranian, acme,
	linuxppc-dev, paulus, mpjohn, mingo, asharma
In-Reply-To: <1351081662.22332.13.camel@twins>

Peter Zijlstra [peterz@infradead.org] wrote:
| On Tue, 2012-10-16 at 11:31 -0700, Sukadev Bhattiprolu wrote:
| > On a side note, how does the kernel on x86 use the 'config' information in 
| > say /sys/bus/event_source/devices/cpu/format/cccr ? On Power7, the raw
| > code encodes the information such as the PMC to use for the event. Is that
| > how the 'config' info in Intel is used ?
| > 
| > Does the 'config' info change from system to system or is it static for
| > a given event on a given CPU ? 
| 
| Have a look at commits (tip/master):
| 
|   641cc938815dfd09f8fa1ec72deb814f0938ac33
|   a47473939db20e3961b200eb00acf5fcf084d755
|   43c032febde48aabcf6d59f47cdcb7b5debbdc63
| 
| 
| So basically
| 
|  /sys/bus/event_source/devices/cpu/format/event
| 
| contains something like:
| 
|   config:0-7
| 
| Which says that for the 'cpu' PMU, field 'event' fills
| perf_event_attr::config bits 0 through 7 (for type=PERF_TYPE_RAW).
| 
| The perf tool syntax for this is:
| 
|   perf stat -e 'cpu/event=0x3c/'
| 
| This basically allows you to expose bitfields in the 'raw' event format
| for ease of writing raw events. I do not know if the Power PMU has such
| or not.

Thanks for the detailed explanation.

Power does not support this yet, but I have started working on it now.

BTW, does this mean that we can use arch-specific names for the sysfs entries
within:

	/sys/bus/event_source/devices/cpu/events/

So instead of the names I came up with in this patch, stalled-cycles-fixed-point
we could use the name used in the CPU spec - 'cmplu_stall_fxu' in the arch
specific code ?

Sukadev

^ permalink raw reply

* [PATCH 0/6] powerpc: SMT priority (PPR) save and restore
From: Haren Myneni @ 2012-10-31  6:49 UTC (permalink / raw)
  To: benh, paulus, anton, mikey; +Cc: linuxppc-dev

[PATCH 0/6] powerpc: SMT priority (PPR) save and restore

On P7 systems, users can define SMT priority levels 2,3 and 4 for
processes so that some can run higher priority than the other ones.
In the current kernel, the default priority is set to 4 which prohibits
processes for using higher priority. Also the kernel boosts the priority to
4 during exceptions without saving the user defined priorities when
the task enters the kernel. So we will be loosing the process PPR value
and can not be restored it back when the task exits the kernel.

This patchset implements saving and restore the user defined PPR value
for all tasks.

With null_syscall testcase (http://ozlabs.org/~anton/junkcode/null_syscall.c),
this feature takes around extra 10 CPU cycles on average for 25 samples. 

Haren Myneni (6):
  powerpc: Move branch instruction from ACCOUNT_CPU_USER_ENTRY to caller
  powerpc: Define CPU_FTR_HAS_PPR
  powerpc: Increase exceptions arrays in paca struct to save PPR
  powerpc: Define ppr in thread_struct
  powerpc: Macros for saving/restore PPR
  powerpc: Implement PPR save/restore

 arch/powerpc/include/asm/cputable.h      |    6 ++-
 arch/powerpc/include/asm/exception-64s.h |   45 ++++++++++++++++++++++++++----
 arch/powerpc/include/asm/paca.h          |    6 ++--
 arch/powerpc/include/asm/ppc_asm.h       |   27 ++++++++++++++++-
 arch/powerpc/include/asm/processor.h     |    6 ++++
 arch/powerpc/include/asm/reg.h           |    1 +
 arch/powerpc/kernel/asm-offsets.c        |    1 +
 arch/powerpc/kernel/entry_64.S           |    6 +++-
 arch/powerpc/kernel/exceptions-64e.S     |    3 +-
 arch/powerpc/kernel/exceptions-64s.S     |   15 +++++----
 arch/powerpc/kernel/process.c            |    2 +
 11 files changed, 96 insertions(+), 22 deletions(-)

^ permalink raw reply

* [PATCH 1/6] powerpc: Move branch instruction from ACCOUNT_CPU_USER_ENTRY to caller
From: Haren Myneni @ 2012-10-31  6:51 UTC (permalink / raw)
  To: benh, paulus, anton, mikey; +Cc: linuxppc-dev

[PATCH 1/6] powerpc: Move branch instruction from ACCOUNT_CPU_USER_ENTRY to caller

The first instruction in ACCOUNT_CPU_USER_ENTRY is 'beq' which checks for
exceptions coming from kernel mode. PPR value will be saved immediately after
ACCOUNT_CPU_USER_ENTRY and is also for user level exceptions. So moved this
branch instruction in the caller code.

Signed-off-by: Haren Myneni <haren@us.ibm.com>
---
 arch/powerpc/include/asm/exception-64s.h |    3 ++-
 arch/powerpc/include/asm/ppc_asm.h       |    2 --
 arch/powerpc/kernel/entry_64.S           |    3 ++-
 arch/powerpc/kernel/exceptions-64e.S     |    3 ++-
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index a43c147..45702e0 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -176,8 +176,9 @@ do_kvm_##n:								\
 	std	r10,0(r1);		/* make stack chain pointer	*/ \
 	std	r0,GPR0(r1);		/* save r0 in stackframe	*/ \
 	std	r10,GPR1(r1);		/* save r1 in stackframe	*/ \
+	beq	4f;			/* if from kernel mode		*/ \
 	ACCOUNT_CPU_USER_ENTRY(r9, r10);				   \
-	std	r2,GPR2(r1);		/* save r2 in stackframe	*/ \
+4:	std	r2,GPR2(r1);		/* save r2 in stackframe	*/ \
 	SAVE_4GPRS(3, r1);		/* save r3 - r6 in stackframe	*/ \
 	SAVE_2GPRS(7, r1);		/* save r7, r8 in stackframe	*/ \
 	ld	r9,area+EX_R9(r13);	/* move r9, r10 to stackframe	*/ \
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index ea2a86e..376e36d 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -30,7 +30,6 @@
 #define ACCOUNT_STOLEN_TIME
 #else
 #define ACCOUNT_CPU_USER_ENTRY(ra, rb)					\
-	beq	2f;			/* if from kernel mode */	\
 	MFTB(ra);			/* get timebase */		\
 	ld	rb,PACA_STARTTIME_USER(r13);				\
 	std	ra,PACA_STARTTIME(r13);					\
@@ -38,7 +37,6 @@
 	ld	ra,PACA_USER_TIME(r13);					\
 	add	ra,ra,rb;		/* add on to user time */	\
 	std	ra,PACA_USER_TIME(r13);					\
-2:
 
 #define ACCOUNT_CPU_USER_EXIT(ra, rb)					\
 	MFTB(ra);			/* get timebase */		\
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 56e0ff0..72c40dd 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -62,8 +62,9 @@ system_call_common:
 	std	r12,_MSR(r1)
 	std	r0,GPR0(r1)
 	std	r10,GPR1(r1)
+	beq	2f			/* if from kernel mode */
 	ACCOUNT_CPU_USER_ENTRY(r10, r11)
-	std	r2,GPR2(r1)
+2:	std	r2,GPR2(r1)
 	std	r3,GPR3(r1)
 	mfcr	r2
 	std	r4,GPR4(r1)
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 4684e33..709c06b 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -159,8 +159,9 @@ exc_##n##_common:							    \
 	std	r9,GPR9(r1);		/* save r9 in stackframe */	    \
 	std	r10,_NIP(r1);		/* save SRR0 to stackframe */	    \
 	std	r11,_MSR(r1);		/* save SRR1 to stackframe */	    \
+	beq	1f			/* if from kernel mode */
 	ACCOUNT_CPU_USER_ENTRY(r10,r11);/* accounting (uses cr0+eq) */	    \
-	ld	r3,excf+EX_R10(r13);	/* get back r10 */		    \
+1:	ld	r3,excf+EX_R10(r13);	/* get back r10 */		    \
 	ld	r4,excf+EX_R11(r13);	/* get back r11 */		    \
 	mfspr	r5,SPRN_SPRG_GEN_SCRATCH;/* get back r13 */		    \
 	std	r12,GPR12(r1);		/* save r12 in stackframe */	    \
-- 
1.7.1

^ permalink raw reply related

* [PATCH 2/6] powerpc: Define CPU_FTR_HAS_PPR
From: Haren Myneni @ 2012-10-31  6:52 UTC (permalink / raw)
  To: benh, paulus, anton, mikey; +Cc: linuxppc-dev

[PATCH 2/6] powerpc: Define CPU_FTR_HAS_PPR

CPU_FTR_HAS_PPR is defined for POWER7.

Signed-off-by: Haren Myneni <haren@us.ibm.com>
---
 arch/powerpc/include/asm/cputable.h |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 21a0687..12e3a1d 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -171,6 +171,7 @@ extern const char *powerpc_base_platform;
 #define CPU_FTR_POPCNTD			LONG_ASM_CONST(0x0800000000000000)
 #define CPU_FTR_ICSWX			LONG_ASM_CONST(0x1000000000000000)
 #define CPU_FTR_VMX_COPY		LONG_ASM_CONST(0x2000000000000000)
+#define	CPU_FTR_HAS_PPR			LONG_ASM_CONST(0x4000000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -400,7 +401,8 @@ extern const char *powerpc_base_platform;
 	    CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
 	    CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT | \
 	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
-	    CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY)
+	    CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | \
+	    CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR)
 #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -422,7 +424,7 @@ extern const char *powerpc_base_platform;
 	    (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 |	\
 	    CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 |	\
 	    CPU_FTRS_POWER7 | CPU_FTRS_CELL | CPU_FTRS_PA6T |		\
-	    CPU_FTR_VSX)
+	    CPU_FTR_VSX | CPU_FTR_HAS_PPR)
 #endif
 #else
 enum {
-- 
1.7.1

^ permalink raw reply related

* [PATCH 3/6] powerpc: Increase exceptions arrays in paca struct to save PPR
From: Haren Myneni @ 2012-10-31  6:54 UTC (permalink / raw)
  To: benh, paulus, anton, mikey; +Cc: linuxppc-dev

[PATCH 3/6] powerpc: Increase exceptions arrays in paca struct to save PPR

Using paca to save user defined PPR value in the first level exception vector.

Signed-off-by: Haren Myneni <haren@us.ibm.com>
---
 arch/powerpc/include/asm/exception-64s.h |    1 +
 arch/powerpc/include/asm/paca.h          |    6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 45702e0..bfd3f1f 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -47,6 +47,7 @@
 #define EX_R3		64
 #define EX_LR		72
 #define EX_CFAR		80
+#define EX_PPR		88	/* SMT thread status register (priority) */
 
 /*
  * We're short on space and time in the exception prolog, so we can't
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index e9e7a69..c47d687 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -93,9 +93,9 @@ struct paca_struct {
 	 * Now, starting in cacheline 2, the exception save areas
 	 */
 	/* used for most interrupts/exceptions */
-	u64 exgen[11] __attribute__((aligned(0x80)));
-	u64 exmc[11];		/* used for machine checks */
-	u64 exslb[11];		/* used for SLB/segment table misses
+	u64 exgen[12] __attribute__((aligned(0x80)));
+	u64 exmc[12];		/* used for machine checks */
+	u64 exslb[12];		/* used for SLB/segment table misses
  				 * on the linear mapping */
 	/* SLB related definitions */
 	u16 vmalloc_sllp;
-- 
1.7.1

^ permalink raw reply related

* [PATCH 4/6] powerpc: Define ppr in thread_struct
From: Haren Myneni @ 2012-10-31  6:55 UTC (permalink / raw)
  To: benh, paulus, anton, mikey; +Cc: linuxppc-dev

[PATCH 4/6] powerpc: Define ppr in thread_struct

ppr in thread_struct is used to save PPR and restore it before process exits
from kernel.

This patch sets the default priority to 3 when tasks are created such
that users can use 4 for higher priority tasks.

Signed-off-by: Haren Myneni <haren@us.ibm.com>
---
 arch/powerpc/include/asm/processor.h |    6 ++++++
 arch/powerpc/kernel/asm-offsets.c    |    1 +
 arch/powerpc/kernel/process.c        |    2 ++
 3 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 8750204..7db5df4 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -245,6 +245,7 @@ struct thread_struct {
 #ifdef CONFIG_PPC64
 	unsigned long	dscr;
 	int		dscr_inherit;
+	unsigned long	ppr;
 #endif
 };
 
@@ -270,6 +271,10 @@ struct thread_struct {
 	SPEFSCR_INIT \
 }
 #else
+/* Default SMT priority is 3. Use 11- 13bits to save priority. */
+/* .ppr is used to save/restore only on P7 or later processors */
+#define INIT_PPR (3ull << 50)
+
 #define INIT_THREAD  { \
 	.ksp = INIT_SP, \
 	.ksp_limit = INIT_SP_LIMIT, \
@@ -278,6 +283,7 @@ struct thread_struct {
 	.fpr = {{0}}, \
 	.fpscr = { .val = 0, }, \
 	.fpexc_mode = 0, \
+	.ppr = INIT_PPR, \
 }
 #endif
 
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 7523539..41f65ec 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -77,6 +77,7 @@ int main(void)
 	DEFINE(NMI_MASK, NMI_MASK);
 	DEFINE(THREAD_DSCR, offsetof(struct thread_struct, dscr));
 	DEFINE(THREAD_DSCR_INHERIT, offsetof(struct thread_struct, dscr_inherit));
+	DEFINE(TASKTHREADPPR, offsetof(struct task_struct, thread.ppr));
 #else
 	DEFINE(THREAD_INFO, offsetof(struct task_struct, stack));
 #endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index ba48233..2563acc 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -814,6 +814,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
 		p->thread.dscr_inherit = current->thread.dscr_inherit;
 		p->thread.dscr = current->thread.dscr;
 	}
+	if (cpu_has_feature(CPU_FTR_HAS_PPR))
+		p->thread.ppr = INIT_PPR;
 #endif
 	/*
 	 * The PPC64 ABI makes use of a TOC to contain function 
-- 
1.7.1

^ permalink raw reply related

* [PATCH 5/6] powerpc: Macros for saving/restore PPR
From: Haren Myneni @ 2012-10-31  6:56 UTC (permalink / raw)
  To: benh, paulus, anton, mikey; +Cc: linuxppc-dev

[PATCH 5/6] powerpc: Macros for saving/restore PPR

Several macros are defined for saving and restore user defined PPR value.

Signed-off-by: Haren Myneni <haren@us.ibm.com>
---
 arch/powerpc/include/asm/exception-64s.h |   29 +++++++++++++++++++++++++++++
 arch/powerpc/include/asm/ppc_asm.h       |   25 +++++++++++++++++++++++++
 arch/powerpc/include/asm/reg.h           |    1 +
 3 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index bfd3f1f..880ef7d 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -62,6 +62,35 @@
 #define EXC_HV	H
 #define EXC_STD
 
+/*
+ * PPR save/restore macros used in exceptions_64s.S  
+ * Used for P7 or later processors
+ */
+#define SAVE_PPR(area, ra, rb)						\
+BEGIN_FTR_SECTION_NESTED(940)						\
+	ld	ra,PACACURRENT(r13);					\
+	ld	rb,area+EX_PPR(r13);	/* Read PPR from paca */	\
+	std	rb,TASKTHREADPPR(ra);					\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,940)
+
+#define RESTORE_PPR_PACA(area, ra)					\
+BEGIN_FTR_SECTION_NESTED(941)						\
+	ld	ra,area+EX_PPR(r13);					\
+	mtspr	SPRN_PPR,ra;						\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,941)
+
+#define HMT_MEDIUM_NO_PPR						\
+BEGIN_FTR_SECTION_NESTED(942)						\
+	HMT_MEDIUM;							\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,0,942)  /*non P7*/		
+
+#define HMT_MEDIUM_HAS_PPR(area, ra)					\
+BEGIN_FTR_SECTION_NESTED(943)						\
+	mfspr	ra,SPRN_PPR;						\
+	std	ra,area+EX_PPR(r13);					\
+	HMT_MEDIUM;							\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,943) 
+
 #define __EXCEPTION_PROLOG_1(area, extra, vec)				\
 	GET_PACA(r13);							\
 	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 376e36d..52649cc 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -389,6 +389,31 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 	FTR_SECTION_ELSE_NESTED(848);	\
 	mtocrf (FXM), RS;		\
 	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_NOEXECUTE, 848)
+
+/*
+ * PPR restore macros used in entry_64.S
+ * Used for P7 or later processors
+ */
+#define HMT_MEDIUM_LOW_HAS_PPR						\
+BEGIN_FTR_SECTION_NESTED(944)						\
+	HMT_MEDIUM_LOW;							\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,944)
+
+#define SET_DEFAULT_THREAD_PPR(ra, rb)					\
+BEGIN_FTR_SECTION_NESTED(945)						\
+	lis	ra,0xc;		/* default ppr=3 */			\
+	ld	rb,PACACURRENT(r13);					\
+	sldi	ra,ra,32;	/* 11- 13 bits are used for ppr */	\
+	std	ra,TASKTHREADPPR(rb);					\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,945)
+
+#define RESTORE_PPR(ra, rb)						\
+BEGIN_FTR_SECTION_NESTED(946)						\
+	ld	ra,PACACURRENT(r13);					\
+	ld	rb,TASKTHREADPPR(ra);					\
+	mtspr	SPRN_PPR,rb;	/* Restore PPR */			\
+END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,946)
+
 #endif
 
 /*
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index d24c141..1723be3 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -287,6 +287,7 @@
 #define SPRN_DBAT6U	0x23C	/* Data BAT 6 Upper Register */
 #define SPRN_DBAT7L	0x23F	/* Data BAT 7 Lower Register */
 #define SPRN_DBAT7U	0x23E	/* Data BAT 7 Upper Register */
+#define SPRN_PPR	0x380	/* SMT Thread status Register */
 
 #define SPRN_DEC	0x016		/* Decrement Register */
 #define SPRN_DER	0x095		/* Debug Enable Regsiter */
-- 
1.7.1

^ permalink raw reply related

* [PATCH 6/6] powerpc: Implement PPR save/restore
From: Haren Myneni @ 2012-10-31  6:57 UTC (permalink / raw)
  To: benh, paulus, anton, mikey; +Cc: linuxppc-dev

[PATCH 6/6] powerpc: Implement PPR save/restore

When the task enters in to kernel space, the user defined priority (PPR)
will be saved in to PACA at the beginning of first level exception
vector and then copy from PACA to thread_info in second level vector.
PPR will be restored from thread_info before exits the kernel space.

P7 temporarily raises the thread priority to higher level during
exception until the program executes HMT_* calls. But it will not modify
PPR register. So we save PPR value whenever some register is available
to use and then calls HMT_MEDIUM to increase the priority. This feature
supports on P7 or later processors.

We save/ restore PPR for all exception vectors except system call entry.
GLIBC will be saving / restore for system calls. So the default PPR
value (3) will be set for the system call exit when the task returned
to the user space.

Signed-off-by: Haren Myneni <haren@us.ibm.com>
---
 arch/powerpc/include/asm/exception-64s.h |   12 +++++++-----
 arch/powerpc/kernel/entry_64.S           |    3 +++
 arch/powerpc/kernel/exceptions-64s.S     |   15 ++++++++-------
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 880ef7d..cf7eae6 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -93,8 +93,9 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,943)
 
 #define __EXCEPTION_PROLOG_1(area, extra, vec)				\
 	GET_PACA(r13);							\
-	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
-	std	r10,area+EX_R10(r13);					\
+	std	r9,area+EX_R9(r13);	/* save r9 */			\
+	HMT_MEDIUM_HAS_PPR(area, r9);					\
+	std	r10,area+EX_R10(r13);	/* save r10 - r12 */		\
 	BEGIN_FTR_SECTION_NESTED(66);					\
 	mfspr	r10,SPRN_CFAR;						\
 	std	r10,area+EX_CFAR(r13);					\
@@ -208,6 +209,7 @@ do_kvm_##n:								\
 	std	r10,GPR1(r1);		/* save r1 in stackframe	*/ \
 	beq	4f;			/* if from kernel mode		*/ \
 	ACCOUNT_CPU_USER_ENTRY(r9, r10);				   \
+	SAVE_PPR(area, r9, r10);					   \
 4:	std	r2,GPR2(r1);		/* save r2 in stackframe	*/ \
 	SAVE_4GPRS(3, r1);		/* save r3 - r6 in stackframe	*/ \
 	SAVE_2GPRS(7, r1);		/* save r7, r8 in stackframe	*/ \
@@ -249,7 +251,7 @@ do_kvm_##n:								\
 	. = loc;					\
 	.globl label##_pSeries;				\
 label##_pSeries:					\
-	HMT_MEDIUM;					\
+	HMT_MEDIUM_NO_PPR;				\
 	SET_SCRATCH0(r13);		/* save r13 */		\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common,	\
 				 EXC_STD, KVMTEST_PR, vec)
@@ -258,7 +260,7 @@ label##_pSeries:					\
 	. = loc;					\
 	.globl label##_hv;				\
 label##_hv:						\
-	HMT_MEDIUM;					\
+	HMT_MEDIUM_NO_PPR;				\
 	SET_SCRATCH0(r13);	/* save r13 */			\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common,	\
 				 EXC_HV, KVMTEST, vec)
@@ -289,7 +291,7 @@ label##_hv:						\
 	_SOFTEN_TEST(EXC_STD, vec)
 
 #define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra)		\
-	HMT_MEDIUM;							\
+	HMT_MEDIUM_NO_PPR;						\
 	SET_SCRATCH0(r13);    /* save r13 */				\
 	__EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec);		\
 	EXCEPTION_PROLOG_PSERIES_1(label##_common, h);
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 72c40dd..1d0f409 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -227,6 +227,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
 
 	beq-	1f
 	ACCOUNT_CPU_USER_EXIT(r11, r12)
+	HMT_MEDIUM_LOW_HAS_PPR
 	ld	r13,GPR13(r1)	/* only restore r13 if returning to usermode */
 1:	ld	r2,GPR2(r1)
 	ld	r1,GPR1(r1)
@@ -303,6 +304,7 @@ syscall_exit_work:
 	subi	r12,r12,TI_FLAGS
 
 4:	/* Anything else left to do? */
+	SET_DEFAULT_THREAD_PPR(r3, r9)		/* Set thread.ppr = 3 */
 	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
 	beq	.ret_from_except_lite
 
@@ -762,6 +764,7 @@ fast_exception_return:
 	andi.	r0,r3,MSR_PR
 	beq	1f
 	ACCOUNT_CPU_USER_EXIT(r2, r4)
+	RESTORE_PPR(r2, r4)
 	REST_GPR(13, r1)
 1:
 	mtspr	SPRN_SRR1,r3
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 10b658a..0fa2c88 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -40,7 +40,7 @@ __start_interrupts:
 
 	.globl system_reset_pSeries;
 system_reset_pSeries:
-	HMT_MEDIUM;
+	HMT_MEDIUM_NO_PPR;
 	SET_SCRATCH0(r13)
 #ifdef CONFIG_PPC_P7_NAP
 BEGIN_FTR_SECTION
@@ -94,7 +94,7 @@ machine_check_pSeries_1:
 	. = 0x300
 	.globl data_access_pSeries
 data_access_pSeries:
-	HMT_MEDIUM
+	HMT_MEDIUM_NO_PPR
 	SET_SCRATCH0(r13)
 BEGIN_FTR_SECTION
 	b	data_access_check_stab
@@ -106,7 +106,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB)
 	. = 0x380
 	.globl data_access_slb_pSeries
 data_access_slb_pSeries:
-	HMT_MEDIUM
+	HMT_MEDIUM_NO_PPR
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x380)
 	std	r3,PACA_EXSLB+EX_R3(r13)
@@ -137,7 +137,7 @@ data_access_slb_pSeries:
 	. = 0x480
 	.globl instruction_access_slb_pSeries
 instruction_access_slb_pSeries:
-	HMT_MEDIUM
+	HMT_MEDIUM_NO_PPR
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480)
 	std	r3,PACA_EXSLB+EX_R3(r13)
@@ -321,7 +321,7 @@ denorm_exception_hv:
 machine_check_pSeries:
 	.globl machine_check_fwnmi
 machine_check_fwnmi:
-	HMT_MEDIUM
+	HMT_MEDIUM_NO_PPR
 	SET_SCRATCH0(r13)		/* save r13 */
 	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common,
 				 EXC_STD, KVMTEST, 0x200)
@@ -540,7 +540,7 @@ _GLOBAL(__replay_interrupt)
 	.globl system_reset_fwnmi
       .align 7
 system_reset_fwnmi:
-	HMT_MEDIUM
+	HMT_MEDIUM_NO_PPR
 	SET_SCRATCH0(r13)		/* save r13 */
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
 				 NOTEST, 0x100)
@@ -843,6 +843,7 @@ _GLOBAL(slb_miss_realmode)
 	mtcrf	0x01,r9		/* slb_allocate uses cr0 and cr7 */
 .machine	pop
 
+	RESTORE_PPR_PACA(PACA_EXSLB, r9)
 	ld	r9,PACA_EXSLB+EX_R9(r13)
 	ld	r10,PACA_EXSLB+EX_R10(r13)
 	ld	r11,PACA_EXSLB+EX_R11(r13)
@@ -1175,7 +1176,7 @@ initial_stab:
 
 #ifdef CONFIG_PPC_POWERNV
 _GLOBAL(opal_mc_secondary_handler)
-	HMT_MEDIUM
+	HMT_MEDIUM_NO_PPR
 	SET_SCRATCH0(r13)
 	GET_PACA(r13)
 	clrldi	r3,r3,2
-- 
1.7.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox