* Re: [PATCH] powerpc/kvm: support to handle sw breakpoint
From: Alexander Graf @ 2014-06-17 11:31 UTC (permalink / raw)
To: Madhavan Srinivasan, Benjamin Herrenschmidt
Cc: linuxppc-dev, paulus, kvm-ppc, kvm
In-Reply-To: <53A0248D.7070909@linux.vnet.ibm.com>
On 17.06.14 13:20, Madhavan Srinivasan wrote:
> On Tuesday 17 June 2014 03:13 PM, Alexander Graf wrote:
>> On 17.06.14 11:32, Benjamin Herrenschmidt wrote:
>>> On Tue, 2014-06-17 at 11:25 +0200, Alexander Graf wrote:
>>>> On 17.06.14 11:22, Benjamin Herrenschmidt wrote:
>>>>> On Tue, 2014-06-17 at 10:54 +0200, Alexander Graf wrote:
>>>>>> Also, why don't we use twi always or something else that actually is
>>>>>> defined as illegal instruction? I would like to see this shared with
>>>>>> book3s_32 PR.
>>>>> twi will be directed to the guest on HV no ? We want a real illegal
>>>>> because those go to the host (for potential emulation by the HV).
>>>> Ah, good point. I guess we need different one for PR and HV then to
>>>> ensure compatibility with older ISAs on PR.
>>> Well, we also need to be careful with what happens if a PR guest puts
>>> that instruction in, do that stop its HV guest/host ?
>>>
>>> What if it's done in userspace ? Do that stop the kernel ? :-)
>> The way SW breakpointing is handled is that when we see one, it gets
>> deflected into user space. User space then has an array of breakpoints
>> it configured itself. If the breakpoint is part of that list, it
>> consumes it. If not, it injects a debug interrupt (program in this case)
>> into the guest.
>>
>> That way we can overlay that one instruction with as many layers as we
>> like :). We only get a performance hit on execution of that instruction.
>>
>>> Maddy, I haven't checked, does your patch ensure that we only ever stop
>>> if the instruction is at a recorded bkpt address ? It still means that a
>>> userspace process can practically DOS its kernel by issuing a lot of
>>> these causing a crapload of exits.
>> Only user space knows about its breakpoint addresses, so we have to
>> deflect. However since time still ticks on, we only increase jitter of
>> the guest. The process would still get scheduled away after the same
> ^^^ Where is this taken care. I am still trying to understand. Kindly
> can you explain or point to the code. Will help.
We tell the guest via VPA about its steal time which includes QEMU time.
Alex
^ permalink raw reply
* Re: [PATCH tty-next 14/22] tty: Remove tty_wait_until_sent_from_close()
From: Arnd Bergmann @ 2014-06-17 11:31 UTC (permalink / raw)
To: David Laight
Cc: One Thousand Gnomes, Karsten Keil, 'Peter Hurley',
Greg Kroah-Hartman, linux-kernel@vger.kernel.org,
linux-serial@vger.kernel.org, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D1725DAF6@AcuExch.aculab.com>
On Tuesday 17 June 2014 11:03:50 David Laight wrote:
> From: Peter Hurley
> ...
> > > I don't understand the second half of the changelog, it doesn't seem
> > > to fit here: there deadlock that we are trying to avoid here happens
> > > when the *same* tty needs the lock to complete the function that
> > > sends the pending data. I don't think we do still do that any more,
> > > but it doesn't seem related to the tty lock being system-wide or not.
> >
> > The tty lock is not used in the i/o path; it's purpose is to
> > mutually exclude state changes in open(), close() and hangup().
> >
> > The commit that added this [1] comments that _other_ ttys may wait
> > for this tty to complete, and comments in the code note that this
> > function should be removed when the system-wide tty mutex was removed
> > (which happened with the commit noted in the changelog).
>
> What happens if another process tries to do a non-blocking open
> while you are sleeping in close waiting for output to drain?
>
> Hopefully this returns before that data has drained.
Before the patch, I believe tty_reopen() would return -EIO because
the TTY_CLOSING flag is set. After the patch, tty_open() blocks
on tty_lock() before calling tty_reopen(). AFAICT, this is independent
of O_NONBLOCK.
Arnd
^ permalink raw reply
* Re: [PATCH tty-next 14/22] tty: Remove tty_wait_until_sent_from_close()
From: Peter Hurley @ 2014-06-17 11:32 UTC (permalink / raw)
To: David Laight, Arnd Bergmann
Cc: One Thousand Gnomes, Karsten Keil, Greg Kroah-Hartman,
linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D1725DAF6@AcuExch.aculab.com>
On 06/17/2014 07:03 AM, David Laight wrote:
> From: Peter Hurley
> ...
>>> I don't understand the second half of the changelog, it doesn't seem
>>> to fit here: there deadlock that we are trying to avoid here happens
>>> when the *same* tty needs the lock to complete the function that
>>> sends the pending data. I don't think we do still do that any more,
>>> but it doesn't seem related to the tty lock being system-wide or not.
>>
>> The tty lock is not used in the i/o path; it's purpose is to
>> mutually exclude state changes in open(), close() and hangup().
>>
>> The commit that added this [1] comments that _other_ ttys may wait
>> for this tty to complete, and comments in the code note that this
>> function should be removed when the system-wide tty mutex was removed
>> (which happened with the commit noted in the changelog).
>
> What happens if another process tries to do a non-blocking open
> while you are sleeping in close waiting for output to drain?
>
> Hopefully this returns before that data has drained.
Good point.
tty_open() should be trylocking both mutexes anyway in O_NONBLOCK.
Regards,
Peter Hurley
^ permalink raw reply
* RE: [PATCH] KVM: PPC: e500mc: Relax tlb invalidation condition on vcpu schedule
From: mihai.caraman @ 2014-06-17 12:00 UTC (permalink / raw)
To: Alexander Graf, Scott Wood
Cc: linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org,
kvm-ppc@vger.kernel.org
In-Reply-To: <53A0059E.7060501@suse.de>
PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBBbGV4YW5kZXIgR3JhZiBbbWFp
bHRvOmFncmFmQHN1c2UuZGVdDQo+IFNlbnQ6IFR1ZXNkYXksIEp1bmUgMTcsIDIwMTQgMTI6MDkg
UE0NCj4gVG86IFdvb2QgU2NvdHQtQjA3NDIxDQo+IENjOiBDYXJhbWFuIE1paGFpIENsYXVkaXUt
QjAyMDA4OyBrdm0tcHBjQHZnZXIua2VybmVsLm9yZzsNCj4ga3ZtQHZnZXIua2VybmVsLm9yZzsg
bGludXhwcGMtZGV2QGxpc3RzLm96bGFicy5vcmcNCj4gU3ViamVjdDogUmU6IFtQQVRDSF0gS1ZN
OiBQUEM6IGU1MDBtYzogUmVsYXggdGxiIGludmFsaWRhdGlvbiBjb25kaXRpb24NCj4gb24gdmNw
dSBzY2hlZHVsZQ0KPiANCj4gDQo+IE9uIDEzLjA2LjE0IDIxOjQyLCBTY290dCBXb29kIHdyb3Rl
Og0KPiA+IE9uIEZyaSwgMjAxNC0wNi0xMyBhdCAxNjo1NSArMDIwMCwgQWxleGFuZGVyIEdyYWYg
d3JvdGU6DQo+ID4+IE9uIDEzLjA2LjE0IDE2OjQzLCBtaWhhaS5jYXJhbWFuQGZyZWVzY2FsZS5j
b20gd3JvdGU6DQo+ID4+Pj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gPj4+PiBGcm9t
OiBBbGV4YW5kZXIgR3JhZiBbbWFpbHRvOmFncmFmQHN1c2UuZGVdDQo+ID4+Pj4gU2VudDogVGh1
cnNkYXksIEp1bmUgMTIsIDIwMTQgODowNSBQTQ0KPiA+Pj4+IFRvOiBDYXJhbWFuIE1paGFpIENs
YXVkaXUtQjAyMDA4DQo+ID4+Pj4gQ2M6IGt2bS1wcGNAdmdlci5rZXJuZWwub3JnOyBrdm1Admdl
ci5rZXJuZWwub3JnOyBsaW51eHBwYy0NCj4gPj4+PiBkZXZAbGlzdHMub3psYWJzLm9yZzsgV29v
ZCBTY290dC1CMDc0MjENCj4gPj4+PiBTdWJqZWN0OiBSZTogW1BBVENIXSBLVk06IFBQQzogZTUw
MG1jOiBSZWxheCB0bGIgaW52YWxpZGF0aW9uDQo+IGNvbmRpdGlvbg0KPiA+Pj4+IG9uIHZjcHUg
c2NoZWR1bGUNCj4gPj4+Pg0KPiA+Pj4+IE9uIDA2LzEyLzIwMTQgMDQ6MDAgUE0sIE1paGFpIENh
cmFtYW4gd3JvdGU6DQo+ID4+Pj4+IE9uIHZjcHUgc2NoZWR1bGUsIHRoZSBjb25kaXRpb24gY2hl
Y2tlZCBmb3IgdGxiIHBvbGx1dGlvbiBpcyB0b28NCj4gdGlnaHQuDQo+ID4+Pj4+IFRoZSB0bGIg
ZW50cmllcyBvZiBvbmUgdmNwdSBhcmUgcG9sbHV0ZWQgd2hlbiBhIGRpZmZlcmVudCB2Y3B1IGZy
b20NCj4gdGhlDQo+ID4+Pj4+IHNhbWUgcGFydGl0aW9uIHJ1bnMgaW4tYmV0d2Vlbi4gUmVsYXgg
dGhlIGN1cnJlbnQgdGxiIGludmFsaWRhdGlvbg0KPiA+Pj4+PiBjb25kaXRpb24gdGFraW5nIGlu
dG8gYWNjb3VudCB0aGUgbHBpZC4NCj4gPiBDYW4geW91IHF1YW50aWZ5IHRoZSBwZXJmb3JtYW5j
ZSBpbXByb3ZlbWVudCBmcm9tIHRoaXM/ICBXZSd2ZSBoYWQgYnVncw0KPiA+IGluIHRoaXMgYXJl
YSBiZWZvcmUsIHNvIGxldCdzIG1ha2Ugc3VyZSBpdCdzIHdvcnRoIGl0IGJlZm9yZSBtYWtpbmcN
Cj4gdGhpcw0KPiA+IG1vcmUgY29tcGxpY2F0ZWQuDQo+ID4NCj4gPj4+Pj4gU2lnbmVkLW9mZi1i
eTogTWloYWkgQ2FyYW1hbiA8bWloYWkuY2FyYW1hbiA8YXQ+IGZyZWVzY2FsZS5jb20+DQo+ID4+
Pj4gWW91ciBtYWlsZXIgaXMgYnJva2VuPyA6KQ0KPiA+Pj4+IFRoaXMgcmVhbGx5IHNob3VsZCBi
ZSBhbiBALg0KPiA+Pj4+DQo+ID4+Pj4gSSB0aGluayB0aGlzIHNob3VsZCB3b3JrLiBTY290dCwg
cGxlYXNlIGFjay4NCj4gPj4+IEFsZXgsIHlvdSB3ZXJlIHJpZ2h0LiBJIHNjcmV3ZWQgdXAgdGhl
IHBhdGNoIGRlc2NyaXB0aW9uIGJ5IGludmVydGluZw0KPiByZWxheA0KPiA+Pj4gYW5kIHRpZ2h0
IHRlcm1zIDopIEl0IHNob3VsZCBoYXZlIGJlZW4gbW9yZSBsaWtlIHRoaXM6DQo+ID4+Pg0KPiA+
Pj4gS1ZNOiBQUEM6IGU1MDBtYzogRW5oYW5jZSB0bGIgaW52YWxpZGF0aW9uIGNvbmRpdGlvbiBv
biB2Y3B1IHNjaGVkdWxlDQo+ID4+Pg0KPiA+Pj4gT24gdmNwdSBzY2hlZHVsZSwgdGhlIGNvbmRp
dGlvbiBjaGVja2VkIGZvciB0bGIgcG9sbHV0aW9uIGlzIHRvbw0KPiBsb29zZS4NCj4gPj4+IFRo
ZSB0bGIgZW50cmllcyBvZiBhIHZjcHUgYXJlIHBvbGx1dGVkICh2cyBzdGFsZSkgb25seSB3aGVu
IGENCj4gZGlmZmVyZW50IHZjcHUNCj4gPj4+IHdpdGhpbiB0aGUgc2FtZSBsb2dpY2FsIHBhcnRp
dGlvbiBydW5zIGluLWJldHdlZW4uIE9wdGltaXplIHRoZSB0bGINCj4gaW52YWxpZGF0aW9uDQo+
ID4+PiBjb25kaXRpb24gdGFraW5nIGludG8gYWNjb3VudCB0aGUgbHBpZC4NCj4gPj4gQ2FuJ3Qg
d2UgZ2l2ZSBldmVyeSB2Y3B1IGl0cyBvd24gbHBpZD8gT3IgZG9uJ3Qgd2UgdHJhcCBvbiBnbG9i
YWwNCj4gPj4gaW52YWxpZGF0ZXM/DQo+ID4gVGhhdCB3b3VsZCBzaWduaWZpY2FudGx5IGluY3Jl
YXNlIHRoZSBvZGRzIG9mIGV4aGF1c3RpbmcgTFBJRHMsDQo+ID4gZXNwZWNpYWxseSBvbiBsYXJn
ZSBjaGlwcyBsaWtlIHQ0MjQwIHdpdGggc2ltaWxhcmx5IGxhcmdlIFZNcy4gIElmIHdlDQo+ID4g
d2VyZSB0byBkbyB0aGF0LCB0aGUgTFBJRHMgd291bGQgbmVlZCB0byBiZSBkeW5hbWljYWxseSBh
c3NpZ25lZCAobGlrZQ0KPiA+IFBJRHMpLCBhbmQgc2hvdWxkIHByb2JhYmx5IGJlIGEgc2VwYXJh
dGUgbnVtYmVyc3BhY2UgcGVyIHBoeXNpY2FsIGNvcmUuDQo+IA0KPiBUcnVlLCBJIGRpZG4ndCBy
ZWFsaXplIHdlIG9ubHkgaGF2ZSBzbyBmZXcgb2YgdGhlbS4gSXQgd291bGQgaG93ZXZlcg0KPiBz
YXZlIHVzIGZyb20gbW9zdCBmbHVzaGluZyBhcyBsb25nIGFzIHdlIGhhdmUgc3BhcmUgTFBJRHMg
YXZhaWxhYmxlIDopLg0KDQpZZXMsIHdlIGhhZCB0aGlzIHByb3Bvc2FsIG9uIHRoZSB0YWJsZSBm
b3IgZTY1MDAgbXVsdGl0aHJlYWRlZCBjb3JlLiBUaGlzDQpjb3JlIGxhY2tzIHRsYiB3cml0ZSBj
b25kaXRpb25hbCBpbnN0cnVjdGlvbiwgc28gYW4gT1MgbmVlZHMgdG8gdXNlIGxvY2tzDQp0byBw
cm90ZWN0IGl0c2VsZiBhZ2FpbnN0IGNvbmN1cnJlbnQgdGxiIHdyaXRlcyBleGVjdXRlZCBmcm9t
IHNpYmxpbmcgdGhyZWFkcy4NCldoZW4gd2UgZXhwb3NlIGh3IHRyZWFkcyBhcyBzaW5nbGUtdGhy
ZWFkZWQgdmNwdXMgKHVzZWZ1bCB3aGVuIHRoZSB1c2VyIG9wdA0Kbm90IHRvIHBpbiB2Y3B1cyks
IHRoZSBndWVzdCBjYW4ndCBubyBsb25nZXIgcHJvdGVjdCBpdHNlbGYgb3B0aW1hbGx5DQooaXQg
Y2FuIHByb3RlY3QgdGxiIHdyaXRlcyBhY3Jvc3MgYWxsIHRocmVhZHMgYnV0IHRoaXMgaXMgbm90
IGFjY2VwdGFibGUpLg0KU28gaW5zdGVhZCwgd2UgZm91bmQgYSBzb2x1dGlvbiBhdCBoeXBlcnZp
c29yIGxldmVsIGJ5IGFzc2lnbmluZyBkaWZmZXJlbnQNCmxvZ2ljYWwgcGFydGl0aW9uIGlkcyB0
byBndWVzdCdzIHZjcHVzIHJ1bm5pbmcgc2ltdWx0YW5lb3VzIG9uIHNpYmxpbmcgaHcNCnRocmVh
ZHMuIEN1cnJlbnRseSBpbiBGU0wgU0RLIHdlIGFsbG9jYXRlIHR3byBscGlkcyB0byBlYWNoIGd1
ZXN0Lg0KDQpJIGFtIGFsc28gYSBwcm9wb25lbnQgZm9yIHVzaW5nIGFsbCBMUElEIHNwYWNlICg2
MyB2YWx1ZXMpIHBlciAobXVsdGktdGhyZWFkZWQpDQpwaHlzaWNhbCBjb3JlLCB3aGljaCB3aWxs
IGxlYWQgdG8gZmV3ZXIgaW52YWxpZGF0ZXMgb24gdmNwdSBzY2hlZHVsZSBhbmQgd2lsbA0KYWNj
b21tb2RhdGUgdGhlIHNvbHV0aW9uIGRlc2NyaWJlZCBhYm92ZS4NCg0KLU1pa2UNCg==
^ permalink raw reply
* Re: [PATCH tty-next 14/22] tty: Remove tty_wait_until_sent_from_close()
From: One Thousand Gnomes @ 2014-06-17 11:54 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Karsten Keil, 'Peter Hurley', Greg Kroah-Hartman,
linux-kernel@vger.kernel.org, David Laight,
linux-serial@vger.kernel.org, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <8191805.dfI4LbYmWz@wuerfel>
> Before the patch, I believe tty_reopen() would return -EIO because
> the TTY_CLOSING flag is set. After the patch, tty_open() blocks
> on tty_lock() before calling tty_reopen(). AFAICT, this is independent
> of O_NONBLOCK.
That would be a bug then. Returning -EIO is fine (if unfriendly). The
O_NONBLOCK can't block in this case though because the port could take a
long time to give up trying to dribble its bits (up to 30 seconds or so)
Alan
^ permalink raw reply
* [PATCH 1/1] powerpc/traps/e500: fix misleading error output
From: Wladislav Wiebe @ 2014-06-17 13:30 UTC (permalink / raw)
To: linuxppc-dev, benh, paulus, scottwood, mikey, mahesh, michael,
anton, r65777, haokexin
Cc: wladislav.kw, linux-kernel
In machine_check_e500 exception handler is a wrong indication
in case of MCSR_BUS_WBERR - so print "Write" instead of "Read".
Signed-off-by: Wladislav Wiebe <wladislav.kw@gmail.com>
---
arch/powerpc/kernel/traps.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 239f1cd..cb9cfe4 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -609,7 +609,7 @@ int machine_check_e500(struct pt_regs *regs)
if (reason & MCSR_BUS_RBERR)
printk("Bus - Read Data Bus Error\n");
if (reason & MCSR_BUS_WBERR)
- printk("Bus - Read Data Bus Error\n");
+ printk("Bus - Write Data Bus Error\n");
if (reason & MCSR_BUS_IPERR)
printk("Bus - Instruction Parity Error\n");
if (reason & MCSR_BUS_RPERR)
--
1.7.1
^ permalink raw reply related
* [PATCH 04/24] powerpc: check/return actual error on sysfs functions
From: Jeff Liu @ 2014-06-17 14:31 UTC (permalink / raw)
To: benh, paulus; +Cc: linuxppc-dev, LKML
From: Jie Liu <jeff.liu@oracle.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Jie Liu <jeff.liu@oracle.com>
---
arch/powerpc/platforms/powernv/opal-dump.c | 2 +-
arch/powerpc/platforms/powernv/opal-elog.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c
index 788a197..e718baf 100644
--- a/arch/powerpc/platforms/powernv/opal-dump.c
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -424,7 +424,7 @@ void __init opal_platform_dump_init(void)
int rc;
dump_kset = kset_create_and_add("dump", NULL, opal_kobj);
- if (!dump_kset) {
+ if (IS_ERR(dump_kset)) {
pr_warn("%s: Failed to create dump kset\n", __func__);
return;
}
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c
index 10268c4..09c1f6f 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -296,9 +296,9 @@ int __init opal_elog_init(void)
int rc = 0;
elog_kset = kset_create_and_add("elog", NULL, opal_kobj);
- if (!elog_kset) {
+ if (IS_ERR(elog_kset)) {
pr_warn("%s: failed to create elog kset\n", __func__);
- return -1;
+ return PTR_ERR(elog_kset);
}
rc = opal_notifier_register(&elog_nb);
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH] powerpc/kvm: support to handle sw breakpoint
From: Alexander Graf @ 2014-06-17 14:42 UTC (permalink / raw)
To: Madhavan Srinivasan, benh, paulus; +Cc: linuxppc-dev, kvm-ppc, kvm
In-Reply-To: <53A022CE.3000704@linux.vnet.ibm.com>
On 17.06.14 13:13, Madhavan Srinivasan wrote:
> On Tuesday 17 June 2014 04:38 PM, Alexander Graf wrote:
>> On 17.06.14 13:07, Madhavan Srinivasan wrote:
>>> On Tuesday 17 June 2014 02:24 PM, Alexander Graf wrote:
>>>> On 14.06.14 23:08, Madhavan Srinivasan wrote:
>>>>> This patch adds kernel side support for software breakpoint.
>>>>> Design is that, by using an illegal instruction, we trap to hypervisor
>>>>> via Emulation Assistance interrupt, where we check for the illegal
>>>>> instruction
>>>>> and accordingly we return to Host or Guest. Patch mandates use of
>>>>> "abs" instruction
>>>>> (primary opcode 31 and extended opcode 360) as sw breakpoint
>>>>> instruction.
>>>>> Based on PowerISA v2.01, ABS instruction has been dropped from the
>>>>> architecture
>>>>> and treated an illegal instruction.
>>>>>
>>>>> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
>>>>> ---
>>>>> arch/powerpc/kvm/book3s.c | 3 ++-
>>>>> arch/powerpc/kvm/book3s_hv.c | 23 +++++++++++++++++++----
>>>>> 2 files changed, 21 insertions(+), 5 deletions(-)
>>>>>
>>>>> diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
>>>>> index c254c27..b40fe5d 100644
>>>>> --- a/arch/powerpc/kvm/book3s.c
>>>>> +++ b/arch/powerpc/kvm/book3s.c
>>>>> @@ -789,7 +789,8 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu
>>>>> *vcpu,
>>>>> int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
>>>>> struct kvm_guest_debug *dbg)
>>>>> {
>>>>> - return -EINVAL;
>>>>> + vcpu->guest_debug = dbg->control;
>>>>> + return 0;
>>>>> }
>>>>> void kvmppc_decrementer_func(unsigned long data)
>>>>> diff --git a/arch/powerpc/kvm/book3s_hv.c
>>>>> b/arch/powerpc/kvm/book3s_hv.c
>>>>> index 7a12edb..688421d 100644
>>>>> --- a/arch/powerpc/kvm/book3s_hv.c
>>>>> +++ b/arch/powerpc/kvm/book3s_hv.c
>>>>> @@ -67,6 +67,14 @@
>>>>> /* Used as a "null" value for timebase values */
>>>>> #define TB_NIL (~(u64)0)
>>>>> +/*
>>>>> + * SW_BRK_DBG_INT is debug Instruction for supporting Software
>>>>> Breakpoint.
>>>>> + * Instruction mnemonic is ABS, primary opcode is 31 and extended
>>>>> opcode is 360.
>>>>> + * Based on PowerISA v2.01, ABS instruction has been dropped from the
>>>>> architecture
>>>>> + * and treated an illegal instruction.
>>>>> + */
>>>>> +#define SW_BRK_DBG_INT 0x7c0002d0
>>>> The instruction we use to trap needs to get exposed to user space via a
>>>> ONE_REG property.
>>>>
>>> Yes. I got to know about that from Bharat (patchset "ppc debug: Add
>>> debug stub support"). I will change it.
Also please make sure to pick an instruction that preferably looks
identical regardless of guest endianness. Segher suggested 0x00dddd00.
Does that trap properly for you?
Alex
^ permalink raw reply
* Re: Build regressions/improvements in v3.16-rc1
From: Geert Uytterhoeven @ 2014-06-17 15:23 UTC (permalink / raw)
To: linux-kernel@vger.kernel.org
Cc: sparclinux, Linux MIPS Mailing List, Michal Simek,
linuxppc-dev@lists.ozlabs.org, Linux-sh list
In-Reply-To: <1403018163-25307-1-git-send-email-geert@linux-m68k.org>
On Tue, Jun 17, 2014 at 5:16 PM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
> 85 regressions:
> + /scratch/kisskb/src/arch/mips/net/bpf_jit.c: error: 'BPF_S_ALU_ADD_K' undeclared (first use in this function): => 930:8
[....]
> + /scratch/kisskb/src/arch/mips/net/bpf_jit.c: error: 'BPF_S_STX' undeclared (first use in this function): => 925:8
mips-allmodconfig (being fixed)
> + /scratch/kisskb/src/arch/powerpc/kernel/cacheinfo.c: error: 'size_kb' may be used uninitialized in this function [-Werror=uninitialized]: => 525:2
> + /scratch/kisskb/src/drivers/tty/serial/nwpserial.c: error: implicit declaration of function 'udelay' [-Werror=implicit-function-declaration]: => 53:3
> + error: No rule to make target drivers/scsi/aic7xxx/aicasm/*.[chyl]: => N/A
powerpc-randconfig
> + /scratch/kisskb/src/arch/sh/kernel/smp.c: error: implicit declaration of function 'cpu_context' [-Werror=implicit-function-declaration]: => 368:5
> + /scratch/kisskb/src/arch/sh/kernel/smp.c: error: lvalue required as left operand of assignment: => 405:24, 368:24, 448:32
> + /scratch/kisskb/src/arch/sh/mm/cache-sh4.c: error: 'cached_to_uncached' undeclared (first use in this function): => 99:17
> + /scratch/kisskb/src/arch/sh/mm/cache-sh4.c: error: implicit declaration of function 'cpu_context' [-Werror=implicit-function-declaration]: => 192:2
sh-randconfig
> + /scratch/kisskb/src/drivers/of/platform.c: error: 'struct pdev_archdata' has no member named 'dma_mask': => 170:16
microblaze/mmu_defconfig (being fixed)
> + /scratch/kisskb/src/include/asm-generic/atomic-long.h: error: implicit declaration of function 'atomic_add' [-Werror=implicit-function-declaration]: => 176:2
> + /scratch/kisskb/src/include/asm-generic/atomic-long.h: error: implicit declaration of function 'atomic_add_negative' [-Werror=implicit-function-declaration]: => 211:2
> + /scratch/kisskb/src/include/asm-generic/atomic-long.h: error: implicit declaration of function 'atomic_add_return' [-Werror=implicit-function-declaration]: => 218:2
> + /scratch/kisskb/src/include/asm-generic/atomic-long.h: error: implicit declaration of function 'atomic_dec' [-Werror=implicit-function-declaration]: => 169:2
> + /scratch/kisskb/src/include/asm-generic/atomic-long.h: error: implicit declaration of function 'atomic_dec_and_test' [-Werror=implicit-function-declaration]: => 197:2
> + /scratch/kisskb/src/include/asm-generic/atomic-long.h: error: implicit declaration of function 'atomic_dec_return' [-Werror=implicit-function-declaration]: => 239:2
> + /scratch/kisskb/src/include/asm-generic/atomic-long.h: error: implicit declaration of function 'atomic_inc' [-Werror=implicit-function-declaration]: => 162:2
> + /scratch/kisskb/src/include/asm-generic/atomic-long.h: error: implicit declaration of function 'atomic_inc_and_test' [-Werror=implicit-function-declaration]: => 204:2
> + /scratch/kisskb/src/include/asm-generic/atomic-long.h: error: implicit declaration of function 'atomic_inc_return' [-Werror=implicit-function-declaration]: => 232:2
> + /scratch/kisskb/src/include/asm-generic/atomic-long.h: error: implicit declaration of function 'atomic_set' [-Werror=implicit-function-declaration]: => 155:2
> + /scratch/kisskb/src/include/asm-generic/atomic-long.h: error: implicit declaration of function 'atomic_sub' [-Werror=implicit-function-declaration]: => 183:2
> + /scratch/kisskb/src/include/asm-generic/atomic-long.h: error: implicit declaration of function 'atomic_sub_and_test' [-Werror=implicit-function-declaration]: => 190:2
> + /scratch/kisskb/src/include/asm-generic/atomic-long.h: error: implicit declaration of function 'atomic_sub_return' [-Werror=implicit-function-declaration]: => 225:2
> + /scratch/kisskb/src/include/linux/atomic.h: error: implicit declaration of function '__atomic_add_unless' [-Werror=implicit-function-declaration]: => 53:2
> + /scratch/kisskb/src/include/linux/atomic.h: error: implicit declaration of function 'atomic_cmpxchg' [-Werror=implicit-function-declaration]: => 89:3
> + /scratch/kisskb/src/include/linux/atomic.h: error: implicit declaration of function 'atomic_read' [-Werror=implicit-function-declaration]: => 136:2
sparc-allmodconfig
> + /scratch/kisskb/src/sound/soc/fsl/fsl_dma.c: error: invalid use of undefined type 'struct ccsr_ssi': => 926:34, 927:34
powerpc/mpc85xx_defconfig
> + error: filter.c: undefined reference to `__fpscr_values': => .text+0x3166c), .text+0x32000), .text+0x31860), .text+0x31d8c), .text+0x324b0)
sh4/se7206_defconfig
sh4/rsk7203_defconfig (toolchain issue)
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH] KVM: PPC: e500mc: Relax tlb invalidation condition on vcpu schedule
From: Scott Wood @ 2014-06-17 15:33 UTC (permalink / raw)
To: Alexander Graf; +Cc: Mihai Caraman, linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <5399DDA8.5060404@suse.de>
On Thu, 2014-06-12 at 19:04 +0200, Alexander Graf wrote:
> On 06/12/2014 04:00 PM, Mihai Caraman wrote:
> > @@ -140,12 +142,24 @@ static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu)
> > mtspr(SPRN_GDEAR, vcpu->arch.shared->dar);
> > mtspr(SPRN_GESR, vcpu->arch.shared->esr);
> >
> > - if (vcpu->arch.oldpir != mfspr(SPRN_PIR) ||
> > - __get_cpu_var(last_vcpu_on_cpu) != vcpu) {
> > - kvmppc_e500_tlbil_all(vcpu_e500);
> > + if (vcpu->arch.oldpir != mfspr(SPRN_PIR)) {
> > + /* tlb entries deprecated */
> > + inval_tlb = update_last = true;
> > + } else if (__get_cpu_var(last_vcpu_on_cpu) != vcpu) {
> > + update_last = true;
> > + /* tlb entries polluted */
> > + inval_tlb = __get_cpu_var(last_lpid_on_cpu) ==
> > + vcpu->kvm->arch.lpid;
> > + }
What about the following sequence on one CPU:
LPID 1, vcpu A
LPID 2, vcpu C
LPID 1, vcpu B
LPID 2, vcpu C doesn't invalidate
LPID 1, vcpu A doesn't invalidate
In the last line, vcpu A last ran on this cpu (oldpir matches), but LPID
2 last ran on this cpu (last_lpid_on_cpu does not match) -- but an
invalidation has never happened since vcpu B from LPID 1 ran on this
cpu.
-Scott
^ permalink raw reply
* Re: [PATCH v2] KVM: PPC: e500mc: Enhance tlb invalidation condition on vcpu schedule
From: Scott Wood @ 2014-06-17 15:35 UTC (permalink / raw)
To: Mihai Caraman; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <1402995739-23756-1-git-send-email-mihai.caraman@freescale.com>
On Tue, 2014-06-17 at 12:02 +0300, Mihai Caraman wrote:
> On vcpu schedule, the condition checked for tlb pollution is too loose.
> The tlb entries of a vcpu become polluted (vs stale) only when a different
> vcpu within the same logical partition runs in-between. Optimize the tlb
> invalidation condition taking into account the logical partition id.
>
> With the new invalidation condition, a guest shows 4% performance improvement
> on P5020DS while running a memory stress application with the cpu oversubscribed,
> the other guest running a cpu intensive workload.
See
https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-June/118547.html
-Scott
^ permalink raw reply
* [RFC PATCH 0/4] Update hotplug for pseries systems
From: Nathan Fontenot @ 2014-06-17 15:42 UTC (permalink / raw)
To: linuxppc-dev@lists.ozlabs.org
In order to support device hotplug (cpu, memory, and pci) in both the
PowerVM and the PowerKVM environments the handling of hotplug events
will need to be updated. This patch set adresses this by creating a
common entry point for handling hotplug events in the kernel that
can be used in both PowerVM and PowerKVM environments. To accomplish
this several changes need to be made.
For PowerVM systems hotplug (DLPAR) events are requested by users from the
HMC which then communicates the request to the partitions via the RSCT
framework. The RSCT framework then invokes the drmgr command to handle
the hotplug event. The drmgr command performs some of the work in user
space and makes calls into the kernel to handle the remaining work.
For PowerKVM systems hotplug events are communicated to the guest via
the ras epow interrupt by qemu. We could have the rtas event sent up
to user space through rtas_errd that would then invoke drmgr. This is
not the most ideal solution and it would be nicer to have hotplug
handled completely in the kernel.
To do this, hotplug events will now be communicated to the kernel in
the form of rtas hotplug events. For PowerKVM systems this is done
by qemu using the ras epow interrupt. For PowerVM systems the drmgr
command will be updated to create a rtas hotplug event and send it to
the kernel via a new /proc/powerpc/dlpar interface. Both of these
entry points for hotplug rtas events then call a common routine
for handling rtas hotplug events.
Additionally we will need to be able to handle all of the work to
do resource hotplug in the kernel. This patch set addresses this for
cpu and memory hotplug, pci hotplug will be done later.
Once all of the work is done to move hotplug handling into the kernel
we should also be able to get rid of the /proc/powerpc/ofdt interface.
Of course these updates do depend on updating the drmgr command. If
you care to look the updates for this is here;
https://github.com/nfont/powerpc-utils/tree/mem_rtas_hp
Patch 1/4:
o Create a common rtas hotplug event handling routine
o Create the /proc/powerpc/dlpar interface for PowerVM systems
o Implement memory hotplug handling in the kernel.
Patch 2/4:
o Move the cpu hotplug code from pseries/dlpar.c to pseries/hotplug-cpu.c
Patch 3/4:
o Update cpu hotplug handling to allow for invocation from rtas event
notifications.
Patch 4/4:
o Update the ras epow interrupt handler to recognize hotplug rtas events
This code (except for patch 4/4 which I cannot test right now) has been tested
on PowerVM systems. There are some error paths that still need to be tested
and of course testing on PowerKVM when cpu and memory hotplug is enabled
for Power.
Thoughts?
-Nathan
---
include/asm/rtas.h | 27 ++
kernel/rtas.c | 7
platforms/pseries/dlpar.c | 253 ++++++--------------------
platforms/pseries/hotplug-cpu.c | 358 +++++++++++++++++++++++++++++++++++++
platforms/pseries/hotplug-memory.c | 351 ++++++++++++++++++++++++++++++------
platforms/pseries/pseries.h | 6
platforms/pseries/ras.c | 12 +
platforms/pseries/reconfig.c | 6
8 files changed, 780 insertions(+), 240 deletions(-)
^ permalink raw reply
* [RFC PATCH 1/4] Create interface for rtas hotplug events and move mem hotplug to the kernel
From: Nathan Fontenot @ 2014-06-17 15:45 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <53A061EC.10403@linux.vnet.ibm.com>
In order to support hotplug of memory, cpu and pci devices in the PowerVM
and the PowerKVM environments we will need to provide a single entry
point. To do this requires updating the way in which we handle hotplug
requests in the PowerVM environment. The idea is to have all of the hotplug
in the kernel so that a hotplug rtas event can used to initiate the hotplug
add/remove of a device.
The current method for handling a hotplug request in a PowerVM partition
is to have the HMC notify the partition of the request through the RSCT
framework which then invokes the drmgr command to hotplug add/remove the
requested devices. The drmgr command does part of this in user-space
and part in the kernel via sysfs and /proc interfaces.
This patch creates the entry point for initiating a hotplug request for
pseries with a rtas hotplug event. For PowerVM systems the drmgr command
will now create and write a hotplug rtas event to /proc/powerpc/dlpar which
will then pass the hotplug rtas event to the entry point. For PowerKVM
systems QEMU will generate an epow interrupt to the guest, which then
calls rtas-check-execption to get the hotplug rtas event and pass it to the
entry point. NOTE that the updates to handle hotplug events from epow
interrupts is not in this intial patch.
This patch also adds funtionality so that we can do memory hotplug in the
kernel. Using the updates to drmgr found below you can initiate memory
hotplug events using the new interface.
https://github.com/nfont/powerpc-utils/tree/mem_rtas_hp
---
arch/powerpc/include/asm/rtas.h | 26 ++
arch/powerpc/kernel/rtas.c | 7 +
arch/powerpc/platforms/pseries/dlpar.c | 65 ++++-
arch/powerpc/platforms/pseries/hotplug-memory.c | 351 ++++++++++++++++++++----
arch/powerpc/platforms/pseries/pseries.h | 4 +
arch/powerpc/platforms/pseries/reconfig.c | 6 +
6 files changed, 403 insertions(+), 56 deletions(-)
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index b390f55..26491ae 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -254,6 +254,31 @@ inline uint32_t rtas_ext_event_company_id(struct rtas_ext_event_log_v6 *ext_log)
return be32_to_cpu(ext_log->company_id);
}
+/* RTAS pseries hotplug elog section */
+struct pseries_hp_elog {
+ uint8_t resource;
+ uint8_t action:8;
+ uint8_t id_type:8;
+ uint8_t reserved;
+ union {
+ __be32 drc_index;
+ __be32 drc_count;
+ char drc_name[1];
+ }_drc_u;
+};
+
+#define HP_ELOG_RESOURCE_CPU 1
+#define HP_ELOG_RESOURCE_MEM 2
+#define HP_ELOG_RESOURCE_SLOT 3
+#define HP_ELOG_RESOURCE_PHB 4
+
+#define HP_ELOG_ACTION_ADD 1
+#define HP_ELOG_ACTION_REMOVE 2
+
+#define HP_ELOG_ID_DRC_NAME 1
+#define HP_ELOG_ID_DRC_INDEX 2
+#define HP_ELOG_ID_DRC_COUNT 3
+
/* pSeries event log format */
/* Two bytes ASCII section IDs */
@@ -273,6 +298,7 @@ inline uint32_t rtas_ext_event_company_id(struct rtas_ext_event_log_v6 *ext_log)
#define PSERIES_ELOG_SECT_ID_MANUFACT_INFO (('M' << 8) | 'I')
#define PSERIES_ELOG_SECT_ID_CALL_HOME (('C' << 8) | 'H')
#define PSERIES_ELOG_SECT_ID_USER_DEF (('U' << 8) | 'D')
+#define PSERIES_ELOG_SECT_ID_HP (('H' << 8) | 'P')
/* Vendor specific Platform Event Log Format, Version 6, section header */
struct pseries_errorlog {
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 8cd5ed0..b738b1b 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -997,6 +997,13 @@ struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log,
uint8_t log_format = rtas_ext_event_log_format(ext_log);
uint32_t company_id = rtas_ext_event_company_id(ext_log);
+ printk(KERN_EMERG "Validation: %x : %lx\n%x : %x\n%x : %x\n",
+ log->extended_log_length, sizeof(struct rtas_ext_event_log_v6),
+ rtas_ext_event_log_format(ext_log),
+ RTAS_V6EXT_LOG_FORMAT_EVENT_LOG,
+ rtas_ext_event_company_id(ext_log),
+ RTAS_V6EXT_COMPANY_ID_IBM);
+
/* Check that we understand the format */
if (ext_log_length < sizeof(struct rtas_ext_event_log_v6) ||
log_format != RTAS_V6EXT_LOG_FORMAT_EVENT_LOG ||
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index 022b38e..dfca23b 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -16,9 +16,13 @@
#include <linux/cpu.h>
#include <linux/slab.h>
#include <linux/of.h>
+#include <linux/proc_fs.h>
+#include <linux/memory.h>
+#include <linux/memblock.h>
+#include <linux/mutex.h>
#include "offline_states.h"
+#include "pseries.h"
-#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/uaccess.h>
#include <asm/rtas.h>
@@ -529,13 +533,68 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count)
return count;
}
+#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
+
+static int handle_dlpar_errorlog(struct rtas_error_log *error_log)
+{
+ struct pseries_errorlog *pseries_log;
+ struct pseries_hp_elog *hp_elog;
+ int rc = -EINVAL;
+
+ pseries_log = get_pseries_errorlog(error_log, PSERIES_ELOG_SECT_ID_HP);
+ if (!pseries_log)
+ return rc;
+
+ hp_elog = (struct pseries_hp_elog *)pseries_log->data;
+ switch (hp_elog->resource) {
+ case HP_ELOG_RESOURCE_MEM:
+ rc = dlpar_memory(hp_elog);
+ break;
+ }
+
+ return rc;
+}
+
+static ssize_t dlpar_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *offset)
+{
+ char *event_buf;
+ int rc;
+
+ event_buf = kmalloc(count + 1, GFP_KERNEL);
+ if (!event_buf)
+ return -ENOMEM;
+
+ rc = copy_from_user(event_buf, buf, count);
+ if (rc) {
+ kfree(event_buf);
+ return rc;
+ }
+
+ rc = handle_dlpar_errorlog((struct rtas_error_log *)event_buf);
+ kfree(event_buf);
+ return rc;
+}
+
+static const struct file_operations dlpar_fops = {
+ .write = dlpar_write,
+ .llseek = noop_llseek,
+};
+
static int __init pseries_dlpar_init(void)
{
+ struct proc_dir_entry *proc_ent;
+
+ proc_ent = proc_create("powerpc/dlpar", S_IWUSR, NULL, &dlpar_fops);
+ if (proc_ent)
+ proc_set_size(proc_ent, 0);
+
+#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
ppc_md.cpu_probe = dlpar_cpu_probe;
ppc_md.cpu_release = dlpar_cpu_release;
+#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
+
return 0;
}
machine_device_initcall(pseries, pseries_dlpar_init);
-
-#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 7f75c94..af479eb 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -15,11 +15,17 @@
#include <linux/vmalloc.h>
#include <linux/memory.h>
#include <linux/memory_hotplug.h>
+#include <linux/slab.h>
#include <asm/firmware.h>
#include <asm/machdep.h>
-#include <asm/prom.h>
#include <asm/sparsemem.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+
+#include "pseries.h"
+
+DEFINE_MUTEX(dlpar_mem_mutex);
static unsigned long get_memblock_size(void)
{
@@ -75,6 +81,186 @@ unsigned long memory_block_size_bytes(void)
return get_memblock_size();
}
+static struct property *dlpar_clone_drconf_property(struct device_node *dn)
+{
+ struct property *prop, *new_prop;
+
+ prop = of_find_property(dn, "ibm,dynamic-memory", NULL);
+ if (!prop)
+ return NULL;
+
+ new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
+ if (!new_prop)
+ return NULL;
+
+ new_prop->name = kstrdup(prop->name, GFP_KERNEL);
+ new_prop->value = kmalloc(prop->length + 1, GFP_KERNEL);
+ if (!new_prop->name || !new_prop->value) {
+ kfree(new_prop->name);
+ kfree(new_prop->value);
+ kfree(new_prop);
+ return NULL;
+ }
+
+ memcpy(new_prop->value, prop->value, prop->length);
+ new_prop->length = prop->length;
+ *(((char *)new_prop->value) + new_prop->length) = 0;
+
+ return new_prop;
+}
+
+static int lmb_is_removable(struct of_drconf_cell *lmb)
+{
+ int i, scns_per_block;
+ int rc = 1;
+ unsigned long pfn, block_sz;
+ uint64_t base_addr;
+
+ base_addr = lmb->base_addr;
+ block_sz = memory_block_size_bytes();
+ scns_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
+
+ for (i = 0; i < scns_per_block; i++) {
+ pfn = PFN_DOWN(base_addr);
+ if (!pfn_present(pfn))
+ continue;
+
+ rc &= is_mem_section_removable(pfn, PAGES_PER_SECTION);
+ base_addr += MIN_MEMORY_BLOCK_SIZE;
+ }
+
+ return rc;
+}
+
+static int lmb_is_usable(struct pseries_hp_elog *hp_elog,
+ struct of_drconf_cell *lmb)
+{
+ if (hp_elog->id_type == HP_ELOG_ID_DRC_INDEX
+ && hp_elog->_drc_u.drc_index == lmb->drc_index) {
+ return 1;
+ } else {
+ if (hp_elog->action == HP_ELOG_ACTION_ADD
+ && !(lmb->flags & DRCONF_MEM_ASSIGNED))
+ return 1;
+
+ if (hp_elog->action == HP_ELOG_ACTION_REMOVE
+ && lmb->flags & DRCONF_MEM_ASSIGNED)
+ return lmb_is_removable(lmb);
+ }
+
+ return 0;
+}
+
+static struct memory_block *lmb_to_memblock(struct of_drconf_cell *lmb)
+{
+ unsigned long section_nr;
+ struct mem_section *mem_sect;
+ struct memory_block *mem_block;
+
+ section_nr = pfn_to_section_nr(PFN_DOWN(lmb->base_addr));
+ mem_sect = __nr_to_section(section_nr);
+
+ mem_block = find_memory_block(mem_sect);
+ return mem_block;
+}
+
+static int dlpar_add_one_lmb(struct of_drconf_cell *lmb)
+{
+ struct memory_block *mem_block;
+ u64 phys_addr;
+ unsigned long pages_per_block;
+ unsigned long block_sz;
+ int nid, sections_per_block;
+ int rc;
+
+ phys_addr = lmb->base_addr;
+ block_sz = memory_block_size_bytes();
+ sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
+ pages_per_block = PAGES_PER_SECTION * sections_per_block;
+
+ if (phys_addr & ((pages_per_block << PAGE_SHIFT) - 1))
+ return -EINVAL;
+
+ nid = memory_add_physaddr_to_nid(phys_addr);
+ rc = add_memory(nid, phys_addr, block_sz);
+ if (rc)
+ return rc;
+
+ rc = memblock_add(lmb->base_addr, block_sz);
+ if (rc) {
+ remove_memory(nid, phys_addr, block_sz);
+ return rc;
+ }
+
+ mem_block = lmb_to_memblock(lmb);
+ if (!mem_block) {
+ remove_memory(nid, phys_addr, block_sz);
+ return -EINVAL;
+ }
+
+ rc = device_online(&mem_block->dev);
+ put_device(&mem_block->dev);
+ if (rc)
+ remove_memory(nid, phys_addr, block_sz);
+
+ return rc;
+}
+
+static int dlpar_memory_add(struct pseries_hp_elog *hp_elog)
+{
+ struct of_drconf_cell *lmb;
+ struct device_node *dn;
+ struct property *prop;
+ uint32_t *p, entries;
+ int i, lmbs_to_add;
+ int lmbs_added = 0;
+ int rc = -EINVAL;
+
+ if (hp_elog->id_type == HP_ELOG_ID_DRC_COUNT)
+ lmbs_to_add = hp_elog->_drc_u.drc_count;
+ else
+ lmbs_to_add = 1;
+
+ dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
+ if (!dn)
+ return -EINVAL;
+
+ prop = dlpar_clone_drconf_property(dn);
+ if (!prop) {
+ of_node_put(dn);
+ return -EINVAL;
+ }
+
+ p = prop->value;
+ entries = *p++;
+ lmb = (struct of_drconf_cell *)p;
+
+ for (i = 0; i < entries; i++, lmb++) {
+ if (lmbs_to_add == lmbs_added)
+ break;
+
+ if (!lmb_is_usable(hp_elog, lmb))
+ continue;
+
+ rc = dlpar_acquire_drc(lmb->drc_index);
+ if (rc)
+ continue;
+
+ rc = dlpar_add_one_lmb(lmb);
+
+ lmb->flags |= DRCONF_MEM_ASSIGNED;
+ lmbs_added++;
+ }
+
+ if (lmbs_added)
+ rc = of_update_property(dn, prop);
+ else
+ kfree(prop);
+
+ of_node_put(dn);
+ return rc ? rc : lmbs_added;
+}
+
#ifdef CONFIG_MEMORY_HOTREMOVE
static int pseries_remove_memory(u64 start, u64 size)
{
@@ -92,6 +278,93 @@ static int pseries_remove_memory(u64 start, u64 size)
return ret;
}
+static int dlpar_remove_one_lmb(struct of_drconf_cell *lmb)
+{
+ struct memory_block *mem_block;
+ unsigned long block_sz;
+ int nid, rc;
+
+ block_sz = memory_block_size_bytes();
+ nid = memory_add_physaddr_to_nid(lmb->base_addr);
+
+ if (!pfn_valid(lmb->base_addr >> PAGE_SHIFT)) {
+ memblock_remove(lmb->base_addr, block_sz);
+ return 0;
+ }
+
+ mem_block = lmb_to_memblock(lmb);
+ if (!mem_block)
+ return -EINVAL;
+
+ rc = device_offline(&mem_block->dev);
+ put_device(&mem_block->dev);
+ if (rc)
+ return rc;
+
+ remove_memory(nid, lmb->base_addr, block_sz);
+ memblock_remove(lmb->base_addr, block_sz);
+
+ return 0;
+}
+
+static int dlpar_memory_remove(struct pseries_hp_elog *hp_elog)
+{
+ struct of_drconf_cell *lmb;
+ struct device_node *dn;
+ struct property *prop;
+ int lmbs_to_remove, lmbs_removed = 0;
+ int i, rc, entries;
+ uint32_t *p;
+
+ if (hp_elog->id_type == HP_ELOG_ID_DRC_COUNT)
+ lmbs_to_remove = hp_elog->_drc_u.drc_count;
+ else
+ lmbs_to_remove = 1;
+
+ dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
+ if (!dn)
+ return -EINVAL;
+
+ prop = dlpar_clone_drconf_property(dn);
+ if (!prop) {
+ of_node_put(dn);
+ return -EINVAL;
+ }
+
+ p = prop->value;
+ entries = *p++;
+ lmb = (struct of_drconf_cell *)p;
+
+ for (i = 0; i < entries; i++, lmb++) {
+ if (lmbs_to_remove == lmbs_removed)
+ break;
+
+ if (!lmb_is_usable(hp_elog, lmb))
+ continue;
+
+ rc = dlpar_remove_one_lmb(lmb);
+ if (rc)
+ continue;
+
+ rc = dlpar_release_drc(lmb->drc_index);
+ if (rc) {
+ dlpar_add_one_lmb(lmb);
+ continue;
+ }
+
+ lmb->flags &= ~DRCONF_MEM_ASSIGNED;
+ lmbs_removed++;
+ }
+
+ if (lmbs_removed)
+ rc = of_update_property(dn, prop);
+ else
+ kfree(prop);
+
+ of_node_put(dn);
+ return rc;
+}
+
static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size)
{
unsigned long block_sz, start_pfn;
@@ -150,6 +423,10 @@ static int pseries_remove_mem_node(struct device_node *np)
return 0;
}
#else
+static inline int dlpar_memory_remove(struct pseries_hp_elog *hp_elog)
+{
+ return -EOPNOTSUPP;
+}
static inline int pseries_remove_memblock(unsigned long base,
unsigned int memblock_size)
{
@@ -161,6 +438,25 @@ static inline int pseries_remove_mem_node(struct device_node *np)
}
#endif /* CONFIG_MEMORY_HOTREMOVE */
+int dlpar_memory(struct pseries_hp_elog *hp_elog)
+{
+ int rc = 0;
+
+ mutex_lock(&dlpar_mem_mutex);
+
+ switch (hp_elog->action) {
+ case HP_ELOG_ACTION_ADD:
+ rc = dlpar_memory_add(hp_elog);
+ break;
+ case HP_ELOG_ACTION_REMOVE:
+ rc = dlpar_memory_remove(hp_elog);
+ break;
+ }
+
+ mutex_unlock(&dlpar_mem_mutex);
+ return rc;
+}
+
static int pseries_add_mem_node(struct device_node *np)
{
const char *type;
@@ -193,56 +489,9 @@ static int pseries_add_mem_node(struct device_node *np)
return (ret < 0) ? -EINVAL : 0;
}
-static int pseries_update_drconf_memory(struct of_prop_reconfig *pr)
-{
- struct of_drconf_cell *new_drmem, *old_drmem;
- unsigned long memblock_size;
- u32 entries;
- u32 *p;
- int i, rc = -EINVAL;
-
- memblock_size = get_memblock_size();
- if (!memblock_size)
- return -EINVAL;
-
- p = (u32 *)of_get_property(pr->dn, "ibm,dynamic-memory", NULL);
- if (!p)
- return -EINVAL;
-
- /* The first int of the property is the number of lmb's described
- * by the property. This is followed by an array of of_drconf_cell
- * entries. Get the niumber of entries and skip to the array of
- * of_drconf_cell's.
- */
- entries = *p++;
- old_drmem = (struct of_drconf_cell *)p;
-
- p = (u32 *)pr->prop->value;
- p++;
- new_drmem = (struct of_drconf_cell *)p;
-
- for (i = 0; i < entries; i++) {
- if ((old_drmem[i].flags & DRCONF_MEM_ASSIGNED) &&
- (!(new_drmem[i].flags & DRCONF_MEM_ASSIGNED))) {
- rc = pseries_remove_memblock(old_drmem[i].base_addr,
- memblock_size);
- break;
- } else if ((!(old_drmem[i].flags & DRCONF_MEM_ASSIGNED)) &&
- (new_drmem[i].flags & DRCONF_MEM_ASSIGNED)) {
- rc = memblock_add(old_drmem[i].base_addr,
- memblock_size);
- rc = (rc < 0) ? -EINVAL : 0;
- break;
- }
- }
-
- return rc;
-}
-
static int pseries_memory_notifier(struct notifier_block *nb,
unsigned long action, void *node)
{
- struct of_prop_reconfig *pr;
int err = 0;
switch (action) {
@@ -252,12 +501,8 @@ static int pseries_memory_notifier(struct notifier_block *nb,
case OF_RECONFIG_DETACH_NODE:
err = pseries_remove_mem_node(node);
break;
- case OF_RECONFIG_UPDATE_PROPERTY:
- pr = (struct of_prop_reconfig *)node;
- if (!strcmp(pr->prop->name, "ibm,dynamic-memory"))
- err = pseries_update_drconf_memory(pr);
- break;
}
+
return notifier_from_errno(err);
}
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 9921953..89c25769 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -11,6 +11,7 @@
#define _PSERIES_PSERIES_H
#include <linux/interrupt.h>
+#include <asm/rtas.h>
struct device_node;
@@ -59,6 +60,9 @@ extern void dlpar_free_cc_property(struct property *);
extern struct device_node *dlpar_configure_connector(u32, struct device_node *);
extern int dlpar_attach_node(struct device_node *);
extern int dlpar_detach_node(struct device_node *);
+extern int dlpar_acquire_drc(u32);
+extern int dlpar_release_drc(u32);
+extern int dlpar_memory(struct pseries_hp_elog *);
/* PCI root bridge prepare function override for pseries */
struct pci_host_bridge;
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 0435bb6..8a1f3cf4 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -370,6 +370,12 @@ static int do_update_property(char *buf, size_t bufsize)
if (!strlen(name))
return -ENODEV;
+ /* updating the ibm,dynamic-memory property is no longer
+ * supported through this interface.
+ */
+ if (!strcmp(name, "ibm,dynamic-memory"))
+ return -EINVAL;
+
newprop = new_property(name, length, value, NULL);
if (!newprop)
return -ENOMEM;
--
2.0.0.rc3.2.g998f840
^ permalink raw reply related
* [RFC PATCH 2/4] Migrate cpu hotplug code to pseries/hotplug-cpu.c
From: Nathan Fontenot @ 2014-06-17 15:46 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <53A061EC.10403@linux.vnet.ibm.com>
This patch moves the cpu hotplug handling code from pseries/dlpar.c
to pseries/hotplug-cpu.c. Additionally it factors out the work to
add/remove a single cpu into its own routine.
---
arch/powerpc/platforms/pseries/dlpar.c | 182 -------------------------
arch/powerpc/platforms/pseries/hotplug-cpu.c | 194 +++++++++++++++++++++++++++
2 files changed, 194 insertions(+), 182 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index dfca23b..16c85b9 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -359,182 +359,6 @@ int dlpar_release_drc(u32 drc_index)
return 0;
}
-#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
-
-static int dlpar_online_cpu(struct device_node *dn)
-{
- int rc = 0;
- unsigned int cpu;
- int len, nthreads, i;
- const u32 *intserv;
-
- intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
- if (!intserv)
- return -EINVAL;
-
- nthreads = len / sizeof(u32);
-
- cpu_maps_update_begin();
- for (i = 0; i < nthreads; i++) {
- for_each_present_cpu(cpu) {
- if (get_hard_smp_processor_id(cpu) != intserv[i])
- continue;
- BUG_ON(get_cpu_current_state(cpu)
- != CPU_STATE_OFFLINE);
- cpu_maps_update_done();
- rc = cpu_up(cpu);
- if (rc)
- goto out;
- cpu_maps_update_begin();
-
- break;
- }
- if (cpu == num_possible_cpus())
- printk(KERN_WARNING "Could not find cpu to online "
- "with physical id 0x%x\n", intserv[i]);
- }
- cpu_maps_update_done();
-
-out:
- return rc;
-
-}
-
-static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
-{
- struct device_node *dn, *parent;
- unsigned long drc_index;
- int rc;
-
- rc = strict_strtoul(buf, 0, &drc_index);
- if (rc)
- return -EINVAL;
-
- parent = of_find_node_by_path("/cpus");
- if (!parent)
- return -ENODEV;
-
- dn = dlpar_configure_connector(drc_index, parent);
- if (!dn)
- return -EINVAL;
-
- of_node_put(parent);
-
- rc = dlpar_acquire_drc(drc_index);
- if (rc) {
- dlpar_free_cc_nodes(dn);
- return -EINVAL;
- }
-
- rc = dlpar_attach_node(dn);
- if (rc) {
- dlpar_release_drc(drc_index);
- dlpar_free_cc_nodes(dn);
- return rc;
- }
-
- rc = dlpar_online_cpu(dn);
- if (rc)
- return rc;
-
- return count;
-}
-
-static int dlpar_offline_cpu(struct device_node *dn)
-{
- int rc = 0;
- unsigned int cpu;
- int len, nthreads, i;
- const u32 *intserv;
-
- intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
- if (!intserv)
- return -EINVAL;
-
- nthreads = len / sizeof(u32);
-
- cpu_maps_update_begin();
- for (i = 0; i < nthreads; i++) {
- for_each_present_cpu(cpu) {
- if (get_hard_smp_processor_id(cpu) != intserv[i])
- continue;
-
- if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE)
- break;
-
- if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) {
- set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
- cpu_maps_update_done();
- rc = cpu_down(cpu);
- if (rc)
- goto out;
- cpu_maps_update_begin();
- break;
-
- }
-
- /*
- * The cpu is in CPU_STATE_INACTIVE.
- * Upgrade it's state to CPU_STATE_OFFLINE.
- */
- set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
- BUG_ON(plpar_hcall_norets(H_PROD, intserv[i])
- != H_SUCCESS);
- __cpu_die(cpu);
- break;
- }
- if (cpu == num_possible_cpus())
- printk(KERN_WARNING "Could not find cpu to offline "
- "with physical id 0x%x\n", intserv[i]);
- }
- cpu_maps_update_done();
-
-out:
- return rc;
-
-}
-
-static ssize_t dlpar_cpu_release(const char *buf, size_t count)
-{
- struct device_node *dn;
- const u32 *drc_index;
- int rc;
-
- dn = of_find_node_by_path(buf);
- if (!dn)
- return -EINVAL;
-
- drc_index = of_get_property(dn, "ibm,my-drc-index", NULL);
- if (!drc_index) {
- of_node_put(dn);
- return -EINVAL;
- }
-
- rc = dlpar_offline_cpu(dn);
- if (rc) {
- of_node_put(dn);
- return -EINVAL;
- }
-
- rc = dlpar_release_drc(*drc_index);
- if (rc) {
- of_node_put(dn);
- return rc;
- }
-
- rc = dlpar_detach_node(dn);
- if (rc) {
- dlpar_acquire_drc(*drc_index);
- return rc;
- }
-
- of_node_put(dn);
-
- return count;
-}
-
-#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
-
static int handle_dlpar_errorlog(struct rtas_error_log *error_log)
{
struct pseries_errorlog *pseries_log;
@@ -589,12 +413,6 @@ static int __init pseries_dlpar_init(void)
if (proc_ent)
proc_set_size(proc_ent, 0);
-#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
- ppc_md.cpu_probe = dlpar_cpu_probe;
- ppc_md.cpu_release = dlpar_cpu_release;
-#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
-
-
return 0;
}
machine_device_initcall(pseries, pseries_dlpar_init);
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 20d6297..6b42fd5 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -33,6 +33,7 @@
#include <asm/plpar_wrappers.h>
#include "offline_states.h"
+#include "pseries.h"
/* This version can't take the spinlock, because it never returns */
static int rtas_stop_self_token = RTAS_UNKNOWN_SERVICE;
@@ -235,6 +236,194 @@ static void pseries_cpu_die(unsigned int cpu)
paca[cpu].cpu_start = 0;
}
+static int dlpar_online_cpu(struct device_node *dn)
+{
+ int rc = 0;
+ unsigned int cpu;
+ int len, nthreads, i;
+ const u32 *intserv;
+
+ intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
+ if (!intserv)
+ return -EINVAL;
+
+ nthreads = len / sizeof(u32);
+
+ cpu_maps_update_begin();
+ for (i = 0; i < nthreads; i++) {
+ for_each_present_cpu(cpu) {
+ if (get_hard_smp_processor_id(cpu) != intserv[i])
+ continue;
+ BUG_ON(get_cpu_current_state(cpu)
+ != CPU_STATE_OFFLINE);
+ cpu_maps_update_done();
+ rc = cpu_up(cpu);
+ if (rc)
+ goto out;
+ cpu_maps_update_begin();
+
+ break;
+ }
+ if (cpu == num_possible_cpus())
+ printk(KERN_WARNING "Could not find cpu to online "
+ "with physical id 0x%x\n", intserv[i]);
+ }
+ cpu_maps_update_done();
+
+out:
+ return rc;
+
+}
+
+static ssize_t dlpar_add_one_cpu(u32 drc_index)
+{
+ struct device_node *dn, *parent;
+ int rc;
+
+ parent = of_find_node_by_path("/cpus");
+ if (!parent)
+ return -ENODEV;
+
+ dn = dlpar_configure_connector(drc_index, parent);
+ if (!dn)
+ return -EINVAL;
+
+ of_node_put(parent);
+
+ rc = dlpar_acquire_drc(drc_index);
+ if (rc) {
+ dlpar_free_cc_nodes(dn);
+ return -EINVAL;
+ }
+
+ rc = dlpar_attach_node(dn);
+ if (rc) {
+ dlpar_release_drc(drc_index);
+ dlpar_free_cc_nodes(dn);
+ return rc;
+ }
+
+ rc = dlpar_online_cpu(dn);
+ return rc;
+}
+
+static int dlpar_offline_cpu(struct device_node *dn)
+{
+ int rc = 0;
+ unsigned int cpu;
+ int len, nthreads, i;
+ const u32 *intserv;
+
+ intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
+ if (!intserv)
+ return -EINVAL;
+
+ nthreads = len / sizeof(u32);
+
+ cpu_maps_update_begin();
+ for (i = 0; i < nthreads; i++) {
+ for_each_present_cpu(cpu) {
+ if (get_hard_smp_processor_id(cpu) != intserv[i])
+ continue;
+
+ if (get_cpu_current_state(cpu) == CPU_STATE_OFFLINE)
+ break;
+
+ if (get_cpu_current_state(cpu) == CPU_STATE_ONLINE) {
+ set_preferred_offline_state(cpu,
+ CPU_STATE_OFFLINE);
+ cpu_maps_update_done();
+ rc = cpu_down(cpu);
+ if (rc)
+ goto out;
+ cpu_maps_update_begin();
+ break;
+
+ }
+
+ /*
+ * The cpu is in CPU_STATE_INACTIVE.
+ * Upgrade it's state to CPU_STATE_OFFLINE.
+ */
+ set_preferred_offline_state(cpu, CPU_STATE_OFFLINE);
+ BUG_ON(plpar_hcall_norets(H_PROD, intserv[i])
+ != H_SUCCESS);
+ __cpu_die(cpu);
+ break;
+ }
+ if (cpu == num_possible_cpus())
+ printk(KERN_WARNING "Could not find cpu to offline "
+ "with physical id 0x%x\n", intserv[i]);
+ }
+ cpu_maps_update_done();
+
+out:
+ return rc;
+
+}
+
+static int dlpar_remove_one_cpu(struct device_node *dn, u32 drc_index)
+{
+ int rc;
+
+ rc = dlpar_offline_cpu(dn);
+ if (rc) {
+ of_node_put(dn);
+ return -EINVAL;
+ }
+
+ rc = dlpar_release_drc(drc_index);
+ if (rc) {
+ of_node_put(dn);
+ return rc;
+ }
+
+ rc = dlpar_detach_node(dn);
+ if (rc) {
+ dlpar_acquire_drc(drc_index);
+ return rc;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
+static ssize_t dlpar_cpu_release(const char *buf, size_t count)
+{
+ struct device_node *dn;
+ const u32 *drc_index;
+ int rc;
+
+ dn = of_find_node_by_path(buf);
+ if (!dn)
+ return -EINVAL;
+
+ drc_index = of_get_property(dn, "ibm,my-drc-index", NULL);
+ if (!drc_index) {
+ of_node_put(dn);
+ return -EINVAL;
+ }
+
+ rc = dlpar_remove_one_cpu(dn, *drc_index);
+ of_node_put(dn);
+
+ return rc ? rc : count;
+}
+
+static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
+{
+ unsigned long drc_index;
+ int rc;
+
+ rc = strict_strtoul(buf, 0, &drc_index);
+ if (rc)
+ return -EINVAL;
+
+ rc = dlpar_add_one_cpu(drc_index);
+ return rc ? rc : count;
+}
+#endif
+
/*
* Update cpu_present_mask and paca(s) for a new cpu node. The wrinkle
* here is that a cpu device node may represent up to two logical cpus
@@ -403,6 +592,11 @@ static int __init pseries_cpu_hotplug_init(void)
return 0;
}
+#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
+ ppc_md.cpu_probe = dlpar_cpu_probe;
+ ppc_md.cpu_release = dlpar_cpu_release;
+#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
+
ppc_md.cpu_die = pseries_mach_cpu_die;
smp_ops->cpu_disable = pseries_cpu_disable;
smp_ops->cpu_die = pseries_cpu_die;
--
2.0.0.rc3.2.g998f840
^ permalink raw reply related
* [RFC PATCH 3/4] Handle cpu hotplug from rtas hotplug events
From: Nathan Fontenot @ 2014-06-17 15:46 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <53A061EC.10403@linux.vnet.ibm.com>
This patch updates the cpu hotplug handling code so that we can perform
cpu hotplug using the new rtas hotplug event interface while still
maintaining the ability to use the probe/release sysfs interface
for adding and removing cpus.
At a later point we could deprecate the use of the probe/release sysfs
files and remove those code bits.
---
arch/powerpc/platforms/pseries/dlpar.c | 4 +
arch/powerpc/platforms/pseries/hotplug-cpu.c | 164 +++++++++++++++++++++++++++
arch/powerpc/platforms/pseries/pseries.h | 1 +
3 files changed, 169 insertions(+)
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index 16c85b9..53f4fe6 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -275,6 +275,7 @@ int dlpar_attach_node(struct device_node *dn)
if (!dn->parent)
return -ENOMEM;
+ of_node_init(dn);
rc = of_attach_node(dn);
if (rc) {
printk(KERN_ERR "Failed to add device node %s\n",
@@ -374,6 +375,9 @@ static int handle_dlpar_errorlog(struct rtas_error_log *error_log)
case HP_ELOG_RESOURCE_MEM:
rc = dlpar_memory(hp_elog);
break;
+ case HP_ELOG_RESOURCE_CPU:
+ rc = dlpar_cpus(hp_elog);
+ break;
}
return rc;
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 6b42fd5..8be88d6 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -24,6 +24,7 @@
#include <linux/sched.h> /* for idle_task_exit */
#include <linux/cpu.h>
#include <linux/of.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include <asm/rtas.h>
#include <asm/firmware.h>
@@ -387,6 +388,169 @@ static int dlpar_remove_one_cpu(struct device_node *dn, u32 drc_index)
return 0;
}
+struct cpu_drc_info {
+ u32 drc_index;
+ int present;
+};
+
+static struct cpu_drc_info *get_cpu_drc_info(int *drc_count)
+{
+ struct device_node *dn, *child = NULL;
+ struct cpu_drc_info *drcs;
+ const u32 *indexes;
+ int i, count;
+
+ dn = of_find_node_by_path("/cpus");
+ if (!dn)
+ return NULL;
+
+ indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
+ if (!indexes) {
+ of_node_put(dn);
+ return NULL;
+ }
+
+ count = *indexes++;
+ drcs = kzalloc(count * sizeof(*drcs), GFP_KERNEL);
+ if (!drcs) {
+ of_node_put(dn);
+ return NULL;
+ }
+
+ for (i = 0; i < count; i++)
+ drcs[i].drc_index = indexes[i];
+
+ for_each_child_of_node(dn, child) {
+ const u32 *drc_index;
+
+ drc_index = of_get_property(child, "ibm,my-drc-index", NULL);
+ if (!drc_index)
+ continue;
+
+ for (i = 0; i < count; i++) {
+ if (drcs[i].drc_index == *drc_index)
+ drcs[i].present = 1;
+ break;
+ }
+ }
+
+ of_node_put(dn);
+ *drc_count = count;
+ return drcs;
+}
+
+static struct device_node *cpu_drc_index_to_device(u32 drc_index)
+{
+ struct device_node *parent, *child;
+ const u32 *my_drc_index;
+
+ parent = of_find_node_by_path("/cpus");
+ if (!parent)
+ return NULL;
+
+ for_each_child_of_node(parent, child) {
+ my_drc_index = of_get_property(child, "ibm,my-drc-index", NULL);
+ if (!my_drc_index)
+ continue;
+
+ if (*my_drc_index == drc_index)
+ break;
+ }
+
+ of_node_put(parent);
+ return child;
+}
+
+static int dlpar_remove_cpus(struct pseries_hp_elog *hp_elog,
+ struct cpu_drc_info *cpu_drcs, int num_drcs)
+{
+ struct device_node *dn;
+ int cpus_to_remove, cpus_removed = 0;
+ int rc, i;
+
+ if (hp_elog->id_type == HP_ELOG_ID_DRC_COUNT)
+ cpus_to_remove = hp_elog->_drc_u.drc_count;
+ else
+ cpus_to_remove = 1;
+
+ for (i = 0; i < num_drcs; i++) {
+ if (cpus_to_remove == cpus_removed)
+ break;
+
+ if (!cpu_drcs[i].present)
+ continue;
+
+ if (hp_elog->id_type == HP_ELOG_ID_DRC_INDEX
+ && hp_elog->_drc_u.drc_index != cpu_drcs[i].drc_index)
+ continue;
+
+ dn = cpu_drc_index_to_device(cpu_drcs[i].drc_index);
+ if (!dn)
+ continue;
+
+ rc = dlpar_remove_one_cpu(dn, cpu_drcs[i].drc_index);
+ of_node_put(dn);
+
+ if (!rc)
+ cpus_removed++;
+ }
+
+ return (cpus_to_remove == cpus_removed) ? 0: -1;
+}
+
+static int dlpar_add_cpus(struct pseries_hp_elog *hp_elog,
+ struct cpu_drc_info *cpu_drcs, int num_drcs)
+{
+ int cpus_to_add, cpus_added = 0;
+ int rc, i;
+
+ if (hp_elog->id_type == HP_ELOG_ID_DRC_COUNT)
+ cpus_to_add = hp_elog->_drc_u.drc_count;
+ else
+ cpus_to_add = 1;
+
+ for (i = 0; i < num_drcs; i++) {
+ if (cpus_to_add == cpus_added)
+ break;
+
+ if (cpu_drcs[i].present)
+ continue;
+
+ if (hp_elog->id_type == HP_ELOG_ID_DRC_INDEX
+ && hp_elog->_drc_u.drc_index != cpu_drcs[i].drc_index)
+ continue;
+
+ rc = dlpar_add_one_cpu(cpu_drcs[i].drc_index);
+ if (!rc)
+ cpus_added++;
+ }
+
+ return (cpus_to_add == cpus_added) ? 0: -1;
+}
+
+int dlpar_cpus(struct pseries_hp_elog *hp_elog)
+{
+ struct cpu_drc_info *cpu_drcs;
+ int num_drcs;
+ int rc = 0;
+
+ cpu_drcs = get_cpu_drc_info(&num_drcs);
+ if (!cpu_drcs)
+ return -1;
+
+ switch (hp_elog->action) {
+ case HP_ELOG_ACTION_ADD:
+ rc = dlpar_add_cpus(hp_elog, cpu_drcs, num_drcs);
+ break;
+ case HP_ELOG_ACTION_REMOVE:
+ rc = dlpar_remove_cpus(hp_elog, cpu_drcs, num_drcs);
+ break;
+ }
+
+ kfree(cpu_drcs);
+ return rc;
+}
+
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
static ssize_t dlpar_cpu_release(const char *buf, size_t count)
{
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 89c25769..1706215 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -63,6 +63,7 @@ extern int dlpar_detach_node(struct device_node *);
extern int dlpar_acquire_drc(u32);
extern int dlpar_release_drc(u32);
extern int dlpar_memory(struct pseries_hp_elog *);
+extern int dlpar_cpus(struct pseries_hp_elog *);
/* PCI root bridge prepare function override for pseries */
struct pci_host_bridge;
--
2.0.0.rc3.2.g998f840
^ permalink raw reply related
* [RFC PATCH 4/4] Hook into ras epow interrupt handler for hotplug
From: Nathan Fontenot @ 2014-06-17 15:47 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <53A061EC.10403@linux.vnet.ibm.com>
This patch hooks into the ras EPOW interrupt handler so that we can
communicate hotplug rtas events to a PowerKVM guest from qemu.
The ras epow interrupt wil lnow check for hotplgu rtas events and
invoke the common handling routine accordingly.
---
arch/powerpc/include/asm/rtas.h | 1 +
arch/powerpc/platforms/pseries/dlpar.c | 2 +-
arch/powerpc/platforms/pseries/pseries.h | 1 +
arch/powerpc/platforms/pseries/ras.c | 12 +++++++++++-
4 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 26491ae..7313e6f 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -124,6 +124,7 @@ struct rtas_suspend_me_data {
#define RTAS_TYPE_INFO 0xE2
#define RTAS_TYPE_DEALLOC 0xE3
#define RTAS_TYPE_DUMP 0xE4
+#define RTAS_TYPE_HOTPLUG 0xE5
/* I don't add PowerMGM events right now, this is a different topic */
#define RTAS_TYPE_PMGM_POWER_SW_ON 0x60
#define RTAS_TYPE_PMGM_POWER_SW_OFF 0x61
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index 53f4fe6..6d3de6e 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -360,7 +360,7 @@ int dlpar_release_drc(u32 drc_index)
return 0;
}
-static int handle_dlpar_errorlog(struct rtas_error_log *error_log)
+int handle_dlpar_errorlog(struct rtas_error_log *error_log)
{
struct pseries_errorlog *pseries_log;
struct pseries_hp_elog *hp_elog;
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 1706215..9b9bd82 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -64,6 +64,7 @@ extern int dlpar_acquire_drc(u32);
extern int dlpar_release_drc(u32);
extern int dlpar_memory(struct pseries_hp_elog *);
extern int dlpar_cpus(struct pseries_hp_elog *);
+extern int handle_dlpar_errorlog(struct rtas_error_log *);
/* PCI root bridge prepare function override for pseries */
struct pci_host_bridge;
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 9c5778e..3cc6a49 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -183,6 +183,7 @@ void rtas_parse_epow_errlog(struct rtas_error_log *log)
/* Handle environmental and power warning (EPOW) interrupts. */
static irqreturn_t ras_epow_interrupt(int irq, void *dev_id)
{
+ struct rtas_error_log *elog;
int status;
int state;
int critical;
@@ -205,7 +206,16 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id)
log_error(ras_log_buf, ERR_TYPE_RTAS_LOG, 0);
- rtas_parse_epow_errlog((struct rtas_error_log *)ras_log_buf);
+ elog = (struct rtas_error_log *)ras_log_buf;
+
+ switch(rtas_error_type(elog)) {
+ case RTAS_TYPE_EPOW:
+ rtas_parse_epow_errlog(elog);
+ break;
+ case RTAS_TYPE_HOTPLUG:
+ handle_dlpar_errorlog(elog);
+ break;
+ }
spin_unlock(&ras_log_buf_lock);
return IRQ_HANDLED;
--
2.0.0.rc3.2.g998f840
^ permalink raw reply related
* [PATCH] powerpc: module: fix TOC symbol CRC
From: Laurent Dufour @ 2014-06-17 15:56 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Anton Blanchard
The commit 71ec7c55ed91 introduced the magic symbol ".TOC." for ELFv2 ABI.
This symbol is built manually and has no CRC value computed. A zero value
is put in the CRC section to avoid modpost complaining about a missing CRC.
Unfortunately, this breaks the kernel module loading when the kernel is
relocated (kdump case for instance) because of the relocation applied to
the kcrctab values.
This patch compute a CRC value for the TOC symbol which will match the one
compute by the kernel when it is relocated - aka '0 - relocate_start' done in
maybe_relocated called by check_version (module.c).
Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
Cc: Anton Blanchard <anton@samba.org>
---
arch/powerpc/kernel/module_64.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 077d2ce..a80c933 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -315,8 +315,15 @@ static void dedotify_versions(struct modversion_info *vers,
struct modversion_info *end;
for (end = (void *)vers + size; vers < end; vers++)
- if (vers->name[0] == '.')
+ if (vers->name[0] == '.') {
memmove(vers->name, vers->name+1, strlen(vers->name));
+ /* The TOC symbol has no CRC computed. To avoid CRC
+ * check failing, we must force it to the expected
+ * value (see CRC check in module.c).
+ */
+ if (!strcmp(vers->name, "TOC."))
+ vers->crc = -(unsigned long)reloc_start;
+ }
}
/* Undefined symbols which refer to .funcname, hack to funcname (or .TOC.) */
^ permalink raw reply related
* Re: [PATCH 3/4] KVM: PPC: Book3S HV: Fix ABIv2 indirect branch issue
From: Alexander Graf @ 2014-06-17 16:05 UTC (permalink / raw)
To: Anton Blanchard, benh, paulus, clg; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <20140612181610.3479c3f2@kryten>
On 12.06.14 10:16, Anton Blanchard wrote:
> To establish addressability quickly, ABIv2 requires the target
> address of the function being called to be in r12.
>
> Signed-off-by: Anton Blanchard <anton@samba.org>
Thanks, applied to kvm-ppc-queue.
Alex
> ---
>
> Index: b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> ===================================================================
> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> @@ -1920,8 +1920,8 @@ hcall_try_real_mode:
> lwax r3,r3,r4
> cmpwi r3,0
> beq guest_exit_cont
> - add r3,r3,r4
> - mtctr r3
> + add r12,r3,r4
> + mtctr r12
> mr r3,r9 /* get vcpu pointer */
> ld r4,VCPU_GPR(R4)(r9)
> bctrl
^ permalink raw reply
* Re: [PATCH 4/4] KVM: PPC: Assembly functions exported to modules need _GLOBAL_TOC()
From: Alexander Graf @ 2014-06-17 16:06 UTC (permalink / raw)
To: Anton Blanchard, benh, paulus, clg; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <20140612181653.7141a7b8@kryten>
On 12.06.14 10:16, Anton Blanchard wrote:
> Both kvmppc_hv_entry_trampoline and kvmppc_entry_trampoline are
> assembly functions that are exported to modules and also require
> a valid r2.
>
> As such we need to use _GLOBAL_TOC so we provide a global entry
> point that establishes the TOC (r2).
>
> Signed-off-by: Anton Blanchard <anton@samba.org>
Thanks, applied to kvm-ppc-queue.
I've not applied patches 1 and 2 for now, as they break BE module support.
Alex
^ permalink raw reply
* RE: [PATCH v2] KVM: PPC: e500mc: Enhance tlb invalidation condition on vcpu schedule
From: mihai.caraman @ 2014-06-17 19:04 UTC (permalink / raw)
To: Scott Wood
Cc: linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org,
kvm-ppc@vger.kernel.org
In-Reply-To: <1403019343.6603.723.camel@snotra.buserror.net>
PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBXb29kIFNjb3R0LUIwNzQyMQ0K
PiBTZW50OiBUdWVzZGF5LCBKdW5lIDE3LCAyMDE0IDY6MzYgUE0NCj4gVG86IENhcmFtYW4gTWlo
YWkgQ2xhdWRpdS1CMDIwMDgNCj4gQ2M6IGt2bS1wcGNAdmdlci5rZXJuZWwub3JnOyBrdm1Admdl
ci5rZXJuZWwub3JnOyBsaW51eHBwYy0NCj4gZGV2QGxpc3RzLm96bGFicy5vcmcNCj4gU3ViamVj
dDogUmU6IFtQQVRDSCB2Ml0gS1ZNOiBQUEM6IGU1MDBtYzogRW5oYW5jZSB0bGIgaW52YWxpZGF0
aW9uDQo+IGNvbmRpdGlvbiBvbiB2Y3B1IHNjaGVkdWxlDQo+IA0KPiBPbiBUdWUsIDIwMTQtMDYt
MTcgYXQgMTI6MDIgKzAzMDAsIE1paGFpIENhcmFtYW4gd3JvdGU6DQo+ID4gT24gdmNwdSBzY2hl
ZHVsZSwgdGhlIGNvbmRpdGlvbiBjaGVja2VkIGZvciB0bGIgcG9sbHV0aW9uIGlzIHRvbyBsb29z
ZS4NCj4gPiBUaGUgdGxiIGVudHJpZXMgb2YgYSB2Y3B1IGJlY29tZSBwb2xsdXRlZCAodnMgc3Rh
bGUpIG9ubHkgd2hlbiBhDQo+IGRpZmZlcmVudA0KPiA+IHZjcHUgd2l0aGluIHRoZSBzYW1lIGxv
Z2ljYWwgcGFydGl0aW9uIHJ1bnMgaW4tYmV0d2Vlbi4gT3B0aW1pemUgdGhlDQo+IHRsYg0KPiA+
IGludmFsaWRhdGlvbiBjb25kaXRpb24gdGFraW5nIGludG8gYWNjb3VudCB0aGUgbG9naWNhbCBw
YXJ0aXRpb24gaWQuDQo+ID4NCj4gPiBXaXRoIHRoZSBuZXcgaW52YWxpZGF0aW9uIGNvbmRpdGlv
biwgYSBndWVzdCBzaG93cyA0JSBwZXJmb3JtYW5jZQ0KPiBpbXByb3ZlbWVudA0KPiA+IG9uIFA1
MDIwRFMgd2hpbGUgcnVubmluZyBhIG1lbW9yeSBzdHJlc3MgYXBwbGljYXRpb24gd2l0aCB0aGUg
Y3B1DQo+IG92ZXJzdWJzY3JpYmVkLA0KPiA+IHRoZSBvdGhlciBndWVzdCBydW5uaW5nIGEgY3B1
IGludGVuc2l2ZSB3b3JrbG9hZC4NCj4gDQo+IFNlZQ0KPiBodHRwczovL2xpc3RzLm96bGFicy5v
cmcvcGlwZXJtYWlsL2xpbnV4cHBjLWRldi8yMDE0LUp1bmUvMTE4NTQ3Lmh0bWwNCg0KVGhhbmtz
LiBUaGUgb3JpZ2luYWwgY29kZSBuZWVkcyBqdXN0IGEgc2ltcGxlIGFkanVzdG1lbnQgdG8gYmVu
ZWZpdCBmcm9tDQp0aGlzIG9wdGltaXphdGlvbiwgcGxlYXNlIHJldmlldyB2My4NCg0KLSBNaWtl
DQo=
^ permalink raw reply
* Re: [PATCH v2] KVM: PPC: e500mc: Enhance tlb invalidation condition on vcpu schedule
From: Scott Wood @ 2014-06-17 19:05 UTC (permalink / raw)
To: Caraman Mihai Claudiu-B02008
Cc: linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org,
kvm-ppc@vger.kernel.org
In-Reply-To: <66e18c10162144f0b9e63c6c3b0ade84@BY2PR03MB508.namprd03.prod.outlook.com>
On Tue, 2014-06-17 at 14:04 -0500, Caraman Mihai Claudiu-B02008 wrote:
> > -----Original Message-----
> > From: Wood Scott-B07421
> > Sent: Tuesday, June 17, 2014 6:36 PM
> > To: Caraman Mihai Claudiu-B02008
> > Cc: kvm-ppc@vger.kernel.org; kvm@vger.kernel.org; linuxppc-
> > dev@lists.ozlabs.org
> > Subject: Re: [PATCH v2] KVM: PPC: e500mc: Enhance tlb invalidation
> > condition on vcpu schedule
> >
> > On Tue, 2014-06-17 at 12:02 +0300, Mihai Caraman wrote:
> > > On vcpu schedule, the condition checked for tlb pollution is too loose.
> > > The tlb entries of a vcpu become polluted (vs stale) only when a
> > different
> > > vcpu within the same logical partition runs in-between. Optimize the
> > tlb
> > > invalidation condition taking into account the logical partition id.
> > >
> > > With the new invalidation condition, a guest shows 4% performance
> > improvement
> > > on P5020DS while running a memory stress application with the cpu
> > oversubscribed,
> > > the other guest running a cpu intensive workload.
> >
> > See
> > https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-June/118547.html
>
> Thanks. The original code needs just a simple adjustment to benefit from
> this optimization, please review v3.
Where is v3? Or is it forthcoming?
-Scott
^ permalink raw reply
* [PATCH v3] KVM: PPC: e500mc: Enhance tlb invalidation condition on vcpu schedule
From: Mihai Caraman @ 2014-06-17 19:09 UTC (permalink / raw)
To: kvm-ppc; +Cc: Scott Wood, Mihai Caraman, linuxppc-dev, kvm
On vcpu schedule, the condition checked for tlb pollution is too loose.
The tlb entries of a vcpu become polluted (vs stale) only when a different
vcpu within the same logical partition runs in-between. Optimize the tlb
invalidation condition keeping last_vcpu_on_cpu per logical partition id.
With the new invalidation condition, a guest shows 4% performance improvement
on P5020DS while running a memory stress application with the cpu oversubscribed,
the other guest running a cpu intensive workload.
Guest - old invalidation condition
real 3.89
user 3.87
sys 0.01
Guest - enhanced invalidation condition
real 3.75
user 3.73
sys 0.01
Host
real 3.70
user 1.85
sys 0.00
The memory stress application accesses 4KB pages backed by 75% of available
TLB0 entries:
char foo[ENTRIES][4096] __attribute__ ((aligned (4096)));
int main()
{
char bar;
int i, j;
for (i = 0; i < ITERATIONS; i++)
for (j = 0; j < ENTRIES; j++)
bar = foo[j][0];
return 0;
}
Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
Cc: Scott Wood <scottwood@freescale.com>
---
v3:
- use existing logic while keeping last_vcpu_per_cpu per lpid
v2:
- improve patch name and description
- add performance results
arch/powerpc/kvm/e500mc.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index 17e4562..95e33e3 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -110,7 +110,7 @@ void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr)
{
}
-static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu_on_cpu);
+static DEFINE_PER_CPU(struct kvm_vcpu * [KVMPPC_NR_LPIDS], last_vcpu_on_cpu);
static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu)
{
@@ -141,9 +141,9 @@ static void kvmppc_core_vcpu_load_e500mc(struct kvm_vcpu *vcpu, int cpu)
mtspr(SPRN_GESR, vcpu->arch.shared->esr);
if (vcpu->arch.oldpir != mfspr(SPRN_PIR) ||
- __get_cpu_var(last_vcpu_on_cpu) != vcpu) {
+ __get_cpu_var(last_vcpu_on_cpu)[vcpu->kvm->arch.lpid] != vcpu) {
kvmppc_e500_tlbil_all(vcpu_e500);
- __get_cpu_var(last_vcpu_on_cpu) = vcpu;
+ __get_cpu_var(last_vcpu_on_cpu)[vcpu->kvm->arch.lpid] = vcpu;
}
kvmppc_load_guest_fp(vcpu);
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH v3] KVM: PPC: e500mc: Enhance tlb invalidation condition on vcpu schedule
From: Scott Wood @ 2014-06-17 19:18 UTC (permalink / raw)
To: Mihai Caraman; +Cc: linuxppc-dev, kvm, kvm-ppc
In-Reply-To: <1403032176-28362-1-git-send-email-mihai.caraman@freescale.com>
On Tue, 2014-06-17 at 22:09 +0300, Mihai Caraman wrote:
> On vcpu schedule, the condition checked for tlb pollution is too loose.
> The tlb entries of a vcpu become polluted (vs stale) only when a different
> vcpu within the same logical partition runs in-between. Optimize the tlb
> invalidation condition keeping last_vcpu_on_cpu per logical partition id.
>
> With the new invalidation condition, a guest shows 4% performance improvement
> on P5020DS while running a memory stress application with the cpu oversubscribed,
> the other guest running a cpu intensive workload.
>
> Guest - old invalidation condition
> real 3.89
> user 3.87
> sys 0.01
>
> Guest - enhanced invalidation condition
> real 3.75
> user 3.73
> sys 0.01
>
> Host
> real 3.70
> user 1.85
> sys 0.00
>
> The memory stress application accesses 4KB pages backed by 75% of available
> TLB0 entries:
>
> char foo[ENTRIES][4096] __attribute__ ((aligned (4096)));
>
> int main()
> {
> char bar;
> int i, j;
>
> for (i = 0; i < ITERATIONS; i++)
> for (j = 0; j < ENTRIES; j++)
> bar = foo[j][0];
>
> return 0;
> }
>
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> Cc: Scott Wood <scottwood@freescale.com>
> ---
> v3:
> - use existing logic while keeping last_vcpu_per_cpu per lpid
>
> v2:
> - improve patch name and description
> - add performance results
>
>
> arch/powerpc/kvm/e500mc.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
> index 17e4562..95e33e3 100644
> --- a/arch/powerpc/kvm/e500mc.c
> +++ b/arch/powerpc/kvm/e500mc.c
> @@ -110,7 +110,7 @@ void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr)
> {
> }
>
> -static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu_on_cpu);
> +static DEFINE_PER_CPU(struct kvm_vcpu * [KVMPPC_NR_LPIDS], last_vcpu_on_cpu);
Hmm, I didn't know you could express types like that. Is this special
syntax that only works for typeof?
No space after *
Name should be adjusted to match, something like last_vcpu_of_lpid (with
the _on_cpu being implied by the fact that it's PER_CPU).
-Scott
^ permalink raw reply
* Re: [PATCH 04/24] powerpc: check/return actual error on sysfs functions
From: Greg KH @ 2014-06-17 19:23 UTC (permalink / raw)
To: Jeff Liu; +Cc: paulus, linuxppc-dev, LKML
In-Reply-To: <53A0512D.1090909@oracle.com>
On Tue, Jun 17, 2014 at 10:31:09PM +0800, Jeff Liu wrote:
> From: Jie Liu <jeff.liu@oracle.com>
>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Signed-off-by: Jie Liu <jeff.liu@oracle.com>
> ---
> arch/powerpc/platforms/powernv/opal-dump.c | 2 +-
> arch/powerpc/platforms/powernv/opal-elog.c | 4 ++--
> 2 files changed, 3 insertions(+), 3 deletions(-)
Ben and Paul, please do not take this patch, it is incorrect.
greg k-h
^ permalink raw reply
* RE: [PATCH v3] KVM: PPC: e500mc: Enhance tlb invalidation condition on vcpu schedule
From: mihai.caraman @ 2014-06-17 19:42 UTC (permalink / raw)
To: Scott Wood
Cc: linuxppc-dev@lists.ozlabs.org, kvm@vger.kernel.org,
kvm-ppc@vger.kernel.org
In-Reply-To: <1403032706.6603.776.camel@snotra.buserror.net>
PiA+IC1zdGF0aWMgREVGSU5FX1BFUl9DUFUoc3RydWN0IGt2bV92Y3B1ICosIGxhc3RfdmNwdV9v
bl9jcHUpOw0KPiA+ICtzdGF0aWMgREVGSU5FX1BFUl9DUFUoc3RydWN0IGt2bV92Y3B1ICogW0tW
TVBQQ19OUl9MUElEU10sDQo+IGxhc3RfdmNwdV9vbl9jcHUpOw0KPiANCj4gSG1tLCBJIGRpZG4n
dCBrbm93IHlvdSBjb3VsZCBleHByZXNzIHR5cGVzIGxpa2UgdGhhdC4gIElzIHRoaXMgc3BlY2lh
bA0KPiBzeW50YXggdGhhdCBvbmx5IHdvcmtzIGZvciB0eXBlb2Y/DQoNClllcywgQUZBSUsuDQoN
Cj4gTm8gc3BhY2UgYWZ0ZXIgKg0KDQpDaGVja3BhdGNoIGNvbXBsYWlucyBhYm91dCB0aGUgbWlz
c2luZyBzcGFjZSA7KQ0KDQo+IA0KPiBOYW1lIHNob3VsZCBiZSBhZGp1c3RlZCB0byBtYXRjaCwg
c29tZXRoaW5nIGxpa2UgbGFzdF92Y3B1X29mX2xwaWQgKHdpdGgNCj4gdGhlIF9vbl9jcHUgYmVp
bmcgaW1wbGllZCBieSB0aGUgZmFjdCB0aGF0IGl0J3MgUEVSX0NQVSkuDQoNCkkgd2FzIHRoaW5r
aW5nIHRvIHRoZSBsb25nIG5hbWUgYnV0IGl0IHdhcyBub3QgYXBwZWFsaW5nLCBJIHdpbGwgY2hh
bmdlIGl0IHRvDQpsYXN0X3ZjcHVfb2ZfbHBpZC4NCg0KLU1pa2UNCg==
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox