LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: DPAA Ethernet traffice troubles with Linux kernel
From: Andrew Lunn @ 2018-01-19 13:22 UTC (permalink / raw)
  To: Joakim Tjernlund
  Cc: madalin.bucur@nxp.com, linuxppc-dev@lists.ozlabs.org,
	netdev@vger.kernel.org, madskateman@gmail.com
In-Reply-To: <1516348851.4730.15.camel@infinera.com>

> > commit 4d8ee1935bcd666360311dfdadeee235d682d69a
> > Author: Florian Fainelli <f.fainelli@gmail.com>
> > Date: Tue Aug 22 15:24:47 2017 -0700
> > fsl/man: Inherit parent device and of_node
> > 
> > and was later addressed by this patch set:
> > 
> > http://patchwork.ozlabs.org/project/netdev/list/?series=8462&state=*
> > 
> > Even with these errors printed, all is working fine, it's just the
> > second probing that fails. Adding the latter patches or reverting
> > the one above makes the errors prints dissapear.
> 
> Looking at the above patch seriers I see it is in state Accepted and has been there
> since 2017-10-16
> That seems like a awful long to wait in before getting into Linux, is there something
> holding these patches back ?

They are in Linux, have been since October 16th. But at the moment,
they are only in v4.15, not v4.14.

These patches probably don't fit the stable rules, for getting them
added to v4.14.

https://github.com/torvalds/linux/blob/master/Documentation/process/stable-kernel-rules.rst

What is needed is a minimal fix. Or just wait until Sunday, when there
is a good chance v4.15 will be released.

   Andrew

^ permalink raw reply

* Re: [PATCH] powerpc/kprobes: Fix call trace due to incorrect preempt count
From: Naveen N. Rao @ 2018-01-19 11:37 UTC (permalink / raw)
  To: ananth, Michael Ellerman; +Cc: linuxppc-dev
In-Reply-To: <87bmhqayeq.fsf@concordia.ellerman.id.au>

Michael Ellerman wrote:
> Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com> writes:
>=20
>> On Wed, Jan 17, 2018 at 05:52:24PM +0530, Naveen N. Rao wrote:
>>> Michael Ellerman reported the following call trace when running
>>> ftracetest:
>>>=20
>>> BUG: using __this_cpu_write() in preemptible [00000000] code: ftracetes=
t/6178
>>> caller is opt_pre_handler+0xc4/0x110
>>> CPU: 1 PID: 6178 Comm: ftracetest Not tainted 4.15.0-rc7-gcc6x-gb2cd1df=
 #1
>>> Call Trace:
>>> [c0000000f9ec39c0] [c000000000ac4304] dump_stack+0xb4/0x100 (unreliable=
)
>>> [c0000000f9ec3a00] [c00000000061159c] check_preemption_disabled+0x15c/0=
x170
>>> [c0000000f9ec3a90] [c000000000217e84] opt_pre_handler+0xc4/0x110
>>> [c0000000f9ec3af0] [c00000000004cf68] optimized_callback+0x148/0x170
>>> [c0000000f9ec3b40] [c00000000004d954] optinsn_slot+0xec/0x10000
>>> [c0000000f9ec3e30] [c00000000004bae0] kretprobe_trampoline+0x0/0x10
>>>=20
>>> This is showing up since OPTPROBES is now enabled with CONFIG_PREEMPT.
>>>=20
>>> trampoline_probe_handler() considers itself to be a special kprobe
>>> handler for kretprobes. In doing so, it expects to be called from
>>> kprobe_handler() on a trap, and re-enables preemption before returning =
a
>>> non-zero return value so as to suppress any subsequent processing of th=
e
>>> trap by the kprobe_handler().
>>>=20
>>> However, with optprobes, we don't deal with special handlers (we ignore
>>> the return code) and just try to re-enable preemption causing the above
>>> trace.
>>>=20
>>> To address this, modify trampoline_probe_handler() to not be special.
>>> The only additional processing done in kprobe_handler() is to emulate
>>> the instruction (in this case, a 'nop'). We adjust the value of
>>> regs->nip for the purpose and delegate the job of re-enabling
>>> preemption and resetting current kprobe to the probe handlers
>>> (kprobe_handler() or optimized_callback()).
>>>=20
>>> Reported-by: Michael Ellerman <mpe@ellerman.id.au>
>>> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
>>
>> Acked-by: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
>=20
> Fixes: 51c9c0843993 ("powerpc/kprobes: Implement Optprobes")

Fixes: 8a2d71a3f2737e ("powerpc/kprobes: Disable preemption before=20
invoking probe handler for optprobes")

I think this is more appropriate. I should have caught this issue with=20
kretprobes, but I am fairly certain that I ran ftracetest at that point,
but didn't see any call traces.

Regards,
Naveen

=

^ permalink raw reply

* [GIT PULL] Please pull powerpc/linux.git powerpc-4.15-8 tag
From: Michael Ellerman @ 2018-01-19 11:23 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: benh, linux-kernel, linuxppc-dev, msuchanek

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

Hi Linus,

Please pull some more powerpc fixes for 4.15:

The following changes since commit 6e032b350cd1fdb830f18f8320ef0e13b4e24094:

  powerpc/powernv: Check device-tree for RFI flush settings (2018-01-10 21:27:16 +1100)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git tags/powerpc-4.15-8

for you to fetch changes up to 1b689a95ce7427075f9ac9fb4aea1af530742b7f:

  powerpc/pseries: include linux/types.h in asm/hvcall.h (2018-01-17 23:30:46 +1100)

----------------------------------------------------------------
powerpc fixes for 4.15 #8

More than we'd like after rc8, but nothing very alarming either, just tying up
loose ends before the release:

Since we changed powernv to use cpufreq_get() from show_cpuinfo(), we see
warnings with PREEMPT enabled. But the preempt_disable() in show_cpuinfo()
doesn't actually prevent CPU hotplug as it suggests, so remove it.

Two updates to the recently merged RFI flush code. Wire up the generic sysfs
file to report the status, and add a debugfs file to allow enabling/disabling it
at runtime.

Two updates to xmon, one to add the RFI flush related fields to the paca dump,
and another to not use hashed pointers in the paca dump.

And one minor fix to add a missing include of linux/types.h in asm/hvcall.h, not
seen to break the build in upstream, but correct anyway.

Thanks to:
  Benjamin Herrenschmidt, Michal Suchanek, Nicholas Piggin.

----------------------------------------------------------------
Benjamin Herrenschmidt (1):
      powerpc: Don't preempt_disable() in show_cpuinfo()

Michael Ellerman (4):
      powerpc/xmon: Add RFI flush related fields to paca dump
      powerpc/xmon: Don't print hashed pointers in paca dump
      powerpc/64s: Wire up cpu_show_meltdown()
      powerpc/64s: Allow control of RFI flush via debugfs

Michal Suchanek (1):
      powerpc/pseries: include linux/types.h in asm/hvcall.h

 arch/powerpc/Kconfig               |  1 +
 arch/powerpc/include/asm/hvcall.h  |  1 +
 arch/powerpc/kernel/setup-common.c | 11 -----------
 arch/powerpc/kernel/setup_64.c     | 38 ++++++++++++++++++++++++++++++++++++++
 arch/powerpc/xmon/xmon.c           | 26 +++++++++++++++-----------
 5 files changed, 55 insertions(+), 22 deletions(-)

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 800 bytes --]

^ permalink raw reply

* Re: [PATCH] powerpc/kprobes: Fix call trace due to incorrect preempt count
From: Michael Ellerman @ 2018-01-19 11:19 UTC (permalink / raw)
  To: ananth, Naveen N. Rao; +Cc: linuxppc-dev
In-Reply-To: <20180117164822.GA3932@in.ibm.com>

Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com> writes:

> On Wed, Jan 17, 2018 at 05:52:24PM +0530, Naveen N. Rao wrote:
>> Michael Ellerman reported the following call trace when running
>> ftracetest:
>> 
>> BUG: using __this_cpu_write() in preemptible [00000000] code: ftracetest/6178
>> caller is opt_pre_handler+0xc4/0x110
>> CPU: 1 PID: 6178 Comm: ftracetest Not tainted 4.15.0-rc7-gcc6x-gb2cd1df #1
>> Call Trace:
>> [c0000000f9ec39c0] [c000000000ac4304] dump_stack+0xb4/0x100 (unreliable)
>> [c0000000f9ec3a00] [c00000000061159c] check_preemption_disabled+0x15c/0x170
>> [c0000000f9ec3a90] [c000000000217e84] opt_pre_handler+0xc4/0x110
>> [c0000000f9ec3af0] [c00000000004cf68] optimized_callback+0x148/0x170
>> [c0000000f9ec3b40] [c00000000004d954] optinsn_slot+0xec/0x10000
>> [c0000000f9ec3e30] [c00000000004bae0] kretprobe_trampoline+0x0/0x10
>> 
>> This is showing up since OPTPROBES is now enabled with CONFIG_PREEMPT.
>> 
>> trampoline_probe_handler() considers itself to be a special kprobe
>> handler for kretprobes. In doing so, it expects to be called from
>> kprobe_handler() on a trap, and re-enables preemption before returning a
>> non-zero return value so as to suppress any subsequent processing of the
>> trap by the kprobe_handler().
>> 
>> However, with optprobes, we don't deal with special handlers (we ignore
>> the return code) and just try to re-enable preemption causing the above
>> trace.
>> 
>> To address this, modify trampoline_probe_handler() to not be special.
>> The only additional processing done in kprobe_handler() is to emulate
>> the instruction (in this case, a 'nop'). We adjust the value of
>> regs->nip for the purpose and delegate the job of re-enabling
>> preemption and resetting current kprobe to the probe handlers
>> (kprobe_handler() or optimized_callback()).
>> 
>> Reported-by: Michael Ellerman <mpe@ellerman.id.au>
>> Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
>
> Acked-by: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>

Fixes: 51c9c0843993 ("powerpc/kprobes: Implement Optprobes")

??

cheers

^ permalink raw reply

* Re: linux-next: manual merge of the powerpc tree with the powerpc-fixes tree
From: Michael Ellerman @ 2018-01-19 11:18 UTC (permalink / raw)
  To: Stephen Rothwell, Benjamin Herrenschmidt, PowerPC
  Cc: Linux-Next Mailing List, Linux Kernel Mailing List
In-Reply-To: <20180118092112.0e46a25c@canb.auug.org.au>

Stephen Rothwell <sfr@canb.auug.org.au> writes:

> Hi all,
>
> Today's linux-next merge of the powerpc tree got a conflict in:
>
>   arch/powerpc/kernel/setup-common.c
>
> between commit:
>
>   349524bc0da6 ("powerpc: Don't preempt_disable() in show_cpuinfo()")
>
> from the powerpc-fixes tree and commit:
>
>   f5f563012a70 ("powerpc: Make newline in cpuinfo unconditional")
>
> from the powerpc tree.
>
> I fixed it up (see below) and can carry the fix as necessary. This
> is now fixed as far as linux-next is concerned, but any non trivial
> conflicts should be mentioned to your upstream maintainer when your tree
> is submitted for merging.  You may also want to consider cooperating
> with the maintainer of the conflicting tree to minimise any particularly
> complex conflicts.

Nah that guy is a jerk.

Thanks for the report.

cheers

^ permalink raw reply

* Re: [PATCH 0/3] PCI: move DT PCI functions to PCI core
From: Michael Ellerman @ 2018-01-19 11:16 UTC (permalink / raw)
  To: Bjorn Helgaas, Rob Herring
  Cc: Bjorn Helgaas, devicetree, linux-kernel, Benjamin Herrenschmidt,
	Paul Mackerras, Frank Rowand, linuxppc-dev, linux-pci
In-Reply-To: <20180117235555.GC53542@bhelgaas-glaptop.roam.corp.google.com>

Bjorn Helgaas <helgaas@kernel.org> writes:

> On Thu, Jan 04, 2018 at 03:12:12PM -0600, Rob Herring wrote:
>> Most subsystem specific functions have been moved into the respective
>> subsystems. Only PCI and networking remain. This series moves most of the
>> PCI related code to drivers/pci/of.c. Some bus address functions for PCI
>> remain in of/address.c because we don't have infrastructure to split up
>> the per bus helper functions.
>> 
>> I expect Bjorn to take this series, so PPC maintainers please ack.
>> 
>> Rob
>> 
>> Rob Herring (3):
>>   PCI: move OF related PCI functions into PCI core
>>   powerpc/pci: use of_irq_parse_and_map_pci helper
>>   PCI: make of_irq_parse_pci static
>> 
>>  arch/arm/mach-mvebu/Kconfig      |   1 -
>>  arch/powerpc/kernel/pci-common.c |   8 +-
>>  drivers/of/Kconfig               |  16 --
>>  drivers/of/Makefile              |   2 -
>>  drivers/of/address.c             |   8 +-
>>  drivers/of/of_pci.c              | 384 -----------------------------
>>  drivers/of/of_pci_irq.c          | 131 ----------
>>  drivers/pci/of.c                 | 505 +++++++++++++++++++++++++++++++++++++++
>>  include/linux/of_pci.h           |   8 +-
>>  9 files changed, 510 insertions(+), 553 deletions(-)
>>  delete mode 100644 drivers/of/of_pci.c
>>  delete mode 100644 drivers/of/of_pci_irq.c
>
> Applied to pci/dt-resources for v4.16, thanks!
>
> I'll update this if necessary if PPC maintainers comment.

Thanks. Seems fine, fingers crossed :)

cheers

^ permalink raw reply

* Re: [PATCH v7 2/2] cxl: read PHB indications from the device tree
From: Laurent Dufour @ 2018-01-19 11:00 UTC (permalink / raw)
  To: Philippe Bergheaud, linuxppc-dev; +Cc: benh, clombard, fbarrat
In-Reply-To: <20180115133937.13063-2-felix@linux.vnet.ibm.com>

On 15/01/2018 14:39, Philippe Bergheaud wrote:
> Configure the P9 XSL_DSNCTL register with PHB indications found
> in the device tree, or else use legacy hard-coded values.
> 
> Signed-off-by: Philippe Bergheaud <felix@linux.vnet.ibm.com>
> ---
> Changelog:
> 
> v2: New patch. Use the new device tree property "ibm,phb-indications".
> 
> v3: No change.
> 
> v4: No functional change.
>     Drop cosmetic fix in comment.
> 
> v5: get_phb_indications():
>       - make static variables local to function.
>       - return static variable values by arguments.
> 
> v6: get_phb_indications():
>       - acquire a mutex before setting the phb indications.
> 
> v7: get_phb_indications():
>     cxl_get_xsl9_dsnctl():
>       - return -ENODEV instead of -1.
> 
> This patch depends on the following skiboot patch:
>   https://patchwork.ozlabs.org/patch/858324/
> ---
>  drivers/misc/cxl/cxl.h    |  2 +-
>  drivers/misc/cxl/cxllib.c |  2 +-
>  drivers/misc/cxl/pci.c    | 50 ++++++++++++++++++++++++++++++++++++++++++-----
>  3 files changed, 47 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
> index e46a4062904a..5a6e9a921c2b 100644
> --- a/drivers/misc/cxl/cxl.h
> +++ b/drivers/misc/cxl/cxl.h
> @@ -1062,7 +1062,7 @@ int cxl_psl_purge(struct cxl_afu *afu);
>  int cxl_calc_capp_routing(struct pci_dev *dev, u64 *chipid,
>  			  u32 *phb_index, u64 *capp_unit_id);
>  int cxl_slot_is_switched(struct pci_dev *dev);
> -int cxl_get_xsl9_dsnctl(u64 capp_unit_id, u64 *reg);
> +int cxl_get_xsl9_dsnctl(struct pci_dev *dev, u64 capp_unit_id, u64 *reg);
>  u64 cxl_calculate_sr(bool master, bool kernel, bool real_mode, bool p9);
> 
>  void cxl_native_irq_dump_regs_psl9(struct cxl_context *ctx);
> diff --git a/drivers/misc/cxl/cxllib.c b/drivers/misc/cxl/cxllib.c
> index dc9bc1807fdf..61f80d586279 100644
> --- a/drivers/misc/cxl/cxllib.c
> +++ b/drivers/misc/cxl/cxllib.c
> @@ -99,7 +99,7 @@ int cxllib_get_xsl_config(struct pci_dev *dev, struct cxllib_xsl_config *cfg)
>  	if (rc)
>  		return rc;
> 
> -	rc = cxl_get_xsl9_dsnctl(capp_unit_id, &cfg->dsnctl);
> +	rc = cxl_get_xsl9_dsnctl(dev, capp_unit_id, &cfg->dsnctl);
>  	if (rc)
>  		return rc;
>  	if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
> diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
> index 19969ee86d6f..89840181fc03 100644
> --- a/drivers/misc/cxl/pci.c
> +++ b/drivers/misc/cxl/pci.c
> @@ -409,21 +409,61 @@ int cxl_calc_capp_routing(struct pci_dev *dev, u64 *chipid,
>  	return 0;
>  }
> 
> -int cxl_get_xsl9_dsnctl(u64 capp_unit_id, u64 *reg)
> +static DEFINE_MUTEX(indications_mutex);
> +
> +static int get_phb_indications(struct pci_dev *dev, u64* capiind, u64 *asnind,
> +			       u64 *nbwind)
> +{
> +	static u64 nbw, asn, capi = 0;
> +	struct device_node *np;
> +	const __be32 *prop;
> +
> +	if (!capi) {
> +		mutex_lock(&indications_mutex);
> +		if (!capi) {
> +			if (!(np = pnv_pci_get_phb_node(dev))) {
> +				mutex_unlock(&indications_mutex);
> +				return -ENODEV;
> +			}
> +
> +			prop = of_get_property(np, "ibm,phb-indications", NULL);
> +			if (!prop) {
> +				nbw = 0x0300UL; /* legacy values */
> +				asn = 0x0400UL;
> +				capi = 0x0200UL;
> +			} else {
> +				nbw = (u64)be32_to_cpu(prop[2]);
> +				asn = (u64)be32_to_cpu(prop[1]);
> +				capi = (u64)be32_to_cpu(prop[0]);
> +			}
> +			of_node_put(np);
> +		}
> +		mutex_unlock(&indications_mutex);
> +	}

In the case capi !=0, I think you will need a smp_rmb() here because there
is a dependancy between the check on capi and the reading of the asn and
nbw values, and there is nothing to prevent the CPU from fetching those
values before fetching and checking capi.

> +	*capiind = capi;
> +	*asnind = asn;
> +	*nbwind = nbw;
> +	return 0;
> +}
> +
> +int cxl_get_xsl9_dsnctl(struct pci_dev *dev, u64 capp_unit_id, u64 *reg)
>  {
>  	u64 xsl_dsnctl;
> +	u64 capiind, asnind, nbwind;
> 
>  	/*
>  	 * CAPI Identifier bits [0:7]
>  	 * bit 61:60 MSI bits --> 0
>  	 * bit 59 TVT selector --> 0
>  	 */
> +	if (get_phb_indications(dev, &capiind, &asnind, &nbwind))
> +		return -ENODEV;
> 
>  	/*
>  	 * Tell XSL where to route data to.
>  	 * The field chipid should match the PHB CAPI_CMPM register
>  	 */
> -	xsl_dsnctl = ((u64)0x2 << (63-7)); /* Bit 57 */
> +	xsl_dsnctl = (capiind << (63-15)); /* Bit 57 */
>  	xsl_dsnctl |= (capp_unit_id << (63-15));
> 
>  	/* nMMU_ID Defaults to: b’000001001’*/
> @@ -437,14 +477,14 @@ int cxl_get_xsl9_dsnctl(u64 capp_unit_id, u64 *reg)
>  		 * nbwind=0x03, bits [57:58], must include capi indicator.
>  		 * Not supported on P9 DD1.
>  		 */
> -		xsl_dsnctl |= ((u64)0x03 << (63-47));
> +		xsl_dsnctl |= (nbwind << (63-55));
> 
>  		/*
>  		 * Upper 16b address bits of ASB_Notify messages sent to the
>  		 * system. Need to match the PHB’s ASN Compare/Mask Register.
>  		 * Not supported on P9 DD1.
>  		 */
> -		xsl_dsnctl |= ((u64)0x04 << (63-55));
> +		xsl_dsnctl |= asnind;
>  	}
> 
>  	*reg = xsl_dsnctl;
> @@ -464,7 +504,7 @@ static int init_implementation_adapter_regs_psl9(struct cxl *adapter,
>  	if (rc)
>  		return rc;
> 
> -	rc = cxl_get_xsl9_dsnctl(capp_unit_id, &xsl_dsnctl);
> +	rc = cxl_get_xsl9_dsnctl(dev, capp_unit_id, &xsl_dsnctl);
>  	if (rc)
>  		return rc;
> 

^ permalink raw reply

* Re: [PATCH v2] powerpc/mm: Fix growth direction for hugepages mmaps with slice
From: Aneesh Kumar K.V @ 2018-01-19 10:05 UTC (permalink / raw)
  To: Christophe LEROY, linuxppc-dev
In-Reply-To: <87y3kuz559.fsf@linux.vnet.ibm.com>


Did a reply instead of reply-all.

Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> writes:

> Christophe LEROY <christophe.leroy@c-s.fr> writes:
>
>> Le 17/01/2018 =C3=A0 04:19, Aneesh Kumar K.V a =C3=A9crit=C2=A0:
>>>=20
>>>=20
>>> On 01/16/2018 10:18 PM, Christophe LEROY wrote:
>>>>
>>>>
>>>> Le 16/01/2018 =C3=A0 17:03, Aneesh Kumar K.V a =C3=A9crit=C2=A0:
>>>>> Christophe Leroy <christophe.leroy@c-s.fr> writes:
>>>>>
>>>>>> An application running with libhugetlbfs fails to allocate
>>>>>> additional pages to HEAP due to the hugemap being done
>>>>>> inconditionally as topdown mapping:
>>>>>>
>>>>>> mmap(0x10080000, 1572864, PROT_READ|PROT_WRITE,=20
>>>>>> MAP_PRIVATE|MAP_ANONYMOUS|0x40000, -1, 0) =3D 0x73e80000
>>>>>> [...]
>>>>>> mmap(0x74000000, 1048576, PROT_READ|PROT_WRITE,=20
>>>>>> MAP_PRIVATE|MAP_ANONYMOUS|0x40000, -1, 0x180000) =3D 0x73d80000
>>>>>> munmap(0x73d80000, 1048576)=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =3D 0
>>>>>> [...]
>>>>>> mmap(0x74000000, 1572864, PROT_READ|PROT_WRITE,=20
>>>>>> MAP_PRIVATE|MAP_ANONYMOUS|0x40000, -1, 0x180000) =3D 0x73d00000
>>>>>> munmap(0x73d00000, 1572864)=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =3D 0
>>>>>> [...]
>>>>>> mmap(0x74000000, 1572864, PROT_READ|PROT_WRITE,=20
>>>>>> MAP_PRIVATE|MAP_ANONYMOUS|0x40000, -1, 0x180000) =3D 0x73d00000
>>>>>> munmap(0x73d00000, 1572864)=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =3D 0
>>>>>> [...]
>>>>>>
>>>>>
>>>>> Can you explain the failure details above. I am not sure I understand
>>>>> what to read from the above output.
>>>>
>>>> libhugetlbfs first requests an area of size 1.5Mbytes, at address=20
>>>> 0x10080000
>>>> mmap() returns an area at address 0x73e80000
>>>>
>>>> Then libhugetlbfs requests an additional area on top of that, ie at=20
>>>> address 0x74000000, to expand the heap.
>>>> But mmap() returns an area at address 0x73d80000, ie under the=20
>>>> previous area.
>>>>
>>>=20
>>>=20
>>> Can you share the test details?. Why does it not fail on book3s64? We=20
>>> use topdown search with book3s64.
>>
>> I don't know about book3s64, I only have 8xx.
>>
>> Here is my test app:
>>
>
> The test ran fine on ppc64.
>
> kvaneesh@ltctulc6a-p1:[~]$ HUGETLB_MORECORE=3Dyes ./a.out=20
> 10000000-10010000 r-xp 00000000 fc:00 9044312                            =
/home/kvaneesh/a.out
> 10010000-10020000 r--p 00000000 fc:00 9044312                            =
/home/kvaneesh/a.out
> 10020000-10030000 rw-p 00010000 fc:00 9044312                            =
/home/kvaneesh/a.out
> 7ffff7d60000-7ffff7f10000 r-xp 00000000 fc:00 9250090                    =
/lib/powerpc64le-linux-gnu/libc-2.23.so
> 7ffff7f10000-7ffff7f20000 r--p 001a0000 fc:00 9250090                    =
/lib/powerpc64le-linux-gnu/libc-2.23.so
> 7ffff7f20000-7ffff7f30000 rw-p 001b0000 fc:00 9250090                    =
/lib/powerpc64le-linux-gnu/libc-2.23.so
> 7ffff7f40000-7ffff7f60000 r-xp 00000000 fc:00 10754812                   =
/usr/lib/libhugetlbfs.so.0
> 7ffff7f60000-7ffff7f70000 r--p 00010000 fc:00 10754812                   =
/usr/lib/libhugetlbfs.so.0
> 7ffff7f70000-7ffff7f80000 rw-p 00020000 fc:00 10754812                   =
/usr/lib/libhugetlbfs.so.0
> 7ffff7f80000-7ffff7fa0000 r-xp 00000000 00:00 0                          =
[vdso]
> 7ffff7fa0000-7ffff7fe0000 r-xp 00000000 fc:00 9250107                    =
/lib/powerpc64le-linux-gnu/ld-2.23.so
> 7ffff7fe0000-7ffff7ff0000 r--p 00030000 fc:00 9250107                    =
/lib/powerpc64le-linux-gnu/ld-2.23.so
> 7ffff7ff0000-7ffff8000000 rw-p 00040000 fc:00 9250107                    =
/lib/powerpc64le-linux-gnu/ld-2.23.so
> 7ffffffd0000-800000000000 rw-p 00000000 00:00 0                          =
[stack]
>
>
> Allocated 1Mbytes at 0x10000000010
>
>
> Allocated 1Mbytes at 0x10002000020
>
>
> Allocated 1Mbytes at 0x10004000030
>
> 10000000-10010000 r-xp 00000000 fc:00 9044312                            =
/home/kvaneesh/a.out
> 10010000-10020000 r--p 00000000 fc:00 9044312                            =
/home/kvaneesh/a.out
> 10020000-10030000 rw-p 00010000 fc:00 9044312                            =
/home/kvaneesh/a.out
> 10000000000-10003000000 rw-p 00000000 00:0d 1041435                      =
/anon_hugepage (deleted)
> 10003000000-10005000000 rw-p 03000000 00:0d 1041436                      =
/anon_hugepage (deleted)
> 10005000000-10007000000 rw-p 05000000 00:0d 1041437                      =
/anon_hugepage (deleted)
> 7ffff7d60000-7ffff7f10000 r-xp 00000000 fc:00 9250090                    =
/lib/powerpc64le-linux-gnu/libc-2.23.so
> 7ffff7f10000-7ffff7f20000 r--p 001a0000 fc:00 9250090                    =
/lib/powerpc64le-linux-gnu/libc-2.23.so
> 7ffff7f20000-7ffff7f30000 rw-p 001b0000 fc:00 9250090                    =
/lib/powerpc64le-linux-gnu/libc-2.23.so
> 7ffff7f40000-7ffff7f60000 r-xp 00000000 fc:00 10754812                   =
/usr/lib/libhugetlbfs.so.0
> 7ffff7f60000-7ffff7f70000 r--p 00010000 fc:00 10754812                   =
/usr/lib/libhugetlbfs.so.0
> 7ffff7f70000-7ffff7f80000 rw-p 00020000 fc:00 10754812                   =
/usr/lib/libhugetlbfs.so.0
> 7ffff7f80000-7ffff7fa0000 r-xp 00000000 00:00 0                          =
[vdso]
> 7ffff7fa0000-7ffff7fe0000 r-xp 00000000 fc:00 9250107                    =
/lib/powerpc64le-linux-gnu/ld-2.23.so
> 7ffff7fe0000-7ffff7ff0000 r--p 00030000 fc:00 9250107                    =
/lib/powerpc64le-linux-gnu/ld-2.23.so
> 7ffff7ff0000-7ffff8000000 rw-p 00040000 fc:00 9250107                    =
/lib/powerpc64le-linux-gnu/ld-2.23.so
> 7ffffffd0000-800000000000 rw-p 00000000 00:00 0                          =
[stack]
>
>
>
> So i am definitely missing something. I understand that generic hugetlb
> get unmapped area always search bottom up and 8xx used to depend on that
> callback. But on ppc64 slice based get unmapped area always did topdown
> and I am not sure whether we should change that. More over I don't think
> MAP_GROWSDOWN is the right flag for selecting topdown/bottom up search.
>
>
> Is it that libhugetlbfs does something specific for 32 bit? Other option
> is to add huget_get_unmapped_area for 8xx that does bottom up search?
>
> If you are on ppc64 irc on freenode we can discuss this there.
> -aneesh

^ permalink raw reply

* Re: [PATCH v2 1/5] powerpc/mm: Enhance 'slice' for supporting PPC32
From: Christophe LEROY @ 2018-01-19  9:45 UTC (permalink / raw)
  To: Aneesh Kumar K.V, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Scott Wood
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <c9ab9a1b-4c77-fdfc-50d1-974388cc3b10@linux.vnet.ibm.com>



Le 19/01/2018 à 10:13, Aneesh Kumar K.V a écrit :
> 
> 
> On 01/19/2018 02:37 PM, Christophe LEROY wrote:
>>
>>
>> Le 19/01/2018 à 10:02, Aneesh Kumar K.V a écrit :
>>>
>>>
>>> On 01/19/2018 02:14 PM, Christophe LEROY wrote:
>>>>
>>>>
>>>> Le 19/01/2018 à 09:24, Aneesh Kumar K.V a écrit :
>>>>> Christophe Leroy <christophe.leroy@c-s.fr> writes:
>>>>>
>>>>>> In preparation for the following patch which will fix an issue on
>>>>>> the 8xx by re-using the 'slices', this patch enhances the
>>>>>> 'slices' implementation to support 32 bits CPUs.
>>>>>>
>>>>>> On PPC32, the address space is limited to 4Gbytes, hence only the low
>>>>>> slices will be used. As of today, the code uses
>>>>>> SLICE_LOW_TOP (0x100000000ul) and compares it with addr to determine
>>>>>> if addr refers to low or high space.
>>>>>> On PPC32, such a (addr < SLICE_LOW_TOP) test is always false because
>>>>>> 0x100000000ul degrades to 0. Therefore, the patch modifies
>>>>>> SLICE_LOW_TOP to (0xfffffffful) and modifies the tests to
>>>>>> (addr <= SLICE_LOW_TOP) which will then always be true on PPC32
>>>>>> as addr has type 'unsigned long' while not modifying the PPC64
>>>>>> behaviour.
>>>>>>
>>>>>> This patch moves "slices" functions prototypes from page64.h to 
>>>>>> page.h
>>>>>>
>>>>>> The high slices use bitmaps. As bitmap functions are not prepared to
>>>>>> handling bitmaps of size 0, the bitmap_xxx() calls are wrapped into
>>>>>> slice_bitmap_xxx() macros which will take care of the 0 nbits case.
>>>>>>
>>>>>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>>>>>> ---
>>>>>>   v2: First patch of v1 serie split in two parts ; added 
>>>>>> slice_bitmap_xxx() macros.
>>>>>>
>>>>>>   arch/powerpc/include/asm/page.h      | 14 +++++++++
>>>>>>   arch/powerpc/include/asm/page_32.h   | 19 ++++++++++++
>>>>>>   arch/powerpc/include/asm/page_64.h   | 21 ++-----------
>>>>>>   arch/powerpc/mm/hash_utils_64.c      |  2 +-
>>>>>>   arch/powerpc/mm/mmu_context_nohash.c |  7 +++++
>>>>>>   arch/powerpc/mm/slice.c              | 60 
>>>>>> ++++++++++++++++++++++++------------
>>>>>>   6 files changed, 83 insertions(+), 40 deletions(-)
>>>>>>
>>>>>> diff --git a/arch/powerpc/include/asm/page.h 
>>>>>> b/arch/powerpc/include/asm/page.h
>>>>>> index 8da5d4c1cab2..d0384f9db9eb 100644
>>>>>> --- a/arch/powerpc/include/asm/page.h
>>>>>> +++ b/arch/powerpc/include/asm/page.h
>>>>>> @@ -342,6 +342,20 @@ typedef struct page *pgtable_t;
>>>>>>   #endif
>>>>>>   #endif
>>>>>> +#ifdef CONFIG_PPC_MM_SLICES
>>>>>> +struct mm_struct;
>>>>>> +
>>>>>> +unsigned long slice_get_unmapped_area(unsigned long addr, 
>>>>>> unsigned long len,
>>>>>> +                      unsigned long flags, unsigned int psize,
>>>>>> +                      int topdown);
>>>>>> +
>>>>>> +unsigned int get_slice_psize(struct mm_struct *mm, unsigned long 
>>>>>> addr);
>>>>>> +
>>>>>> +void slice_set_user_psize(struct mm_struct *mm, unsigned int psize);
>>>>>> +void slice_set_range_psize(struct mm_struct *mm, unsigned long 
>>>>>> start,
>>>>>> +               unsigned long len, unsigned int psize);
>>>>>> +#endif
>>>>>> +
>>>>>
>>>>> Should we do a slice.h ? the way we have other files? and then do
>>>>
>>>> Yes we could add a slice.h instead of using page.h for that, good idea.
>>>>
>>>>>
>>>>> arch/powerpc/include/asm/book3s/64/slice.h that will carry
>>>>> #define slice_bitmap_zero(dst, nbits) \
>>>>>     do { if (nbits) bitmap_zero(dst, nbits); } while (0)
>>>>> #define slice_bitmap_set(dst, pos, nbits) \
>>>>> do { if (nbits) bitmap_set(dst, pos, nbits); } while (0)
>>>>> #define slice_bitmap_copy(dst, src, nbits) \
>>>>> do { if (nbits) bitmap_copy(dst, src, nbits); } while (0)
>>>>> #define slice_bitmap_and(dst, src1, src2, nbits) \
>>>>>     ({ (nbits) ? bitmap_and(dst, src1, src2, nbits) : 0; })
>>>>> #define slice_bitmap_or(dst, src1, src2, nbits) \
>>>>>     do { if (nbits) bitmap_or(dst, src1, src2, nbits); } while (0)
>>>>> #define slice_bitmap_andnot(dst, src1, src2, nbits) \
>>>>>     ({ (nbits) ? bitmap_andnot(dst, src1, src2, nbits) : 0; })
>>>>> #define slice_bitmap_equal(src1, src2, nbits) \
>>>>>     ({ (nbits) ? bitmap_equal(src1, src2, nbits) : 1; })
>>>>> #define slice_bitmap_empty(src, nbits) \
>>>>>     ({ (nbits) ? bitmap_empty(src, nbits) : 1; })
>>>>>
>>>>> This without that if(nbits) check and a proper static inline so 
>>>>> that we
>>>>> can do type checking.
>>>>
>>>> Is it really worth duplicating that just for eliminating the 'if 
>>>> (nbits)' in one case ?
>>>>
>>>> Only in book3s/64 we will be able to eliminate that, for nohash/32 
>>>> we need to keep the test due to the difference between low and high 
>>>> slices.
>>>
>>> the other advantage is we move the SLICE_LOW_SHIFT to the right 
>>> location. IMHO mm subystem is really complex with these really 
>>> overloaded headers. If we can keep it  seperate we should with 
>>> minimal code duplication?
>>
>> For the constants I fully agree with your proposal and I will do it. I 
>> was only questionning the benefit of moving the slice_bitmap_xxxx() 
>> stuff, taking into account that the 'if (nbits)' test is already 
>> eliminated by the compiler.
>>
> 
> That is compiler dependent as you are finding with the other patch where 
> if (0) didn't get compiled out

I don't think so. When I had the missing prototype, the compilation goes 
ok, including the final link. Which means at the end the code is not 
included since radix_enabled() evaluates to 0.

Many many parts of the kernel are based on this assumption.

Christophe

> 
> -aneesh

^ permalink raw reply

* Re: [PATCH v2 1/5] powerpc/mm: Enhance 'slice' for supporting PPC32
From: Aneesh Kumar K.V @ 2018-01-19  9:13 UTC (permalink / raw)
  To: Christophe LEROY, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Scott Wood
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <28c3ba39-ef31-5ff3-7672-3e9d1942be94@c-s.fr>



On 01/19/2018 02:37 PM, Christophe LEROY wrote:
> 
> 
> Le 19/01/2018 à 10:02, Aneesh Kumar K.V a écrit :
>>
>>
>> On 01/19/2018 02:14 PM, Christophe LEROY wrote:
>>>
>>>
>>> Le 19/01/2018 à 09:24, Aneesh Kumar K.V a écrit :
>>>> Christophe Leroy <christophe.leroy@c-s.fr> writes:
>>>>
>>>>> In preparation for the following patch which will fix an issue on
>>>>> the 8xx by re-using the 'slices', this patch enhances the
>>>>> 'slices' implementation to support 32 bits CPUs.
>>>>>
>>>>> On PPC32, the address space is limited to 4Gbytes, hence only the low
>>>>> slices will be used. As of today, the code uses
>>>>> SLICE_LOW_TOP (0x100000000ul) and compares it with addr to determine
>>>>> if addr refers to low or high space.
>>>>> On PPC32, such a (addr < SLICE_LOW_TOP) test is always false because
>>>>> 0x100000000ul degrades to 0. Therefore, the patch modifies
>>>>> SLICE_LOW_TOP to (0xfffffffful) and modifies the tests to
>>>>> (addr <= SLICE_LOW_TOP) which will then always be true on PPC32
>>>>> as addr has type 'unsigned long' while not modifying the PPC64
>>>>> behaviour.
>>>>>
>>>>> This patch moves "slices" functions prototypes from page64.h to page.h
>>>>>
>>>>> The high slices use bitmaps. As bitmap functions are not prepared to
>>>>> handling bitmaps of size 0, the bitmap_xxx() calls are wrapped into
>>>>> slice_bitmap_xxx() macros which will take care of the 0 nbits case.
>>>>>
>>>>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>>>>> ---
>>>>>   v2: First patch of v1 serie split in two parts ; added 
>>>>> slice_bitmap_xxx() macros.
>>>>>
>>>>>   arch/powerpc/include/asm/page.h      | 14 +++++++++
>>>>>   arch/powerpc/include/asm/page_32.h   | 19 ++++++++++++
>>>>>   arch/powerpc/include/asm/page_64.h   | 21 ++-----------
>>>>>   arch/powerpc/mm/hash_utils_64.c      |  2 +-
>>>>>   arch/powerpc/mm/mmu_context_nohash.c |  7 +++++
>>>>>   arch/powerpc/mm/slice.c              | 60 
>>>>> ++++++++++++++++++++++++------------
>>>>>   6 files changed, 83 insertions(+), 40 deletions(-)
>>>>>
>>>>> diff --git a/arch/powerpc/include/asm/page.h 
>>>>> b/arch/powerpc/include/asm/page.h
>>>>> index 8da5d4c1cab2..d0384f9db9eb 100644
>>>>> --- a/arch/powerpc/include/asm/page.h
>>>>> +++ b/arch/powerpc/include/asm/page.h
>>>>> @@ -342,6 +342,20 @@ typedef struct page *pgtable_t;
>>>>>   #endif
>>>>>   #endif
>>>>> +#ifdef CONFIG_PPC_MM_SLICES
>>>>> +struct mm_struct;
>>>>> +
>>>>> +unsigned long slice_get_unmapped_area(unsigned long addr, unsigned 
>>>>> long len,
>>>>> +                      unsigned long flags, unsigned int psize,
>>>>> +                      int topdown);
>>>>> +
>>>>> +unsigned int get_slice_psize(struct mm_struct *mm, unsigned long 
>>>>> addr);
>>>>> +
>>>>> +void slice_set_user_psize(struct mm_struct *mm, unsigned int psize);
>>>>> +void slice_set_range_psize(struct mm_struct *mm, unsigned long start,
>>>>> +               unsigned long len, unsigned int psize);
>>>>> +#endif
>>>>> +
>>>>
>>>> Should we do a slice.h ? the way we have other files? and then do
>>>
>>> Yes we could add a slice.h instead of using page.h for that, good idea.
>>>
>>>>
>>>> arch/powerpc/include/asm/book3s/64/slice.h that will carry
>>>> #define slice_bitmap_zero(dst, nbits) \
>>>>     do { if (nbits) bitmap_zero(dst, nbits); } while (0)
>>>> #define slice_bitmap_set(dst, pos, nbits) \
>>>> do { if (nbits) bitmap_set(dst, pos, nbits); } while (0)
>>>> #define slice_bitmap_copy(dst, src, nbits) \
>>>> do { if (nbits) bitmap_copy(dst, src, nbits); } while (0)
>>>> #define slice_bitmap_and(dst, src1, src2, nbits) \
>>>>     ({ (nbits) ? bitmap_and(dst, src1, src2, nbits) : 0; })
>>>> #define slice_bitmap_or(dst, src1, src2, nbits) \
>>>>     do { if (nbits) bitmap_or(dst, src1, src2, nbits); } while (0)
>>>> #define slice_bitmap_andnot(dst, src1, src2, nbits) \
>>>>     ({ (nbits) ? bitmap_andnot(dst, src1, src2, nbits) : 0; })
>>>> #define slice_bitmap_equal(src1, src2, nbits) \
>>>>     ({ (nbits) ? bitmap_equal(src1, src2, nbits) : 1; })
>>>> #define slice_bitmap_empty(src, nbits) \
>>>>     ({ (nbits) ? bitmap_empty(src, nbits) : 1; })
>>>>
>>>> This without that if(nbits) check and a proper static inline so that we
>>>> can do type checking.
>>>
>>> Is it really worth duplicating that just for eliminating the 'if 
>>> (nbits)' in one case ?
>>>
>>> Only in book3s/64 we will be able to eliminate that, for nohash/32 we 
>>> need to keep the test due to the difference between low and high slices.
>>
>> the other advantage is we move the SLICE_LOW_SHIFT to the right 
>> location. IMHO mm subystem is really complex with these really 
>> overloaded headers. If we can keep it  seperate we should with minimal 
>> code duplication?
> 
> For the constants I fully agree with your proposal and I will do it. I 
> was only questionning the benefit of moving the slice_bitmap_xxxx() 
> stuff, taking into account that the 'if (nbits)' test is already 
> eliminated by the compiler.
> 

That is compiler dependent as you are finding with the other patch where 
if (0) didn't get compiled out

-aneesh

^ permalink raw reply

* Re: [PATCH v2 1/5] powerpc/mm: Enhance 'slice' for supporting PPC32
From: Christophe LEROY @ 2018-01-19  9:07 UTC (permalink / raw)
  To: Aneesh Kumar K.V, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Scott Wood
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <b4d8f01b-9ee1-ec34-aa0d-5a353064438c@linux.vnet.ibm.com>



Le 19/01/2018 à 10:02, Aneesh Kumar K.V a écrit :
> 
> 
> On 01/19/2018 02:14 PM, Christophe LEROY wrote:
>>
>>
>> Le 19/01/2018 à 09:24, Aneesh Kumar K.V a écrit :
>>> Christophe Leroy <christophe.leroy@c-s.fr> writes:
>>>
>>>> In preparation for the following patch which will fix an issue on
>>>> the 8xx by re-using the 'slices', this patch enhances the
>>>> 'slices' implementation to support 32 bits CPUs.
>>>>
>>>> On PPC32, the address space is limited to 4Gbytes, hence only the low
>>>> slices will be used. As of today, the code uses
>>>> SLICE_LOW_TOP (0x100000000ul) and compares it with addr to determine
>>>> if addr refers to low or high space.
>>>> On PPC32, such a (addr < SLICE_LOW_TOP) test is always false because
>>>> 0x100000000ul degrades to 0. Therefore, the patch modifies
>>>> SLICE_LOW_TOP to (0xfffffffful) and modifies the tests to
>>>> (addr <= SLICE_LOW_TOP) which will then always be true on PPC32
>>>> as addr has type 'unsigned long' while not modifying the PPC64
>>>> behaviour.
>>>>
>>>> This patch moves "slices" functions prototypes from page64.h to page.h
>>>>
>>>> The high slices use bitmaps. As bitmap functions are not prepared to
>>>> handling bitmaps of size 0, the bitmap_xxx() calls are wrapped into
>>>> slice_bitmap_xxx() macros which will take care of the 0 nbits case.
>>>>
>>>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>>>> ---
>>>>   v2: First patch of v1 serie split in two parts ; added 
>>>> slice_bitmap_xxx() macros.
>>>>
>>>>   arch/powerpc/include/asm/page.h      | 14 +++++++++
>>>>   arch/powerpc/include/asm/page_32.h   | 19 ++++++++++++
>>>>   arch/powerpc/include/asm/page_64.h   | 21 ++-----------
>>>>   arch/powerpc/mm/hash_utils_64.c      |  2 +-
>>>>   arch/powerpc/mm/mmu_context_nohash.c |  7 +++++
>>>>   arch/powerpc/mm/slice.c              | 60 
>>>> ++++++++++++++++++++++++------------
>>>>   6 files changed, 83 insertions(+), 40 deletions(-)
>>>>
>>>> diff --git a/arch/powerpc/include/asm/page.h 
>>>> b/arch/powerpc/include/asm/page.h
>>>> index 8da5d4c1cab2..d0384f9db9eb 100644
>>>> --- a/arch/powerpc/include/asm/page.h
>>>> +++ b/arch/powerpc/include/asm/page.h
>>>> @@ -342,6 +342,20 @@ typedef struct page *pgtable_t;
>>>>   #endif
>>>>   #endif
>>>> +#ifdef CONFIG_PPC_MM_SLICES
>>>> +struct mm_struct;
>>>> +
>>>> +unsigned long slice_get_unmapped_area(unsigned long addr, unsigned 
>>>> long len,
>>>> +                      unsigned long flags, unsigned int psize,
>>>> +                      int topdown);
>>>> +
>>>> +unsigned int get_slice_psize(struct mm_struct *mm, unsigned long 
>>>> addr);
>>>> +
>>>> +void slice_set_user_psize(struct mm_struct *mm, unsigned int psize);
>>>> +void slice_set_range_psize(struct mm_struct *mm, unsigned long start,
>>>> +               unsigned long len, unsigned int psize);
>>>> +#endif
>>>> +
>>>
>>> Should we do a slice.h ? the way we have other files? and then do
>>
>> Yes we could add a slice.h instead of using page.h for that, good idea.
>>
>>>
>>> arch/powerpc/include/asm/book3s/64/slice.h that will carry
>>> #define slice_bitmap_zero(dst, nbits) \
>>>     do { if (nbits) bitmap_zero(dst, nbits); } while (0)
>>> #define slice_bitmap_set(dst, pos, nbits) \
>>> do { if (nbits) bitmap_set(dst, pos, nbits); } while (0)
>>> #define slice_bitmap_copy(dst, src, nbits) \
>>> do { if (nbits) bitmap_copy(dst, src, nbits); } while (0)
>>> #define slice_bitmap_and(dst, src1, src2, nbits) \
>>>     ({ (nbits) ? bitmap_and(dst, src1, src2, nbits) : 0; })
>>> #define slice_bitmap_or(dst, src1, src2, nbits) \
>>>     do { if (nbits) bitmap_or(dst, src1, src2, nbits); } while (0)
>>> #define slice_bitmap_andnot(dst, src1, src2, nbits) \
>>>     ({ (nbits) ? bitmap_andnot(dst, src1, src2, nbits) : 0; })
>>> #define slice_bitmap_equal(src1, src2, nbits) \
>>>     ({ (nbits) ? bitmap_equal(src1, src2, nbits) : 1; })
>>> #define slice_bitmap_empty(src, nbits) \
>>>     ({ (nbits) ? bitmap_empty(src, nbits) : 1; })
>>>
>>> This without that if(nbits) check and a proper static inline so that we
>>> can do type checking.
>>
>> Is it really worth duplicating that just for eliminating the 'if 
>> (nbits)' in one case ?
>>
>> Only in book3s/64 we will be able to eliminate that, for nohash/32 we 
>> need to keep the test due to the difference between low and high slices.
> 
> the other advantage is we move the SLICE_LOW_SHIFT to the right 
> location. IMHO mm subystem is really complex with these really 
> overloaded headers. If we can keep it  seperate we should with minimal 
> code duplication?

For the constants I fully agree with your proposal and I will do it. I 
was only questionning the benefit of moving the slice_bitmap_xxxx() 
stuff, taking into account that the 'if (nbits)' test is already 
eliminated by the compiler.

Christophe

>>
>> In any case, as the nbits we use in slice.c is a constant, the test is 
>> eliminated at compilation, so I can't see the benefit of making 
> 
> -aneesh

^ permalink raw reply

* Re: [PATCH v2 3/5] powerpc/mm: Allow more than 16 low slices
From: Aneesh Kumar K.V @ 2018-01-19  9:06 UTC (permalink / raw)
  To: Christophe LEROY, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Scott Wood
  Cc: linux-kernel, linuxppc-dev
In-Reply-To: <baf3a2db-3522-8419-0eda-ef62ad13d76e@c-s.fr>



On 01/19/2018 02:29 PM, Christophe LEROY wrote:
> 
> 
> Le 19/01/2018 à 09:30, Aneesh Kumar K.V a écrit :
>> Christophe Leroy <christophe.leroy@c-s.fr> writes:
>>
>>> While the implementation of the "slices" address space allows
>>> a significant amount of high slices, it limits the number of
>>> low slices to 16 due to the use of a single u64 low_slices_psize
>>> element in struct mm_context_t
>>>
>>> On the 8xx, the minimum slice size is the size of the area
>>> covered by a single PMD entry, ie 4M in 4K pages mode and 64M in
>>> 16K pages mode. This means we could have resp. up to 1024 and 64
>>> slices.
>>>
>>> In order to override this limitation, this patch switches the
>>> handling of low_slices to BITMAPs as done already for high_slices.
>>
>> Does it have a performance impact. When we switched high_slices
>> that was one of the question asked. Now with a topdown search we should
>> mostly be using the high_slices. But it will good to get numbers for
>> ppc64 for this change.
> 
> It should have almost no performance impact at all, because all bitmap 
> functions used a simplified way when the number of bits is small and 
> constant:
> 
> -    ret->low_slices = 0;
> +    slice_bitmap_zero(ret->low_slices, SLICE_NUM_LOW);
> 
> 
> static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
> {
>      if (small_const_nbits(nbits))
>          *dst = 0UL;
>      else {
>          unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
>          memset(dst, 0, len);
>      }
> }
> 
> 
> 
> -    dst->low_slices |= src->low_slices;
> +    slice_bitmap_or(dst->low_slices, dst->low_slices, src->low_slices,
> +            SLICE_NUM_LOW);
> 
> 
> static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
>              const unsigned long *src2, unsigned int nbits)
> {
>      if (small_const_nbits(nbits))
>          *dst = *src1 | *src2;
>      else
>          __bitmap_or(dst, src1, src2, nbits);
> }
> 
> 
>

may be capture that in commit message saying since we are 64 bit on 
ppc64 there is no impact there?

-aneesh

^ permalink raw reply

* Re: [PATCH v2 1/5] powerpc/mm: Enhance 'slice' for supporting PPC32
From: Aneesh Kumar K.V @ 2018-01-19  9:02 UTC (permalink / raw)
  To: Christophe LEROY, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Scott Wood
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <84dc1df4-db2f-be11-c1f3-5dddd1e44983@c-s.fr>



On 01/19/2018 02:14 PM, Christophe LEROY wrote:
> 
> 
> Le 19/01/2018 à 09:24, Aneesh Kumar K.V a écrit :
>> Christophe Leroy <christophe.leroy@c-s.fr> writes:
>>
>>> In preparation for the following patch which will fix an issue on
>>> the 8xx by re-using the 'slices', this patch enhances the
>>> 'slices' implementation to support 32 bits CPUs.
>>>
>>> On PPC32, the address space is limited to 4Gbytes, hence only the low
>>> slices will be used. As of today, the code uses
>>> SLICE_LOW_TOP (0x100000000ul) and compares it with addr to determine
>>> if addr refers to low or high space.
>>> On PPC32, such a (addr < SLICE_LOW_TOP) test is always false because
>>> 0x100000000ul degrades to 0. Therefore, the patch modifies
>>> SLICE_LOW_TOP to (0xfffffffful) and modifies the tests to
>>> (addr <= SLICE_LOW_TOP) which will then always be true on PPC32
>>> as addr has type 'unsigned long' while not modifying the PPC64
>>> behaviour.
>>>
>>> This patch moves "slices" functions prototypes from page64.h to page.h
>>>
>>> The high slices use bitmaps. As bitmap functions are not prepared to
>>> handling bitmaps of size 0, the bitmap_xxx() calls are wrapped into
>>> slice_bitmap_xxx() macros which will take care of the 0 nbits case.
>>>
>>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>>> ---
>>>   v2: First patch of v1 serie split in two parts ; added 
>>> slice_bitmap_xxx() macros.
>>>
>>>   arch/powerpc/include/asm/page.h      | 14 +++++++++
>>>   arch/powerpc/include/asm/page_32.h   | 19 ++++++++++++
>>>   arch/powerpc/include/asm/page_64.h   | 21 ++-----------
>>>   arch/powerpc/mm/hash_utils_64.c      |  2 +-
>>>   arch/powerpc/mm/mmu_context_nohash.c |  7 +++++
>>>   arch/powerpc/mm/slice.c              | 60 
>>> ++++++++++++++++++++++++------------
>>>   6 files changed, 83 insertions(+), 40 deletions(-)
>>>
>>> diff --git a/arch/powerpc/include/asm/page.h 
>>> b/arch/powerpc/include/asm/page.h
>>> index 8da5d4c1cab2..d0384f9db9eb 100644
>>> --- a/arch/powerpc/include/asm/page.h
>>> +++ b/arch/powerpc/include/asm/page.h
>>> @@ -342,6 +342,20 @@ typedef struct page *pgtable_t;
>>>   #endif
>>>   #endif
>>> +#ifdef CONFIG_PPC_MM_SLICES
>>> +struct mm_struct;
>>> +
>>> +unsigned long slice_get_unmapped_area(unsigned long addr, unsigned 
>>> long len,
>>> +                      unsigned long flags, unsigned int psize,
>>> +                      int topdown);
>>> +
>>> +unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr);
>>> +
>>> +void slice_set_user_psize(struct mm_struct *mm, unsigned int psize);
>>> +void slice_set_range_psize(struct mm_struct *mm, unsigned long start,
>>> +               unsigned long len, unsigned int psize);
>>> +#endif
>>> +
>>
>> Should we do a slice.h ? the way we have other files? and then do
> 
> Yes we could add a slice.h instead of using page.h for that, good idea.
> 
>>
>> arch/powerpc/include/asm/book3s/64/slice.h that will carry
>> #define slice_bitmap_zero(dst, nbits) \
>>     do { if (nbits) bitmap_zero(dst, nbits); } while (0)
>> #define slice_bitmap_set(dst, pos, nbits) \
>> do { if (nbits) bitmap_set(dst, pos, nbits); } while (0)
>> #define slice_bitmap_copy(dst, src, nbits) \
>> do { if (nbits) bitmap_copy(dst, src, nbits); } while (0)
>> #define slice_bitmap_and(dst, src1, src2, nbits) \
>>     ({ (nbits) ? bitmap_and(dst, src1, src2, nbits) : 0; })
>> #define slice_bitmap_or(dst, src1, src2, nbits) \
>>     do { if (nbits) bitmap_or(dst, src1, src2, nbits); } while (0)
>> #define slice_bitmap_andnot(dst, src1, src2, nbits) \
>>     ({ (nbits) ? bitmap_andnot(dst, src1, src2, nbits) : 0; })
>> #define slice_bitmap_equal(src1, src2, nbits) \
>>     ({ (nbits) ? bitmap_equal(src1, src2, nbits) : 1; })
>> #define slice_bitmap_empty(src, nbits) \
>>     ({ (nbits) ? bitmap_empty(src, nbits) : 1; })
>>
>> This without that if(nbits) check and a proper static inline so that we
>> can do type checking.
> 
> Is it really worth duplicating that just for eliminating the 'if 
> (nbits)' in one case ?
> 
> Only in book3s/64 we will be able to eliminate that, for nohash/32 we 
> need to keep the test due to the difference between low and high slices.

the other advantage is we move the SLICE_LOW_SHIFT to the right 
location. IMHO mm subystem is really complex with these really 
overloaded headers. If we can keep it  seperate we should with minimal 
code duplication?
> 
> In any case, as the nbits we use in slice.c is a constant, the test is 
> eliminated at compilation, so I can't see the benefit of making 

-aneesh

^ permalink raw reply

* Re: [PATCH v2 3/5] powerpc/mm: Allow more than 16 low slices
From: Christophe LEROY @ 2018-01-19  8:59 UTC (permalink / raw)
  To: Aneesh Kumar K.V, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Scott Wood
  Cc: linux-kernel, linuxppc-dev
In-Reply-To: <87po66z1w2.fsf@linux.vnet.ibm.com>



Le 19/01/2018 à 09:30, Aneesh Kumar K.V a écrit :
> Christophe Leroy <christophe.leroy@c-s.fr> writes:
> 
>> While the implementation of the "slices" address space allows
>> a significant amount of high slices, it limits the number of
>> low slices to 16 due to the use of a single u64 low_slices_psize
>> element in struct mm_context_t
>>
>> On the 8xx, the minimum slice size is the size of the area
>> covered by a single PMD entry, ie 4M in 4K pages mode and 64M in
>> 16K pages mode. This means we could have resp. up to 1024 and 64
>> slices.
>>
>> In order to override this limitation, this patch switches the
>> handling of low_slices to BITMAPs as done already for high_slices.
> 
> Does it have a performance impact. When we switched high_slices
> that was one of the question asked. Now with a topdown search we should
> mostly be using the high_slices. But it will good to get numbers for
> ppc64 for this change.

It should have almost no performance impact at all, because all bitmap 
functions used a simplified way when the number of bits is small and 
constant:

-	ret->low_slices = 0;
+	slice_bitmap_zero(ret->low_slices, SLICE_NUM_LOW);


static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
{
	if (small_const_nbits(nbits))
		*dst = 0UL;
	else {
		unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
		memset(dst, 0, len);
	}
}



-	dst->low_slices |= src->low_slices;
+	slice_bitmap_or(dst->low_slices, dst->low_slices, src->low_slices,
+			SLICE_NUM_LOW);


static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
			const unsigned long *src2, unsigned int nbits)
{
	if (small_const_nbits(nbits))
		*dst = *src1 | *src2;
	else
		__bitmap_or(dst, src1, src2, nbits);
}


> 
> 
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>> ---
>>   v2: Usign slice_bitmap_xxx() macros instead of bitmap_xxx() functions.
>>
>>   arch/powerpc/include/asm/book3s/64/mmu.h |   2 +-
>>   arch/powerpc/include/asm/mmu-8xx.h       |   2 +-
>>   arch/powerpc/include/asm/paca.h          |   2 +-
>>   arch/powerpc/kernel/paca.c               |   3 +-
>>   arch/powerpc/mm/hash_utils_64.c          |  13 ++--
>>   arch/powerpc/mm/slb_low.S                |   8 ++-
>>   arch/powerpc/mm/slice.c                  | 104 +++++++++++++++++--------------
>>   7 files changed, 74 insertions(+), 60 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h
>> index c9448e19847a..27e7e9732ea1 100644
>> --- a/arch/powerpc/include/asm/book3s/64/mmu.h
>> +++ b/arch/powerpc/include/asm/book3s/64/mmu.h
>> @@ -91,7 +91,7 @@ typedef struct {
>>   	struct npu_context *npu_context;
>>   
>>   #ifdef CONFIG_PPC_MM_SLICES
>> -	u64 low_slices_psize;	/* SLB page size encodings */
>> +	unsigned char low_slices_psize[8]; /* SLB page size encodings */
> 
> Can that 8 be a #define?

Sure

> 
> 
>>   	unsigned char high_slices_psize[SLICE_ARRAY_SIZE];
>>   	unsigned long slb_addr_limit;
>>   #else
> 
> -aneesh
> 

Christophe

^ permalink raw reply

* [PATCH] powerpc/64s: Fix ps3 build error due to tlbiel_all()
From: Michael Ellerman @ 2018-01-19  8:55 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: npiggin, sfr

The recent changes to TLB handling broke the PS3 build:

  arch/powerpc/include/asm/book3s/64/tlbflush.h:30: undefined reference to `.hash__tlbiel_all'

Fix it by adding an fallback version of tlbiel_all() for non-native
builds. It should never be called, due to checks in callers so it
calls BUG(). We should probably clean it up further but this will
suffice for now.

Fixes: d4748276ae14 ("powerpc/64s: Improve local TLB flush for boot and MCE on POWER9")
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/include/asm/book3s/64/tlbflush.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush.h b/arch/powerpc/include/asm/book3s/64/tlbflush.h
index 9befb4df235c..0cac17253513 100644
--- a/arch/powerpc/include/asm/book3s/64/tlbflush.h
+++ b/arch/powerpc/include/asm/book3s/64/tlbflush.h
@@ -14,6 +14,7 @@ enum {
 	TLB_INVAL_SCOPE_LPID = 1,	/* invalidate TLBs for current LPID */
 };
 
+#ifdef CONFIG_PPC_NATIVE
 static inline void tlbiel_all(void)
 {
 	/*
@@ -29,6 +30,9 @@ static inline void tlbiel_all(void)
 	else
 		hash__tlbiel_all(TLB_INVAL_SCOPE_GLOBAL);
 }
+#else
+static inline void tlbiel_all(void) { BUG(); };
+#endif
 
 static inline void tlbiel_all_lpid(bool radix)
 {
-- 
2.14.3

^ permalink raw reply related

* Re: [PATCH v2 2/5] powerpc/32: Fix hugepage allocation on 8xx at hint address
From: Christophe LEROY @ 2018-01-19  8:49 UTC (permalink / raw)
  To: Aneesh Kumar K.V, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Scott Wood
  Cc: linux-kernel, linuxppc-dev
In-Reply-To: <87shb2z22l.fsf@linux.vnet.ibm.com>



Le 19/01/2018 à 09:26, Aneesh Kumar K.V a écrit :
> Christophe Leroy <christophe.leroy@c-s.fr> writes:
> 
>> On the 8xx, the page size is set in the PMD entry and applies to
>> all pages of the page table pointed by the said PMD entry.
>>
>> When an app has some regular pages allocated (e.g. see below) and tries
>> to mmap() a huge page at a hint address covered by the same PMD entry,
>> the kernel accepts the hint allthough the 8xx cannot handle different
>> page sizes in the same PMD entry.
>>
>> 10000000-10001000 r-xp 00000000 00:0f 2597 /root/malloc
>> 10010000-10011000 rwxp 00000000 00:0f 2597 /root/malloc
>>
>> mmap(0x10080000, 524288, PROT_READ|PROT_WRITE,
>>       MAP_PRIVATE|MAP_ANONYMOUS|0x40000, -1, 0) = 0x10080000
>>
>> This results the app remaining forever in do_page_fault()/hugetlb_fault()
>> and when interrupting that app, we get the following warning:
>>
>> [162980.035629] WARNING: CPU: 0 PID: 2777 at arch/powerpc/mm/hugetlbpage.c:354 hugetlb_free_pgd_range+0xc8/0x1e4
>> [162980.035699] CPU: 0 PID: 2777 Comm: malloc Tainted: G W       4.14.6 #85
>> [162980.035744] task: c67e2c00 task.stack: c668e000
>> [162980.035783] NIP:  c000fe18 LR: c00e1eec CTR: c00f90c0
>> [162980.035830] REGS: c668fc20 TRAP: 0700   Tainted: G W        (4.14.6)
>> [162980.035854] MSR:  00029032 <EE,ME,IR,DR,RI>  CR: 24044224 XER: 20000000
>> [162980.036003]
>> [162980.036003] GPR00: c00e1eec c668fcd0 c67e2c00 00000010 c6869410 10080000 00000000 77fb4000
>> [162980.036003] GPR08: ffff0001 0683c001 00000000 ffffff80 44028228 10018a34 00004008 418004fc
>> [162980.036003] GPR16: c668e000 00040100 c668e000 c06c0000 c668fe78 c668e000 c6835ba0 c668fd48
>> [162980.036003] GPR24: 00000000 73ffffff 74000000 00000001 77fb4000 100fffff 10100000 10100000
>> [162980.036743] NIP [c000fe18] hugetlb_free_pgd_range+0xc8/0x1e4
>> [162980.036839] LR [c00e1eec] free_pgtables+0x12c/0x150
>> [162980.036861] Call Trace:
>> [162980.036939] [c668fcd0] [c00f0774] unlink_anon_vmas+0x1c4/0x214 (unreliable)
>> [162980.037040] [c668fd10] [c00e1eec] free_pgtables+0x12c/0x150
>> [162980.037118] [c668fd40] [c00eabac] exit_mmap+0xe8/0x1b4
>> [162980.037210] [c668fda0] [c0019710] mmput.part.9+0x20/0xd8
>> [162980.037301] [c668fdb0] [c001ecb0] do_exit+0x1f0/0x93c
>> [162980.037386] [c668fe00] [c001f478] do_group_exit+0x40/0xcc
>> [162980.037479] [c668fe10] [c002a76c] get_signal+0x47c/0x614
>> [162980.037570] [c668fe70] [c0007840] do_signal+0x54/0x244
>> [162980.037654] [c668ff30] [c0007ae8] do_notify_resume+0x34/0x88
>> [162980.037744] [c668ff40] [c000dae8] do_user_signal+0x74/0xc4
>> [162980.037781] Instruction dump:
>> [162980.037821] 7fdff378 81370000 54a3463a 80890020 7d24182e 7c841a14 712a0004 4082ff94
>> [162980.038014] 2f890000 419e0010 712a0ff0 408200e0 <0fe00000> 54a9000a 7f984840 419d0094
>> [162980.038216] ---[ end trace c0ceeca8e7a5800a ]---
>> [162980.038754] BUG: non-zero nr_ptes on freeing mm: 1
>> [162985.363322] BUG: non-zero nr_ptes on freeing mm: -1
>>
>> In order to fix this, this patch uses the address space "slices"
>> implemented for BOOK3S/64 and enhanced to support PPC32 by the
>> preceding patch.
>>
>> This patch modifies the context.id on the 8xx to be in the range
>> [1:16] instead of [0:15] in order to identify context.id == 0 as
>> not initialised contexts as done on BOOK3S
>>
>> This patch activates CONFIG_PPC_MM_SLICES when CONFIG_HUGETLB_PAGE is
>> selected for the 8xx
>>
>> Alltough we could in theory have as many slices as PMD entries, the
>> current slices implementation limits the number of low slices to 16.
>> This limitation is not preventing us to fix the initial issue allthough
>> it is suboptimal. It will be cured in a subsequent patch.
>>
>> Fixes: 4b91428699477 ("powerpc/8xx: Implement support of hugepages")
>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>> ---
>>   v2: First patch of v1 serie split in two parts
>>
>>   arch/powerpc/include/asm/mmu-8xx.h     | 6 ++++++
>>   arch/powerpc/kernel/setup-common.c     | 2 ++
>>   arch/powerpc/mm/8xx_mmu.c              | 2 +-
>>   arch/powerpc/mm/hugetlbpage.c          | 2 ++
>>   arch/powerpc/mm/mmu_context_nohash.c   | 4 ++--
>>   arch/powerpc/mm/slice.c                | 2 ++
>>   arch/powerpc/platforms/Kconfig.cputype | 1 +
>>   7 files changed, 16 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h
>> index 5bb3dbede41a..5f89b6010453 100644
>> --- a/arch/powerpc/include/asm/mmu-8xx.h
>> +++ b/arch/powerpc/include/asm/mmu-8xx.h
>> @@ -169,6 +169,12 @@ typedef struct {
>>   	unsigned int id;
>>   	unsigned int active;
>>   	unsigned long vdso_base;
>> +#ifdef CONFIG_PPC_MM_SLICES
>> +	u16 user_psize;		/* page size index */
>> +	u64 low_slices_psize;	/* page size encodings */
>> +	unsigned char high_slices_psize[0];
>> +	unsigned long slb_addr_limit;
>> +#endif
>>   } mm_context_t;
>>   
>>   #define PHYS_IMMR_BASE (mfspr(SPRN_IMMR) & 0xfff80000)
>> diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
>> index 9d213542a48b..67075a1cff36 100644
>> --- a/arch/powerpc/kernel/setup-common.c
>> +++ b/arch/powerpc/kernel/setup-common.c
>> @@ -927,6 +927,8 @@ void __init setup_arch(char **cmdline_p)
>>   #ifdef CONFIG_PPC64
>>   	if (!radix_enabled())
>>   		init_mm.context.slb_addr_limit = DEFAULT_MAP_WINDOW_USER64;
>> +#elif defined(CONFIG_PPC_8xx)
>> +	init_mm.context.slb_addr_limit = DEFAULT_MAP_WINDOW;
>>   #else
>>   #error	"context.addr_limit not initialized."
>>   #endif
>> diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c
>> index f29212e40f40..0be77709446c 100644
>> --- a/arch/powerpc/mm/8xx_mmu.c
>> +++ b/arch/powerpc/mm/8xx_mmu.c
>> @@ -192,7 +192,7 @@ void set_context(unsigned long id, pgd_t *pgd)
>>   	mtspr(SPRN_M_TW, __pa(pgd) - offset);
>>   
>>   	/* Update context */
>> -	mtspr(SPRN_M_CASID, id);
>> +	mtspr(SPRN_M_CASID, id - 1);
>>   	/* sync */
>>   	mb();
>>   }
>> diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
>> index a9b9083c5e49..79e1378ee303 100644
>> --- a/arch/powerpc/mm/hugetlbpage.c
>> +++ b/arch/powerpc/mm/hugetlbpage.c
>> @@ -553,9 +553,11 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
>>   	struct hstate *hstate = hstate_file(file);
>>   	int mmu_psize = shift_to_mmu_psize(huge_page_shift(hstate));
>>   
>> +#ifdef CONFIG_PPC_RADIX_MMU
>>   	if (radix_enabled())
>>   		return radix__hugetlb_get_unmapped_area(file, addr, len,
>>   						       pgoff, flags);
>> +#endif
> 
> if (0) didn't remove the following radix__hugetlb_get_unmapped_area for
> you?
> 

No

   CC      arch/powerpc/mm/hugetlbpage.o
arch/powerpc/mm/hugetlbpage.c: In function ‘hugetlb_get_unmapped_area’:
arch/powerpc/mm/hugetlbpage.c:558:10: error: implicit declaration of 
function ‘radix__hugetlb_get_unmapped_area’ 
[-Werror=implicit-function-declaration]
    return radix__hugetlb_get_unmapped_area(file, addr, len,
           ^
cc1: all warnings being treated as errors
make[1]: *** [arch/powerpc/mm/hugetlbpage.o] Error 1


Christophe

> 
>>   	return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1);
>>   }
>>   #endif
>> diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
>> index 42e02f5b6660..c1e1bf186871 100644
>> --- a/arch/powerpc/mm/mmu_context_nohash.c
>> +++ b/arch/powerpc/mm/mmu_context_nohash.c
>> @@ -435,8 +435,8 @@ void __init mmu_context_init(void)
>>   	 *      -- BenH
>>   	 */
>>   	if (mmu_has_feature(MMU_FTR_TYPE_8xx)) {
>> -		first_context = 0;
>> -		last_context = 15;
>> +		first_context = 1;
>> +		last_context = 16;
>>   		no_selective_tlbil = true;
>>   	} else if (mmu_has_feature(MMU_FTR_TYPE_47x)) {
>>   		first_context = 1;
>> diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
>> index 3f35a93afe13..b617acf35836 100644
>> --- a/arch/powerpc/mm/slice.c
>> +++ b/arch/powerpc/mm/slice.c
>> @@ -206,6 +206,7 @@ static int slice_check_fit(struct mm_struct *mm,
>>   
>>   static void slice_flush_segments(void *parm)
>>   {
>> +#ifdef CONFIG_PPC_BOOK3S_64
>>   	struct mm_struct *mm = parm;
>>   	unsigned long flags;
>>   
>> @@ -217,6 +218,7 @@ static void slice_flush_segments(void *parm)
>>   	local_irq_save(flags);
>>   	slb_flush_and_rebolt();
>>   	local_irq_restore(flags);
>> +#endif
>>   }
>>   
>>   static void slice_convert(struct mm_struct *mm, struct slice_mask mask, int psize)
>> diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
>> index ae07470fde3c..73a7ea333e9e 100644
>> --- a/arch/powerpc/platforms/Kconfig.cputype
>> +++ b/arch/powerpc/platforms/Kconfig.cputype
>> @@ -334,6 +334,7 @@ config PPC_BOOK3E_MMU
>>   config PPC_MM_SLICES
>>   	bool
>>   	default y if PPC_BOOK3S_64
>> +	default y if PPC_8xx && HUGETLB_PAGE
>>   	default n
>>   
>>   config PPC_HAVE_PMU_SUPPORT
>> -- 
>> 2.13.3

^ permalink raw reply

* Re: [PATCH v2 1/5] powerpc/mm: Enhance 'slice' for supporting PPC32
From: Christophe LEROY @ 2018-01-19  8:44 UTC (permalink / raw)
  To: Aneesh Kumar K.V, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Scott Wood
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <87vafyz265.fsf@linux.vnet.ibm.com>



Le 19/01/2018 à 09:24, Aneesh Kumar K.V a écrit :
> Christophe Leroy <christophe.leroy@c-s.fr> writes:
> 
>> In preparation for the following patch which will fix an issue on
>> the 8xx by re-using the 'slices', this patch enhances the
>> 'slices' implementation to support 32 bits CPUs.
>>
>> On PPC32, the address space is limited to 4Gbytes, hence only the low
>> slices will be used. As of today, the code uses
>> SLICE_LOW_TOP (0x100000000ul) and compares it with addr to determine
>> if addr refers to low or high space.
>> On PPC32, such a (addr < SLICE_LOW_TOP) test is always false because
>> 0x100000000ul degrades to 0. Therefore, the patch modifies
>> SLICE_LOW_TOP to (0xfffffffful) and modifies the tests to
>> (addr <= SLICE_LOW_TOP) which will then always be true on PPC32
>> as addr has type 'unsigned long' while not modifying the PPC64
>> behaviour.
>>
>> This patch moves "slices" functions prototypes from page64.h to page.h
>>
>> The high slices use bitmaps. As bitmap functions are not prepared to
>> handling bitmaps of size 0, the bitmap_xxx() calls are wrapped into
>> slice_bitmap_xxx() macros which will take care of the 0 nbits case.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>> ---
>>   v2: First patch of v1 serie split in two parts ; added slice_bitmap_xxx() macros.
>>
>>   arch/powerpc/include/asm/page.h      | 14 +++++++++
>>   arch/powerpc/include/asm/page_32.h   | 19 ++++++++++++
>>   arch/powerpc/include/asm/page_64.h   | 21 ++-----------
>>   arch/powerpc/mm/hash_utils_64.c      |  2 +-
>>   arch/powerpc/mm/mmu_context_nohash.c |  7 +++++
>>   arch/powerpc/mm/slice.c              | 60 ++++++++++++++++++++++++------------
>>   6 files changed, 83 insertions(+), 40 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
>> index 8da5d4c1cab2..d0384f9db9eb 100644
>> --- a/arch/powerpc/include/asm/page.h
>> +++ b/arch/powerpc/include/asm/page.h
>> @@ -342,6 +342,20 @@ typedef struct page *pgtable_t;
>>   #endif
>>   #endif
>>   
>> +#ifdef CONFIG_PPC_MM_SLICES
>> +struct mm_struct;
>> +
>> +unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
>> +				      unsigned long flags, unsigned int psize,
>> +				      int topdown);
>> +
>> +unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr);
>> +
>> +void slice_set_user_psize(struct mm_struct *mm, unsigned int psize);
>> +void slice_set_range_psize(struct mm_struct *mm, unsigned long start,
>> +			   unsigned long len, unsigned int psize);
>> +#endif
>> +
> 
> Should we do a slice.h ? the way we have other files? and then do

Yes we could add a slice.h instead of using page.h for that, good idea.

> 
> arch/powerpc/include/asm/book3s/64/slice.h that will carry
> #define slice_bitmap_zero(dst, nbits) \
> 	do { if (nbits) bitmap_zero(dst, nbits); } while (0)
> #define slice_bitmap_set(dst, pos, nbits) \
> do { if (nbits) bitmap_set(dst, pos, nbits); } while (0)
> #define slice_bitmap_copy(dst, src, nbits) \
> do { if (nbits) bitmap_copy(dst, src, nbits); } while (0)
> #define slice_bitmap_and(dst, src1, src2, nbits) \
> 	({ (nbits) ? bitmap_and(dst, src1, src2, nbits) : 0; })
> #define slice_bitmap_or(dst, src1, src2, nbits) \
> 	do { if (nbits) bitmap_or(dst, src1, src2, nbits); } while (0)
> #define slice_bitmap_andnot(dst, src1, src2, nbits) \
> 	({ (nbits) ? bitmap_andnot(dst, src1, src2, nbits) : 0; })
> #define slice_bitmap_equal(src1, src2, nbits) \
> 	({ (nbits) ? bitmap_equal(src1, src2, nbits) : 1; })
> #define slice_bitmap_empty(src, nbits) \
> 	({ (nbits) ? bitmap_empty(src, nbits) : 1; })
> 
> This without that if(nbits) check and a proper static inline so that we
> can do type checking.

Is it really worth duplicating that just for eliminating the 'if 
(nbits)' in one case ?

Only in book3s/64 we will be able to eliminate that, for nohash/32 we 
need to keep the test due to the difference between low and high slices.

In any case, as the nbits we use in slice.c is a constant, the test is 
eliminated at compilation, so I can't see the benefit of making 
different slice_bitmap_xxxx() based on platform.

Christophe

> 
> also related definitions for
> #define SLICE_LOW_SHIFT		28
> #define SLICE_HIGH_SHIFT	0
> 
> #define SLICE_LOW_TOP		(0xfffffffful)
> #define SLICE_NUM_LOW		((SLICE_LOW_TOP >> SLICE_LOW_SHIFT) + 1)
> +#define SLICE_NUM_HIGH		0ul
> 
> Common stuff between 64 and 32 can got to
> arch/powerpc/include/asm/slice.h ?
> 
> It also gives an indication of which 32 bit version we are looking at
> here. IIUC 8xx will got to arch/powerpc/include/asm/nohash/32/slice.h?
> 
>>   #include <asm-generic/memory_model.h>
>>   #endif /* __ASSEMBLY__ */
>>   
>> diff --git a/arch/powerpc/include/asm/page_32.h b/arch/powerpc/include/asm/page_32.h
>> index 5c378e9b78c8..f7d1bd1183c8 100644
>> --- a/arch/powerpc/include/asm/page_32.h
>> +++ b/arch/powerpc/include/asm/page_32.h
>> @@ -60,4 +60,23 @@ extern void copy_page(void *to, void *from);
>>   
>>   #endif /* __ASSEMBLY__ */
>>   
>> +#ifdef CONFIG_PPC_MM_SLICES
>> +
>> +#define SLICE_LOW_SHIFT		28
>> +#define SLICE_HIGH_SHIFT	0
>> +
>> +#define SLICE_LOW_TOP		(0xfffffffful)
>> +#define SLICE_NUM_LOW		((SLICE_LOW_TOP >> SLICE_LOW_SHIFT) + 1)
>> +#define SLICE_NUM_HIGH		0ul
>> +
>> +#define GET_LOW_SLICE_INDEX(addr)	((addr) >> SLICE_LOW_SHIFT)
>> +#define GET_HIGH_SLICE_INDEX(addr)	(addr & 0)
>> +
>> +#ifdef CONFIG_HUGETLB_PAGE
>> +#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
>> +#endif
>> +#define HAVE_ARCH_UNMAPPED_AREA
>> +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
>> +
>> +#endif
>>   #endif /* _ASM_POWERPC_PAGE_32_H */
>> diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h
>> index 56234c6fcd61..a7baef5bbe5f 100644
>> --- a/arch/powerpc/include/asm/page_64.h
>> +++ b/arch/powerpc/include/asm/page_64.h
>> @@ -91,30 +91,13 @@ extern u64 ppc64_pft_size;
>>   #define SLICE_LOW_SHIFT		28
>>   #define SLICE_HIGH_SHIFT	40
>>   
>> -#define SLICE_LOW_TOP		(0x100000000ul)
>> -#define SLICE_NUM_LOW		(SLICE_LOW_TOP >> SLICE_LOW_SHIFT)
>> +#define SLICE_LOW_TOP		(0xfffffffful)
>> +#define SLICE_NUM_LOW		((SLICE_LOW_TOP >> SLICE_LOW_SHIFT) + 1)
>>   #define SLICE_NUM_HIGH		(H_PGTABLE_RANGE >> SLICE_HIGH_SHIFT)
>>   
>>   #define GET_LOW_SLICE_INDEX(addr)	((addr) >> SLICE_LOW_SHIFT)
>>   #define GET_HIGH_SLICE_INDEX(addr)	((addr) >> SLICE_HIGH_SHIFT)
>>   
>> -#ifndef __ASSEMBLY__
>> -struct mm_struct;
>> -
>> -extern unsigned long slice_get_unmapped_area(unsigned long addr,
>> -					     unsigned long len,
>> -					     unsigned long flags,
>> -					     unsigned int psize,
>> -					     int topdown);
>> -
>> -extern unsigned int get_slice_psize(struct mm_struct *mm,
>> -				    unsigned long addr);
>> -
>> -extern void slice_set_user_psize(struct mm_struct *mm, unsigned int psize);
>> -extern void slice_set_range_psize(struct mm_struct *mm, unsigned long start,
>> -				  unsigned long len, unsigned int psize);
>> -
>> -#endif /* __ASSEMBLY__ */
>>   #else
>>   #define slice_init()
>>   #ifdef CONFIG_PPC_BOOK3S_64
>> diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
>> index 655a5a9a183d..3266b3326088 100644
>> --- a/arch/powerpc/mm/hash_utils_64.c
>> +++ b/arch/powerpc/mm/hash_utils_64.c
>> @@ -1101,7 +1101,7 @@ static unsigned int get_paca_psize(unsigned long addr)
>>   	unsigned char *hpsizes;
>>   	unsigned long index, mask_index;
>>   
>> -	if (addr < SLICE_LOW_TOP) {
>> +	if (addr <= SLICE_LOW_TOP) {
>>   		lpsizes = get_paca()->mm_ctx_low_slices_psize;
>>   		index = GET_LOW_SLICE_INDEX(addr);
>>   		return (lpsizes >> (index * 4)) & 0xF;
>> diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
>> index 4554d6527682..42e02f5b6660 100644
>> --- a/arch/powerpc/mm/mmu_context_nohash.c
>> +++ b/arch/powerpc/mm/mmu_context_nohash.c
>> @@ -331,6 +331,13 @@ int init_new_context(struct task_struct *t, struct mm_struct *mm)
>>   {
>>   	pr_hard("initing context for mm @%p\n", mm);
>>   
>> +#ifdef CONFIG_PPC_MM_SLICES
>> +	if (!mm->context.slb_addr_limit)
>> +		mm->context.slb_addr_limit = DEFAULT_MAP_WINDOW;
>> +	if (!mm->context.id)
>> +		slice_set_user_psize(mm, mmu_virtual_psize);
>> +#endif
>> +
>>   	mm->context.id = MMU_NO_CONTEXT;
>>   	mm->context.active = 0;
>>   	return 0;
>> diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
>> index 23ec2c5e3b78..3f35a93afe13 100644
>> --- a/arch/powerpc/mm/slice.c
>> +++ b/arch/powerpc/mm/slice.c
>> @@ -67,16 +67,33 @@ static void slice_print_mask(const char *label, struct slice_mask mask) {}
>>   
>>   #endif
>>   
>> +#define slice_bitmap_zero(dst, nbits) \
>> +	do { if (nbits) bitmap_zero(dst, nbits); } while (0)
>> +#define slice_bitmap_set(dst, pos, nbits) \
>> +	do { if (nbits) bitmap_set(dst, pos, nbits); } while (0)
>> +#define slice_bitmap_copy(dst, src, nbits) \
>> +	do { if (nbits) bitmap_copy(dst, src, nbits); } while (0)
>> +#define slice_bitmap_and(dst, src1, src2, nbits) \
>> +	({ (nbits) ? bitmap_and(dst, src1, src2, nbits) : 0; })
>> +#define slice_bitmap_or(dst, src1, src2, nbits) \
>> +	do { if (nbits) bitmap_or(dst, src1, src2, nbits); } while (0)
>> +#define slice_bitmap_andnot(dst, src1, src2, nbits) \
>> +	({ (nbits) ? bitmap_andnot(dst, src1, src2, nbits) : 0; })
>> +#define slice_bitmap_equal(src1, src2, nbits) \
>> +	({ (nbits) ? bitmap_equal(src1, src2, nbits) : 1; })
>> +#define slice_bitmap_empty(src, nbits) \
>> +	({ (nbits) ? bitmap_empty(src, nbits) : 1; })
>> +
>>   static void slice_range_to_mask(unsigned long start, unsigned long len,
>>   				struct slice_mask *ret)
>>   {
>>   	unsigned long end = start + len - 1;
>>   
>>   	ret->low_slices = 0;
>> -	bitmap_zero(ret->high_slices, SLICE_NUM_HIGH);
>> +	slice_bitmap_zero(ret->high_slices, SLICE_NUM_HIGH);
>>   
>> -	if (start < SLICE_LOW_TOP) {
>> -		unsigned long mend = min(end, (SLICE_LOW_TOP - 1));
>> +	if (start <= SLICE_LOW_TOP) {
>> +		unsigned long mend = min(end, SLICE_LOW_TOP);
>>   
>>   		ret->low_slices = (1u << (GET_LOW_SLICE_INDEX(mend) + 1))
>>   			- (1u << GET_LOW_SLICE_INDEX(start));
>> @@ -87,7 +104,7 @@ static void slice_range_to_mask(unsigned long start, unsigned long len,
>>   		unsigned long align_end = ALIGN(end, (1UL << SLICE_HIGH_SHIFT));
>>   		unsigned long count = GET_HIGH_SLICE_INDEX(align_end) - start_index;
>>   
>> -		bitmap_set(ret->high_slices, start_index, count);
>> +		slice_bitmap_set(ret->high_slices, start_index, count);
>>   	}
>>   }
>>   
>> @@ -117,7 +134,7 @@ static int slice_high_has_vma(struct mm_struct *mm, unsigned long slice)
>>   	 * of the high or low area bitmaps, the first high area starts
>>   	 * at 4GB, not 0 */
>>   	if (start == 0)
>> -		start = SLICE_LOW_TOP;
>> +		start = SLICE_LOW_TOP + 1;
>>   
>>   	return !slice_area_is_free(mm, start, end - start);
>>   }
>> @@ -128,7 +145,7 @@ static void slice_mask_for_free(struct mm_struct *mm, struct slice_mask *ret,
>>   	unsigned long i;
>>   
>>   	ret->low_slices = 0;
>> -	bitmap_zero(ret->high_slices, SLICE_NUM_HIGH);
>> +	slice_bitmap_zero(ret->high_slices, SLICE_NUM_HIGH);
>>   
>>   	for (i = 0; i < SLICE_NUM_LOW; i++)
>>   		if (!slice_low_has_vma(mm, i))
>> @@ -151,7 +168,7 @@ static void slice_mask_for_size(struct mm_struct *mm, int psize, struct slice_ma
>>   	u64 lpsizes;
>>   
>>   	ret->low_slices = 0;
>> -	bitmap_zero(ret->high_slices, SLICE_NUM_HIGH);
>> +	slice_bitmap_zero(ret->high_slices, SLICE_NUM_HIGH);
>>   
>>   	lpsizes = mm->context.low_slices_psize;
>>   	for (i = 0; i < SLICE_NUM_LOW; i++)
>> @@ -180,11 +197,11 @@ static int slice_check_fit(struct mm_struct *mm,
>>   	 */
>>   	unsigned long slice_count = GET_HIGH_SLICE_INDEX(mm->context.slb_addr_limit);
>>   
>> -	bitmap_and(result, mask.high_slices,
>> -		   available.high_slices, slice_count);
>> +	slice_bitmap_and(result, mask.high_slices,
>> +			 available.high_slices, slice_count);
>>   
>>   	return (mask.low_slices & available.low_slices) == mask.low_slices &&
>> -		bitmap_equal(result, mask.high_slices, slice_count);
>> +		slice_bitmap_equal(result, mask.high_slices, slice_count));
>>   }
>>   
>>   static void slice_flush_segments(void *parm)
>> @@ -259,7 +276,7 @@ static bool slice_scan_available(unsigned long addr,
>>   				 unsigned long *boundary_addr)
>>   {
>>   	unsigned long slice;
>> -	if (addr < SLICE_LOW_TOP) {
>> +	if (addr <= SLICE_LOW_TOP) {
>>   		slice = GET_LOW_SLICE_INDEX(addr);
>>   		*boundary_addr = (slice + end) << SLICE_LOW_SHIFT;
>>   		return !!(available.low_slices & (1u << slice));
>> @@ -391,8 +408,9 @@ static inline void slice_or_mask(struct slice_mask *dst, struct slice_mask *src)
>>   	DECLARE_BITMAP(result, SLICE_NUM_HIGH);
>>   
>>   	dst->low_slices |= src->low_slices;
>> -	bitmap_or(result, dst->high_slices, src->high_slices, SLICE_NUM_HIGH);
>> -	bitmap_copy(dst->high_slices, result, SLICE_NUM_HIGH);
>> +	slice_bitmap_or(result, dst->high_slices, src->high_slices,
>> +			SLICE_NUM_HIGH);
>> +	slice_bitmap_copy(dst->high_slices, result, SLICE_NUM_HIGH);
>>   }
>>   
>>   static inline void slice_andnot_mask(struct slice_mask *dst, struct slice_mask *src)
>> @@ -401,8 +419,9 @@ static inline void slice_andnot_mask(struct slice_mask *dst, struct slice_mask *
>>   
>>   	dst->low_slices &= ~src->low_slices;
>>   
>> -	bitmap_andnot(result, dst->high_slices, src->high_slices, SLICE_NUM_HIGH);
>> -	bitmap_copy(dst->high_slices, result, SLICE_NUM_HIGH);
>> +	slice_bitmap_andnot(result, dst->high_slices, src->high_slices,
>> +			    SLICE_NUM_HIGH);
>> +	slice_bitmap_copy(dst->high_slices, result, SLICE_NUM_HIGH);
>>   }
>>   
>>   #ifdef CONFIG_PPC_64K_PAGES
>> @@ -450,14 +469,14 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
>>   	 * init different masks
>>   	 */
>>   	mask.low_slices = 0;
>> -	bitmap_zero(mask.high_slices, SLICE_NUM_HIGH);
>> +	slice_bitmap_zero(mask.high_slices, SLICE_NUM_HIGH);
>>   
>>   	/* silence stupid warning */;
>>   	potential_mask.low_slices = 0;
>> -	bitmap_zero(potential_mask.high_slices, SLICE_NUM_HIGH);
>> +	slice_bitmap_zero(potential_mask.high_slices, SLICE_NUM_HIGH);
>>   
>>   	compat_mask.low_slices = 0;
>> -	bitmap_zero(compat_mask.high_slices, SLICE_NUM_HIGH);
>> +	slice_bitmap_zero(compat_mask.high_slices, SLICE_NUM_HIGH);
>>   
>>   	/* Sanity checks */
>>   	BUG_ON(mm->task_size == 0);
>> @@ -595,7 +614,8 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
>>    convert:
>>   	slice_andnot_mask(&mask, &good_mask);
>>   	slice_andnot_mask(&mask, &compat_mask);
>> -	if (mask.low_slices || !bitmap_empty(mask.high_slices, SLICE_NUM_HIGH)) {
>> +	if (mask.low_slices ||
>> +	    !slice_bitmap_empty(mask.high_slices, SLICE_NUM_HIGH)) {
>>   		slice_convert(mm, mask, psize);
>>   		if (psize > MMU_PAGE_BASE)
>>   			on_each_cpu(slice_flush_segments, mm, 1);
>> @@ -640,7 +660,7 @@ unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr)
>>   		return MMU_PAGE_4K;
>>   #endif
>>   	}
>> -	if (addr < SLICE_LOW_TOP) {
>> +	if (addr <= SLICE_LOW_TOP) {
>>   		u64 lpsizes;
>>   		lpsizes = mm->context.low_slices_psize;
>>   		index = GET_LOW_SLICE_INDEX(addr);
>> -- 
>> 2.13.3

^ permalink raw reply

* Re: [PATCH v2 3/5] powerpc/mm: Allow more than 16 low slices
From: Aneesh Kumar K.V @ 2018-01-19  8:30 UTC (permalink / raw)
  To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Scott Wood
  Cc: linux-kernel, linuxppc-dev
In-Reply-To: <1c9752ac98fd3278ef448e2553053c287af42b3f.1516179904.git.christophe.leroy@c-s.fr>

Christophe Leroy <christophe.leroy@c-s.fr> writes:

> While the implementation of the "slices" address space allows
> a significant amount of high slices, it limits the number of
> low slices to 16 due to the use of a single u64 low_slices_psize
> element in struct mm_context_t
>
> On the 8xx, the minimum slice size is the size of the area
> covered by a single PMD entry, ie 4M in 4K pages mode and 64M in
> 16K pages mode. This means we could have resp. up to 1024 and 64
> slices.
>
> In order to override this limitation, this patch switches the
> handling of low_slices to BITMAPs as done already for high_slices.

Does it have a performance impact. When we switched high_slices
that was one of the question asked. Now with a topdown search we should
mostly be using the high_slices. But it will good to get numbers for
ppc64 for this change.


>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> ---
>  v2: Usign slice_bitmap_xxx() macros instead of bitmap_xxx() functions.
>
>  arch/powerpc/include/asm/book3s/64/mmu.h |   2 +-
>  arch/powerpc/include/asm/mmu-8xx.h       |   2 +-
>  arch/powerpc/include/asm/paca.h          |   2 +-
>  arch/powerpc/kernel/paca.c               |   3 +-
>  arch/powerpc/mm/hash_utils_64.c          |  13 ++--
>  arch/powerpc/mm/slb_low.S                |   8 ++-
>  arch/powerpc/mm/slice.c                  | 104 +++++++++++++++++--------------
>  7 files changed, 74 insertions(+), 60 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h
> index c9448e19847a..27e7e9732ea1 100644
> --- a/arch/powerpc/include/asm/book3s/64/mmu.h
> +++ b/arch/powerpc/include/asm/book3s/64/mmu.h
> @@ -91,7 +91,7 @@ typedef struct {
>  	struct npu_context *npu_context;
>  
>  #ifdef CONFIG_PPC_MM_SLICES
> -	u64 low_slices_psize;	/* SLB page size encodings */
> +	unsigned char low_slices_psize[8]; /* SLB page size encodings */

Can that 8 be a #define?


>  	unsigned char high_slices_psize[SLICE_ARRAY_SIZE];
>  	unsigned long slb_addr_limit;
>  #else

-aneesh

^ permalink raw reply

* Re: [PATCH v2 2/5] powerpc/32: Fix hugepage allocation on 8xx at hint address
From: Aneesh Kumar K.V @ 2018-01-19  8:26 UTC (permalink / raw)
  To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Scott Wood
  Cc: linux-kernel, linuxppc-dev
In-Reply-To: <ed0e31af563aa34045b43a20d0668650e8a7bb7a.1516179904.git.christophe.leroy@c-s.fr>

Christophe Leroy <christophe.leroy@c-s.fr> writes:

> On the 8xx, the page size is set in the PMD entry and applies to
> all pages of the page table pointed by the said PMD entry.
>
> When an app has some regular pages allocated (e.g. see below) and tries
> to mmap() a huge page at a hint address covered by the same PMD entry,
> the kernel accepts the hint allthough the 8xx cannot handle different
> page sizes in the same PMD entry.
>
> 10000000-10001000 r-xp 00000000 00:0f 2597 /root/malloc
> 10010000-10011000 rwxp 00000000 00:0f 2597 /root/malloc
>
> mmap(0x10080000, 524288, PROT_READ|PROT_WRITE,
>      MAP_PRIVATE|MAP_ANONYMOUS|0x40000, -1, 0) = 0x10080000
>
> This results the app remaining forever in do_page_fault()/hugetlb_fault()
> and when interrupting that app, we get the following warning:
>
> [162980.035629] WARNING: CPU: 0 PID: 2777 at arch/powerpc/mm/hugetlbpage.c:354 hugetlb_free_pgd_range+0xc8/0x1e4
> [162980.035699] CPU: 0 PID: 2777 Comm: malloc Tainted: G W       4.14.6 #85
> [162980.035744] task: c67e2c00 task.stack: c668e000
> [162980.035783] NIP:  c000fe18 LR: c00e1eec CTR: c00f90c0
> [162980.035830] REGS: c668fc20 TRAP: 0700   Tainted: G W        (4.14.6)
> [162980.035854] MSR:  00029032 <EE,ME,IR,DR,RI>  CR: 24044224 XER: 20000000
> [162980.036003]
> [162980.036003] GPR00: c00e1eec c668fcd0 c67e2c00 00000010 c6869410 10080000 00000000 77fb4000
> [162980.036003] GPR08: ffff0001 0683c001 00000000 ffffff80 44028228 10018a34 00004008 418004fc
> [162980.036003] GPR16: c668e000 00040100 c668e000 c06c0000 c668fe78 c668e000 c6835ba0 c668fd48
> [162980.036003] GPR24: 00000000 73ffffff 74000000 00000001 77fb4000 100fffff 10100000 10100000
> [162980.036743] NIP [c000fe18] hugetlb_free_pgd_range+0xc8/0x1e4
> [162980.036839] LR [c00e1eec] free_pgtables+0x12c/0x150
> [162980.036861] Call Trace:
> [162980.036939] [c668fcd0] [c00f0774] unlink_anon_vmas+0x1c4/0x214 (unreliable)
> [162980.037040] [c668fd10] [c00e1eec] free_pgtables+0x12c/0x150
> [162980.037118] [c668fd40] [c00eabac] exit_mmap+0xe8/0x1b4
> [162980.037210] [c668fda0] [c0019710] mmput.part.9+0x20/0xd8
> [162980.037301] [c668fdb0] [c001ecb0] do_exit+0x1f0/0x93c
> [162980.037386] [c668fe00] [c001f478] do_group_exit+0x40/0xcc
> [162980.037479] [c668fe10] [c002a76c] get_signal+0x47c/0x614
> [162980.037570] [c668fe70] [c0007840] do_signal+0x54/0x244
> [162980.037654] [c668ff30] [c0007ae8] do_notify_resume+0x34/0x88
> [162980.037744] [c668ff40] [c000dae8] do_user_signal+0x74/0xc4
> [162980.037781] Instruction dump:
> [162980.037821] 7fdff378 81370000 54a3463a 80890020 7d24182e 7c841a14 712a0004 4082ff94
> [162980.038014] 2f890000 419e0010 712a0ff0 408200e0 <0fe00000> 54a9000a 7f984840 419d0094
> [162980.038216] ---[ end trace c0ceeca8e7a5800a ]---
> [162980.038754] BUG: non-zero nr_ptes on freeing mm: 1
> [162985.363322] BUG: non-zero nr_ptes on freeing mm: -1
>
> In order to fix this, this patch uses the address space "slices"
> implemented for BOOK3S/64 and enhanced to support PPC32 by the
> preceding patch.
>
> This patch modifies the context.id on the 8xx to be in the range
> [1:16] instead of [0:15] in order to identify context.id == 0 as
> not initialised contexts as done on BOOK3S
>
> This patch activates CONFIG_PPC_MM_SLICES when CONFIG_HUGETLB_PAGE is
> selected for the 8xx
>
> Alltough we could in theory have as many slices as PMD entries, the
> current slices implementation limits the number of low slices to 16.
> This limitation is not preventing us to fix the initial issue allthough
> it is suboptimal. It will be cured in a subsequent patch.
>
> Fixes: 4b91428699477 ("powerpc/8xx: Implement support of hugepages")
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> ---
>  v2: First patch of v1 serie split in two parts
>
>  arch/powerpc/include/asm/mmu-8xx.h     | 6 ++++++
>  arch/powerpc/kernel/setup-common.c     | 2 ++
>  arch/powerpc/mm/8xx_mmu.c              | 2 +-
>  arch/powerpc/mm/hugetlbpage.c          | 2 ++
>  arch/powerpc/mm/mmu_context_nohash.c   | 4 ++--
>  arch/powerpc/mm/slice.c                | 2 ++
>  arch/powerpc/platforms/Kconfig.cputype | 1 +
>  7 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h
> index 5bb3dbede41a..5f89b6010453 100644
> --- a/arch/powerpc/include/asm/mmu-8xx.h
> +++ b/arch/powerpc/include/asm/mmu-8xx.h
> @@ -169,6 +169,12 @@ typedef struct {
>  	unsigned int id;
>  	unsigned int active;
>  	unsigned long vdso_base;
> +#ifdef CONFIG_PPC_MM_SLICES
> +	u16 user_psize;		/* page size index */
> +	u64 low_slices_psize;	/* page size encodings */
> +	unsigned char high_slices_psize[0];
> +	unsigned long slb_addr_limit;
> +#endif
>  } mm_context_t;
>  
>  #define PHYS_IMMR_BASE (mfspr(SPRN_IMMR) & 0xfff80000)
> diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
> index 9d213542a48b..67075a1cff36 100644
> --- a/arch/powerpc/kernel/setup-common.c
> +++ b/arch/powerpc/kernel/setup-common.c
> @@ -927,6 +927,8 @@ void __init setup_arch(char **cmdline_p)
>  #ifdef CONFIG_PPC64
>  	if (!radix_enabled())
>  		init_mm.context.slb_addr_limit = DEFAULT_MAP_WINDOW_USER64;
> +#elif defined(CONFIG_PPC_8xx)
> +	init_mm.context.slb_addr_limit = DEFAULT_MAP_WINDOW;
>  #else
>  #error	"context.addr_limit not initialized."
>  #endif
> diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c
> index f29212e40f40..0be77709446c 100644
> --- a/arch/powerpc/mm/8xx_mmu.c
> +++ b/arch/powerpc/mm/8xx_mmu.c
> @@ -192,7 +192,7 @@ void set_context(unsigned long id, pgd_t *pgd)
>  	mtspr(SPRN_M_TW, __pa(pgd) - offset);
>  
>  	/* Update context */
> -	mtspr(SPRN_M_CASID, id);
> +	mtspr(SPRN_M_CASID, id - 1);
>  	/* sync */
>  	mb();
>  }
> diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
> index a9b9083c5e49..79e1378ee303 100644
> --- a/arch/powerpc/mm/hugetlbpage.c
> +++ b/arch/powerpc/mm/hugetlbpage.c
> @@ -553,9 +553,11 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
>  	struct hstate *hstate = hstate_file(file);
>  	int mmu_psize = shift_to_mmu_psize(huge_page_shift(hstate));
>  
> +#ifdef CONFIG_PPC_RADIX_MMU
>  	if (radix_enabled())
>  		return radix__hugetlb_get_unmapped_area(file, addr, len,
>  						       pgoff, flags);
> +#endif

if (0) didn't remove the following radix__hugetlb_get_unmapped_area for
you? 


>  	return slice_get_unmapped_area(addr, len, flags, mmu_psize, 1);
>  }
>  #endif
> diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
> index 42e02f5b6660..c1e1bf186871 100644
> --- a/arch/powerpc/mm/mmu_context_nohash.c
> +++ b/arch/powerpc/mm/mmu_context_nohash.c
> @@ -435,8 +435,8 @@ void __init mmu_context_init(void)
>  	 *      -- BenH
>  	 */
>  	if (mmu_has_feature(MMU_FTR_TYPE_8xx)) {
> -		first_context = 0;
> -		last_context = 15;
> +		first_context = 1;
> +		last_context = 16;
>  		no_selective_tlbil = true;
>  	} else if (mmu_has_feature(MMU_FTR_TYPE_47x)) {
>  		first_context = 1;
> diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
> index 3f35a93afe13..b617acf35836 100644
> --- a/arch/powerpc/mm/slice.c
> +++ b/arch/powerpc/mm/slice.c
> @@ -206,6 +206,7 @@ static int slice_check_fit(struct mm_struct *mm,
>  
>  static void slice_flush_segments(void *parm)
>  {
> +#ifdef CONFIG_PPC_BOOK3S_64
>  	struct mm_struct *mm = parm;
>  	unsigned long flags;
>  
> @@ -217,6 +218,7 @@ static void slice_flush_segments(void *parm)
>  	local_irq_save(flags);
>  	slb_flush_and_rebolt();
>  	local_irq_restore(flags);
> +#endif
>  }
>  
>  static void slice_convert(struct mm_struct *mm, struct slice_mask mask, int psize)
> diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
> index ae07470fde3c..73a7ea333e9e 100644
> --- a/arch/powerpc/platforms/Kconfig.cputype
> +++ b/arch/powerpc/platforms/Kconfig.cputype
> @@ -334,6 +334,7 @@ config PPC_BOOK3E_MMU
>  config PPC_MM_SLICES
>  	bool
>  	default y if PPC_BOOK3S_64
> +	default y if PPC_8xx && HUGETLB_PAGE
>  	default n
>  
>  config PPC_HAVE_PMU_SUPPORT
> -- 
> 2.13.3

^ permalink raw reply

* Re: [PATCH v2 1/5] powerpc/mm: Enhance 'slice' for supporting PPC32
From: Aneesh Kumar K.V @ 2018-01-19  8:24 UTC (permalink / raw)
  To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman, Scott Wood
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <49148d07955d3e5f963cedf9adcfcc37c3e03ef4.1516179904.git.christophe.leroy@c-s.fr>

Christophe Leroy <christophe.leroy@c-s.fr> writes:

> In preparation for the following patch which will fix an issue on
> the 8xx by re-using the 'slices', this patch enhances the
> 'slices' implementation to support 32 bits CPUs.
>
> On PPC32, the address space is limited to 4Gbytes, hence only the low
> slices will be used. As of today, the code uses
> SLICE_LOW_TOP (0x100000000ul) and compares it with addr to determine
> if addr refers to low or high space.
> On PPC32, such a (addr < SLICE_LOW_TOP) test is always false because
> 0x100000000ul degrades to 0. Therefore, the patch modifies
> SLICE_LOW_TOP to (0xfffffffful) and modifies the tests to
> (addr <= SLICE_LOW_TOP) which will then always be true on PPC32
> as addr has type 'unsigned long' while not modifying the PPC64
> behaviour.
>
> This patch moves "slices" functions prototypes from page64.h to page.h
>
> The high slices use bitmaps. As bitmap functions are not prepared to
> handling bitmaps of size 0, the bitmap_xxx() calls are wrapped into
> slice_bitmap_xxx() macros which will take care of the 0 nbits case.
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> ---
>  v2: First patch of v1 serie split in two parts ; added slice_bitmap_xxx() macros.
>
>  arch/powerpc/include/asm/page.h      | 14 +++++++++
>  arch/powerpc/include/asm/page_32.h   | 19 ++++++++++++
>  arch/powerpc/include/asm/page_64.h   | 21 ++-----------
>  arch/powerpc/mm/hash_utils_64.c      |  2 +-
>  arch/powerpc/mm/mmu_context_nohash.c |  7 +++++
>  arch/powerpc/mm/slice.c              | 60 ++++++++++++++++++++++++------------
>  6 files changed, 83 insertions(+), 40 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
> index 8da5d4c1cab2..d0384f9db9eb 100644
> --- a/arch/powerpc/include/asm/page.h
> +++ b/arch/powerpc/include/asm/page.h
> @@ -342,6 +342,20 @@ typedef struct page *pgtable_t;
>  #endif
>  #endif
>  
> +#ifdef CONFIG_PPC_MM_SLICES
> +struct mm_struct;
> +
> +unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
> +				      unsigned long flags, unsigned int psize,
> +				      int topdown);
> +
> +unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr);
> +
> +void slice_set_user_psize(struct mm_struct *mm, unsigned int psize);
> +void slice_set_range_psize(struct mm_struct *mm, unsigned long start,
> +			   unsigned long len, unsigned int psize);
> +#endif
> +

Should we do a slice.h ? the way we have other files? and then do

arch/powerpc/include/asm/book3s/64/slice.h that will carry
#define slice_bitmap_zero(dst, nbits) \
	do { if (nbits) bitmap_zero(dst, nbits); } while (0)
#define slice_bitmap_set(dst, pos, nbits) \
do { if (nbits) bitmap_set(dst, pos, nbits); } while (0)
#define slice_bitmap_copy(dst, src, nbits) \
do { if (nbits) bitmap_copy(dst, src, nbits); } while (0)
#define slice_bitmap_and(dst, src1, src2, nbits) \
	({ (nbits) ? bitmap_and(dst, src1, src2, nbits) : 0; })
#define slice_bitmap_or(dst, src1, src2, nbits) \
	do { if (nbits) bitmap_or(dst, src1, src2, nbits); } while (0)
#define slice_bitmap_andnot(dst, src1, src2, nbits) \
	({ (nbits) ? bitmap_andnot(dst, src1, src2, nbits) : 0; })
#define slice_bitmap_equal(src1, src2, nbits) \
	({ (nbits) ? bitmap_equal(src1, src2, nbits) : 1; })
#define slice_bitmap_empty(src, nbits) \
	({ (nbits) ? bitmap_empty(src, nbits) : 1; })

This without that if(nbits) check and a proper static inline so that we
can do type checking.

also related definitions for
#define SLICE_LOW_SHIFT		28
#define SLICE_HIGH_SHIFT	0

#define SLICE_LOW_TOP		(0xfffffffful)
#define SLICE_NUM_LOW		((SLICE_LOW_TOP >> SLICE_LOW_SHIFT) + 1)
+#define SLICE_NUM_HIGH		0ul

Common stuff between 64 and 32 can got to
arch/powerpc/include/asm/slice.h ?

It also gives an indication of which 32 bit version we are looking at
here. IIUC 8xx will got to arch/powerpc/include/asm/nohash/32/slice.h?

>  #include <asm-generic/memory_model.h>
>  #endif /* __ASSEMBLY__ */
>  
> diff --git a/arch/powerpc/include/asm/page_32.h b/arch/powerpc/include/asm/page_32.h
> index 5c378e9b78c8..f7d1bd1183c8 100644
> --- a/arch/powerpc/include/asm/page_32.h
> +++ b/arch/powerpc/include/asm/page_32.h
> @@ -60,4 +60,23 @@ extern void copy_page(void *to, void *from);
>  
>  #endif /* __ASSEMBLY__ */
>  
> +#ifdef CONFIG_PPC_MM_SLICES
> +
> +#define SLICE_LOW_SHIFT		28
> +#define SLICE_HIGH_SHIFT	0
> +
> +#define SLICE_LOW_TOP		(0xfffffffful)
> +#define SLICE_NUM_LOW		((SLICE_LOW_TOP >> SLICE_LOW_SHIFT) + 1)
> +#define SLICE_NUM_HIGH		0ul
> +
> +#define GET_LOW_SLICE_INDEX(addr)	((addr) >> SLICE_LOW_SHIFT)
> +#define GET_HIGH_SLICE_INDEX(addr)	(addr & 0)
> +
> +#ifdef CONFIG_HUGETLB_PAGE
> +#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
> +#endif
> +#define HAVE_ARCH_UNMAPPED_AREA
> +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
> +
> +#endif
>  #endif /* _ASM_POWERPC_PAGE_32_H */
> diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h
> index 56234c6fcd61..a7baef5bbe5f 100644
> --- a/arch/powerpc/include/asm/page_64.h
> +++ b/arch/powerpc/include/asm/page_64.h
> @@ -91,30 +91,13 @@ extern u64 ppc64_pft_size;
>  #define SLICE_LOW_SHIFT		28
>  #define SLICE_HIGH_SHIFT	40
>  
> -#define SLICE_LOW_TOP		(0x100000000ul)
> -#define SLICE_NUM_LOW		(SLICE_LOW_TOP >> SLICE_LOW_SHIFT)
> +#define SLICE_LOW_TOP		(0xfffffffful)
> +#define SLICE_NUM_LOW		((SLICE_LOW_TOP >> SLICE_LOW_SHIFT) + 1)
>  #define SLICE_NUM_HIGH		(H_PGTABLE_RANGE >> SLICE_HIGH_SHIFT)
>  
>  #define GET_LOW_SLICE_INDEX(addr)	((addr) >> SLICE_LOW_SHIFT)
>  #define GET_HIGH_SLICE_INDEX(addr)	((addr) >> SLICE_HIGH_SHIFT)
>  
> -#ifndef __ASSEMBLY__
> -struct mm_struct;
> -
> -extern unsigned long slice_get_unmapped_area(unsigned long addr,
> -					     unsigned long len,
> -					     unsigned long flags,
> -					     unsigned int psize,
> -					     int topdown);
> -
> -extern unsigned int get_slice_psize(struct mm_struct *mm,
> -				    unsigned long addr);
> -
> -extern void slice_set_user_psize(struct mm_struct *mm, unsigned int psize);
> -extern void slice_set_range_psize(struct mm_struct *mm, unsigned long start,
> -				  unsigned long len, unsigned int psize);
> -
> -#endif /* __ASSEMBLY__ */
>  #else
>  #define slice_init()
>  #ifdef CONFIG_PPC_BOOK3S_64
> diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
> index 655a5a9a183d..3266b3326088 100644
> --- a/arch/powerpc/mm/hash_utils_64.c
> +++ b/arch/powerpc/mm/hash_utils_64.c
> @@ -1101,7 +1101,7 @@ static unsigned int get_paca_psize(unsigned long addr)
>  	unsigned char *hpsizes;
>  	unsigned long index, mask_index;
>  
> -	if (addr < SLICE_LOW_TOP) {
> +	if (addr <= SLICE_LOW_TOP) {
>  		lpsizes = get_paca()->mm_ctx_low_slices_psize;
>  		index = GET_LOW_SLICE_INDEX(addr);
>  		return (lpsizes >> (index * 4)) & 0xF;
> diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
> index 4554d6527682..42e02f5b6660 100644
> --- a/arch/powerpc/mm/mmu_context_nohash.c
> +++ b/arch/powerpc/mm/mmu_context_nohash.c
> @@ -331,6 +331,13 @@ int init_new_context(struct task_struct *t, struct mm_struct *mm)
>  {
>  	pr_hard("initing context for mm @%p\n", mm);
>  
> +#ifdef CONFIG_PPC_MM_SLICES
> +	if (!mm->context.slb_addr_limit)
> +		mm->context.slb_addr_limit = DEFAULT_MAP_WINDOW;
> +	if (!mm->context.id)
> +		slice_set_user_psize(mm, mmu_virtual_psize);
> +#endif
> +
>  	mm->context.id = MMU_NO_CONTEXT;
>  	mm->context.active = 0;
>  	return 0;
> diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
> index 23ec2c5e3b78..3f35a93afe13 100644
> --- a/arch/powerpc/mm/slice.c
> +++ b/arch/powerpc/mm/slice.c
> @@ -67,16 +67,33 @@ static void slice_print_mask(const char *label, struct slice_mask mask) {}
>  
>  #endif
>  
> +#define slice_bitmap_zero(dst, nbits) \
> +	do { if (nbits) bitmap_zero(dst, nbits); } while (0)
> +#define slice_bitmap_set(dst, pos, nbits) \
> +	do { if (nbits) bitmap_set(dst, pos, nbits); } while (0)
> +#define slice_bitmap_copy(dst, src, nbits) \
> +	do { if (nbits) bitmap_copy(dst, src, nbits); } while (0)
> +#define slice_bitmap_and(dst, src1, src2, nbits) \
> +	({ (nbits) ? bitmap_and(dst, src1, src2, nbits) : 0; })
> +#define slice_bitmap_or(dst, src1, src2, nbits) \
> +	do { if (nbits) bitmap_or(dst, src1, src2, nbits); } while (0)
> +#define slice_bitmap_andnot(dst, src1, src2, nbits) \
> +	({ (nbits) ? bitmap_andnot(dst, src1, src2, nbits) : 0; })
> +#define slice_bitmap_equal(src1, src2, nbits) \
> +	({ (nbits) ? bitmap_equal(src1, src2, nbits) : 1; })
> +#define slice_bitmap_empty(src, nbits) \
> +	({ (nbits) ? bitmap_empty(src, nbits) : 1; })
> +
>  static void slice_range_to_mask(unsigned long start, unsigned long len,
>  				struct slice_mask *ret)
>  {
>  	unsigned long end = start + len - 1;
>  
>  	ret->low_slices = 0;
> -	bitmap_zero(ret->high_slices, SLICE_NUM_HIGH);
> +	slice_bitmap_zero(ret->high_slices, SLICE_NUM_HIGH);
>  
> -	if (start < SLICE_LOW_TOP) {
> -		unsigned long mend = min(end, (SLICE_LOW_TOP - 1));
> +	if (start <= SLICE_LOW_TOP) {
> +		unsigned long mend = min(end, SLICE_LOW_TOP);
>  
>  		ret->low_slices = (1u << (GET_LOW_SLICE_INDEX(mend) + 1))
>  			- (1u << GET_LOW_SLICE_INDEX(start));
> @@ -87,7 +104,7 @@ static void slice_range_to_mask(unsigned long start, unsigned long len,
>  		unsigned long align_end = ALIGN(end, (1UL << SLICE_HIGH_SHIFT));
>  		unsigned long count = GET_HIGH_SLICE_INDEX(align_end) - start_index;
>  
> -		bitmap_set(ret->high_slices, start_index, count);
> +		slice_bitmap_set(ret->high_slices, start_index, count);
>  	}
>  }
>  
> @@ -117,7 +134,7 @@ static int slice_high_has_vma(struct mm_struct *mm, unsigned long slice)
>  	 * of the high or low area bitmaps, the first high area starts
>  	 * at 4GB, not 0 */
>  	if (start == 0)
> -		start = SLICE_LOW_TOP;
> +		start = SLICE_LOW_TOP + 1;
>  
>  	return !slice_area_is_free(mm, start, end - start);
>  }
> @@ -128,7 +145,7 @@ static void slice_mask_for_free(struct mm_struct *mm, struct slice_mask *ret,
>  	unsigned long i;
>  
>  	ret->low_slices = 0;
> -	bitmap_zero(ret->high_slices, SLICE_NUM_HIGH);
> +	slice_bitmap_zero(ret->high_slices, SLICE_NUM_HIGH);
>  
>  	for (i = 0; i < SLICE_NUM_LOW; i++)
>  		if (!slice_low_has_vma(mm, i))
> @@ -151,7 +168,7 @@ static void slice_mask_for_size(struct mm_struct *mm, int psize, struct slice_ma
>  	u64 lpsizes;
>  
>  	ret->low_slices = 0;
> -	bitmap_zero(ret->high_slices, SLICE_NUM_HIGH);
> +	slice_bitmap_zero(ret->high_slices, SLICE_NUM_HIGH);
>  
>  	lpsizes = mm->context.low_slices_psize;
>  	for (i = 0; i < SLICE_NUM_LOW; i++)
> @@ -180,11 +197,11 @@ static int slice_check_fit(struct mm_struct *mm,
>  	 */
>  	unsigned long slice_count = GET_HIGH_SLICE_INDEX(mm->context.slb_addr_limit);
>  
> -	bitmap_and(result, mask.high_slices,
> -		   available.high_slices, slice_count);
> +	slice_bitmap_and(result, mask.high_slices,
> +			 available.high_slices, slice_count);
>  
>  	return (mask.low_slices & available.low_slices) == mask.low_slices &&
> -		bitmap_equal(result, mask.high_slices, slice_count);
> +		slice_bitmap_equal(result, mask.high_slices, slice_count));
>  }
>  
>  static void slice_flush_segments(void *parm)
> @@ -259,7 +276,7 @@ static bool slice_scan_available(unsigned long addr,
>  				 unsigned long *boundary_addr)
>  {
>  	unsigned long slice;
> -	if (addr < SLICE_LOW_TOP) {
> +	if (addr <= SLICE_LOW_TOP) {
>  		slice = GET_LOW_SLICE_INDEX(addr);
>  		*boundary_addr = (slice + end) << SLICE_LOW_SHIFT;
>  		return !!(available.low_slices & (1u << slice));
> @@ -391,8 +408,9 @@ static inline void slice_or_mask(struct slice_mask *dst, struct slice_mask *src)
>  	DECLARE_BITMAP(result, SLICE_NUM_HIGH);
>  
>  	dst->low_slices |= src->low_slices;
> -	bitmap_or(result, dst->high_slices, src->high_slices, SLICE_NUM_HIGH);
> -	bitmap_copy(dst->high_slices, result, SLICE_NUM_HIGH);
> +	slice_bitmap_or(result, dst->high_slices, src->high_slices,
> +			SLICE_NUM_HIGH);
> +	slice_bitmap_copy(dst->high_slices, result, SLICE_NUM_HIGH);
>  }
>  
>  static inline void slice_andnot_mask(struct slice_mask *dst, struct slice_mask *src)
> @@ -401,8 +419,9 @@ static inline void slice_andnot_mask(struct slice_mask *dst, struct slice_mask *
>  
>  	dst->low_slices &= ~src->low_slices;
>  
> -	bitmap_andnot(result, dst->high_slices, src->high_slices, SLICE_NUM_HIGH);
> -	bitmap_copy(dst->high_slices, result, SLICE_NUM_HIGH);
> +	slice_bitmap_andnot(result, dst->high_slices, src->high_slices,
> +			    SLICE_NUM_HIGH);
> +	slice_bitmap_copy(dst->high_slices, result, SLICE_NUM_HIGH);
>  }
>  
>  #ifdef CONFIG_PPC_64K_PAGES
> @@ -450,14 +469,14 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
>  	 * init different masks
>  	 */
>  	mask.low_slices = 0;
> -	bitmap_zero(mask.high_slices, SLICE_NUM_HIGH);
> +	slice_bitmap_zero(mask.high_slices, SLICE_NUM_HIGH);
>  
>  	/* silence stupid warning */;
>  	potential_mask.low_slices = 0;
> -	bitmap_zero(potential_mask.high_slices, SLICE_NUM_HIGH);
> +	slice_bitmap_zero(potential_mask.high_slices, SLICE_NUM_HIGH);
>  
>  	compat_mask.low_slices = 0;
> -	bitmap_zero(compat_mask.high_slices, SLICE_NUM_HIGH);
> +	slice_bitmap_zero(compat_mask.high_slices, SLICE_NUM_HIGH);
>  
>  	/* Sanity checks */
>  	BUG_ON(mm->task_size == 0);
> @@ -595,7 +614,8 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
>   convert:
>  	slice_andnot_mask(&mask, &good_mask);
>  	slice_andnot_mask(&mask, &compat_mask);
> -	if (mask.low_slices || !bitmap_empty(mask.high_slices, SLICE_NUM_HIGH)) {
> +	if (mask.low_slices ||
> +	    !slice_bitmap_empty(mask.high_slices, SLICE_NUM_HIGH)) {
>  		slice_convert(mm, mask, psize);
>  		if (psize > MMU_PAGE_BASE)
>  			on_each_cpu(slice_flush_segments, mm, 1);
> @@ -640,7 +660,7 @@ unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr)
>  		return MMU_PAGE_4K;
>  #endif
>  	}
> -	if (addr < SLICE_LOW_TOP) {
> +	if (addr <= SLICE_LOW_TOP) {
>  		u64 lpsizes;
>  		lpsizes = mm->context.low_slices_psize;
>  		index = GET_LOW_SLICE_INDEX(addr);
> -- 
> 2.13.3

^ permalink raw reply

* Re: DPAA Ethernet traffice troubles with Linux kernel
From: Joakim Tjernlund @ 2018-01-19  8:00 UTC (permalink / raw)
  To: madalin.bucur@nxp.com, andrew@lunn.ch
  Cc: linuxppc-dev@lists.ozlabs.org, netdev@vger.kernel.org,
	madskateman@gmail.com
In-Reply-To: <DB3PR0402MB38492999533EB4400DED45BFECE90@DB3PR0402MB3849.eurprd04.prod.outlook.com>

T24gVGh1LCAxOTcwLTAxLTAxIGF0IDAwOjAwICswMDAwLCBNYWRhbGluLWNyaXN0aWFuIEJ1Y3Vy
IHdyb3RlOg0KPiANCj4gPiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiA+IEZyb206IEpv
YWtpbSBUamVybmx1bmQgW21haWx0bzpKb2FraW0uVGplcm5sdW5kQGluZmluZXJhLmNvbV0NCj4g
PiBTZW50OiBUdWVzZGF5LCBKYW51YXJ5IDE2LCAyMDE4IDc6NTggUE0NCj4gPiBUbzogYW5kcmV3
QGx1bm4uY2gNCj4gPiBTdWJqZWN0OiBSZTogRFBBQSBFdGhlcm5ldCB0cmFmZmljZSB0cm91Ymxl
cyB3aXRoIExpbnV4IGtlcm5lbA0KPiA+IA0KPiA+IE9uIFRodSwgMTk3MC0wMS0wMSBhdCAwMDow
MCArMDAwMCwgQW5kcmV3IEx1bm4gd3JvdGU6DQo+ID4gPiANCj4gPiA+IEhpIEpvYWtpbQ0KPiA+
ID4gDQo+ID4gPiBZb3UgYXBwZWFyIHRvIGJlIHVzaW5nIGFuIG9sZCBrZXJuZWwuIFRha2UgYSBs
b29rIGF0Og0KPiA+IA0KPiA+IE5vdCByZWFsbHksIEkgYW0gdXNpbmcgNC4xNC54IGFuZCBJIGRv
bid0IHRoaW5rIHRoYXQgaXMgb2xkLiBTZWVtcyBsaWtlDQo+ID4gdGhpcw0KPiA+IHBhdGNoIGhh
c24ndCBiZWVuIHNlbnQgdG8gNC4xNC54Lg0KPiA+IA0KPiA+IEkgd29uZGVyIGlmIEkgbWlnaHQg
YmUgbWlzc2luZyBzb21ldGhpbmcgZWxzZSwgd2UganVzdCBtb3ZlZCB0byA0LjE0IGFuZA0KPiA+
IG5vdGljIHRoYXQgYWxsDQo+ID4gb3VyIGZpeGVkIFBIWXMgYXJlIG5vbiBmdW5jdGlvbmluZzoN
Cj4gPiBmc2xfbWFjIGZmZTRlMjAwMC5ldGhlcm5ldDogRk1hbiBNRU1BQw0KPiA+IGZzbF9tYWMg
ZmZlNGUyMDAwLmV0aGVybmV0OiBGTWFuIE1BQyBhZGRyZXNzOiAwMDowNjo5YzowYjowNjoyMA0K
PiA+IGZzbF9tYWMgZHBhYS1ldGhlcm5ldC4wOiBfX2Rldm1fcmVxdWVzdF9tZW1fcmVnaW9uKG1h
YykgZmFpbGVkDQo+ID4gZnNsX21hYzogcHJvYmUgb2YgZHBhYS1ldGhlcm5ldC4wIGZhaWxlZCB3
aXRoIGVycm9yIC0xNg0KPiA+IGZzbF9tYWMgZmZlNGU0MDAwLmV0aGVybmV0OiBGTWFuIE1FTUFD
DQo+ID4gZnNsX21hYyBmZmU0ZTQwMDAuZXRoZXJuZXQ6IEZNYW4gTUFDIGFkZHJlc3M6IDAwOjA2
OjljOjBiOjA2OjIxDQo+ID4gZnNsX21hYyBkcGFhLWV0aGVybmV0LjE6IF9fZGV2bV9yZXF1ZXN0
X21lbV9yZWdpb24obWFjKSBmYWlsZWQNCj4gPiBmc2xfbWFjOiBwcm9iZSBvZiBkcGFhLWV0aGVy
bmV0LjEgZmFpbGVkIHdpdGggZXJyb3IgLTE2DQo+ID4gZnNsX21hYyBmZmU0ZTYwMDAuZXRoZXJu
ZXQ6IEZNYW4gTUVNQUMNCj4gPiBmc2xfbWFjIGZmZTRlNjAwMC5ldGhlcm5ldDogRk1hbiBNQUMg
YWRkcmVzczogMDA6MDY6OWM6MGI6MDY6MjINCj4gPiBmc2xfbWFjIGRwYWEtZXRoZXJuZXQuMjog
X19kZXZtX3JlcXVlc3RfbWVtX3JlZ2lvbihtYWMpIGZhaWxlZA0KPiA+IGZzbF9tYWM6IHByb2Jl
IG9mIGRwYWEtZXRoZXJuZXQuMiBmYWlsZWQgd2l0aCBlcnJvciAtMTYNCj4gPiBmc2xfbWFjIGZm
ZTRlODAwMC5ldGhlcm5ldDogRk1hbiBNRU1BQw0KPiA+IGZzbF9tYWMgZmZlNGU4MDAwLmV0aGVy
bmV0OiBGTWFuIE1BQyBhZGRyZXNzOiAwMDowNjo5YzowYjowNjoyMw0KPiA+IGZzbF9tYWMgZHBh
YS1ldGhlcm5ldC4zOiBfX2Rldm1fcmVxdWVzdF9tZW1fcmVnaW9uKG1hYykgZmFpbGVkDQo+ID4g
ZnNsX21hYzogcHJvYmUgb2YgZHBhYS1ldGhlcm5ldC4zIGZhaWxlZCB3aXRoIGVycm9yIC0xNg0K
PiA+IA0KPiA+IEZlZWxzIGxpa2UgRk1BTiBzdGlsbCB0aGluayB0aGVyZSBhcmUgcmVhbCBQSFlz
IHRoZXJlID8NCj4gDQo+IEhpIEpvYWtpbSwNCj4gDQo+IFRoZXNlIGVycm9ycyBhcmUgaXNzdWVk
IHdoZW4gdHJ5aW5nIHRvIHByb2JlIHRoZSBzZWNvbmQgdGltZSB0aGUgc2FtZQ0KPiBNQUMgbm9k
ZS4gVGhlIGlzc3VlIHdhcyBpbnRyb2R1Y2VkIGJ5IHRoaXMgY29tbWl0Og0KPiANCj4gY29tbWl0
IDRkOGVlMTkzNWJjZDY2NjM2MDMxMWRmZGFkZWVlMjM1ZDY4MmQ2OWENCj4gQXV0aG9yOiBGbG9y
aWFuIEZhaW5lbGxpIDxmLmZhaW5lbGxpQGdtYWlsLmNvbT4NCj4gRGF0ZTogVHVlIEF1ZyAyMiAx
NToyNDo0NyAyMDE3IC0wNzAwDQo+IGZzbC9tYW46IEluaGVyaXQgcGFyZW50IGRldmljZSBhbmQg
b2Zfbm9kZQ0KPiANCj4gYW5kIHdhcyBsYXRlciBhZGRyZXNzZWQgYnkgdGhpcyBwYXRjaCBzZXQ6
DQo+IA0KPiBodHRwOi8vcGF0Y2h3b3JrLm96bGFicy5vcmcvcHJvamVjdC9uZXRkZXYvbGlzdC8/
c2VyaWVzPTg0NjImc3RhdGU9Kg0KPiANCj4gRXZlbiB3aXRoIHRoZXNlIGVycm9ycyBwcmludGVk
LCBhbGwgaXMgd29ya2luZyBmaW5lLCBpdCdzIGp1c3QgdGhlDQo+IHNlY29uZCBwcm9iaW5nIHRo
YXQgZmFpbHMuIEFkZGluZyB0aGUgbGF0dGVyIHBhdGNoZXMgb3IgcmV2ZXJ0aW5nDQo+IHRoZSBv
bmUgYWJvdmUgbWFrZXMgdGhlIGVycm9ycyBwcmludHMgZGlzc2FwZWFyLg0KDQpMb29raW5nIGF0
IHRoZSBhYm92ZSBwYXRjaCBzZXJpZXJzIEkgc2VlIGl0IGlzIGluIHN0YXRlIEFjY2VwdGVkIGFu
ZCBoYXMgYmVlbiB0aGVyZQ0Kc2luY2UgMjAxNy0xMC0xNg0KVGhhdCBzZWVtcyBsaWtlIGEgYXdm
dWwgbG9uZyB0byB3YWl0IGluIGJlZm9yZSBnZXR0aW5nIGludG8gTGludXgsIGlzIHRoZXJlIHNv
bWV0aGluZw0KaG9sZGluZyB0aGVzZSBwYXRjaGVzIGJhY2sgPw0KDQogSm9ja2Ug

^ permalink raw reply

* linux-next: build failure after merge of the powerpc tree
From: Stephen Rothwell @ 2018-01-19  5:53 UTC (permalink / raw)
  To: Michael Ellerman, Benjamin Herrenschmidt, PowerPC
  Cc: Linux-Next Mailing List, Linux Kernel Mailing List,
	Nicholas Piggin

Hi all,

After merging the powerpc tree, today's linux-next build (powerpc64
allnoconfig) failed like this:

arch/powerpc/kernel/mce_power.o: In function `.mce_handle_error':
mce_power.c:(.text+0x5a8): undefined reference to `.hash__tlbiel_all'
mce_power.c:(.text+0x6b8): undefined reference to `.hash__tlbiel_all'
arch/powerpc/mm/hash_utils_64.o: In function `.hash__early_init_mmu':
hash_utils_64.c:(.init.text+0x9d0): undefined reference to `.hash__tlbiel_all'

Caused by commit

  d4748276ae14 ("powerpc/64s: Improve local TLB flush for boot and MCE on POWER9")

The definition of hash__tlbiel_all() is in
arch/powerpc/mm/hash_native_64.c which is only built if CONFIG_PPC_NATIVE
is set, which it is not for this build.

I applied a supplied fix patch.

-- 
Cheers,
Stephen Rothwell

^ permalink raw reply

* [PATCH v10 27/27] mm: display pkey in smaps if arch_pkeys_enabled() is true
From: Ram Pai @ 2018-01-19  1:50 UTC (permalink / raw)
  To: mpe, mingo, akpm, corbet, arnd
  Cc: linuxppc-dev, linux-mm, x86, linux-arch, linux-doc,
	linux-kselftest, linux-kernel, dave.hansen, benh, paulus,
	khandual, aneesh.kumar, bsingharora, hbabu, mhocko, bauerman,
	ebiederm, linuxram
In-Reply-To: <1516326648-22775-1-git-send-email-linuxram@us.ibm.com>

Currently the  architecture  specific code is expected to
display  the  protection  keys  in  smap  for a given vma.
This can lead to redundant code and possibly to divergent
formats in which the key gets displayed.

This  patch  changes  the implementation. It displays the
pkey only if the architecture support pkeys.

x86 arch_show_smap() function is not needed anymore.
Delete it.

Signed-off-by: Ram Pai <linuxram@us.ibm.com>
---
 arch/x86/kernel/setup.c |    8 --------
 fs/proc/task_mmu.c      |   11 ++++++-----
 2 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 8af2e8d..ddf945a 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1326,11 +1326,3 @@ static int __init register_kernel_offset_dumper(void)
 	return 0;
 }
 __initcall(register_kernel_offset_dumper);
-
-void arch_show_smap(struct seq_file *m, struct vm_area_struct *vma)
-{
-	if (!boot_cpu_has(X86_FEATURE_OSPKE))
-		return;
-
-	seq_printf(m, "ProtectionKey:  %8u\n", vma_pkey(vma));
-}
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 0edd4da..4b39a94 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -18,6 +18,7 @@
 #include <linux/page_idle.h>
 #include <linux/shmem_fs.h>
 #include <linux/uaccess.h>
+#include <linux/pkeys.h>
 
 #include <asm/elf.h>
 #include <asm/tlb.h>
@@ -728,10 +729,6 @@ static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
 }
 #endif /* HUGETLB_PAGE */
 
-void __weak arch_show_smap(struct seq_file *m, struct vm_area_struct *vma)
-{
-}
-
 static int show_smap(struct seq_file *m, void *v, int is_pid)
 {
 	struct proc_maps_private *priv = m->private;
@@ -851,9 +848,13 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
 			   (unsigned long)(mss->pss >> (10 + PSS_SHIFT)));
 
 	if (!rollup_mode) {
-		arch_show_smap(m, vma);
+#ifdef CONFIG_ARCH_HAS_PKEYS
+		if (arch_pkeys_enabled())
+			seq_printf(m, "ProtectionKey:  %8u\n", vma_pkey(vma));
+#endif
 		show_smap_vma_flags(m, vma);
 	}
+
 	m_cache_vma(m, vma);
 	return ret;
 }
-- 
1.7.1

^ permalink raw reply related

* [PATCH v10 26/27] mm, x86 : introduce arch_pkeys_enabled()
From: Ram Pai @ 2018-01-19  1:50 UTC (permalink / raw)
  To: mpe, mingo, akpm, corbet, arnd
  Cc: linuxppc-dev, linux-mm, x86, linux-arch, linux-doc,
	linux-kselftest, linux-kernel, dave.hansen, benh, paulus,
	khandual, aneesh.kumar, bsingharora, hbabu, mhocko, bauerman,
	ebiederm, linuxram
In-Reply-To: <1516326648-22775-1-git-send-email-linuxram@us.ibm.com>

Arch neutral code needs to know if the architecture supports
protection  keys  to  display protection key in smaps. Hence
introducing arch_pkeys_enabled().

This patch also provides x86 implementation for
arch_pkeys_enabled().

Signed-off-by: Ram Pai <linuxram@us.ibm.com>
---
 arch/x86/include/asm/pkeys.h |    1 +
 arch/x86/kernel/fpu/xstate.c |    5 +++++
 include/linux/pkeys.h        |    5 +++++
 3 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/pkeys.h b/arch/x86/include/asm/pkeys.h
index a0ba1ff..f6c287b 100644
--- a/arch/x86/include/asm/pkeys.h
+++ b/arch/x86/include/asm/pkeys.h
@@ -6,6 +6,7 @@
 
 extern int arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
 		unsigned long init_val);
+extern bool arch_pkeys_enabled(void);
 
 /*
  * Try to dedicate one of the protection keys to be used as an
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 87a57b7..4f566e9 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -945,6 +945,11 @@ int arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
 
 	return 0;
 }
+
+bool arch_pkeys_enabled(void)
+{
+	return boot_cpu_has(X86_FEATURE_OSPKE);
+}
 #endif /* ! CONFIG_ARCH_HAS_PKEYS */
 
 /*
diff --git a/include/linux/pkeys.h b/include/linux/pkeys.h
index 0794ca7..3ca2e44 100644
--- a/include/linux/pkeys.h
+++ b/include/linux/pkeys.h
@@ -35,6 +35,11 @@ static inline int arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
 	return 0;
 }
 
+static inline bool arch_pkeys_enabled(void)
+{
+	return false;
+}
+
 static inline void copy_init_pkru_to_fpregs(void)
 {
 }
-- 
1.7.1

^ permalink raw reply related

* [PATCH v10 25/27] powerpc: sys_pkey_mprotect() system call
From: Ram Pai @ 2018-01-19  1:50 UTC (permalink / raw)
  To: mpe, mingo, akpm, corbet, arnd
  Cc: linuxppc-dev, linux-mm, x86, linux-arch, linux-doc,
	linux-kselftest, linux-kernel, dave.hansen, benh, paulus,
	khandual, aneesh.kumar, bsingharora, hbabu, mhocko, bauerman,
	ebiederm, linuxram
In-Reply-To: <1516326648-22775-1-git-send-email-linuxram@us.ibm.com>

Patch provides the ability for a process to
associate a pkey with a address range.

Signed-off-by: Ram Pai <linuxram@us.ibm.com>
---
 arch/powerpc/include/asm/systbl.h      |    1 +
 arch/powerpc/include/asm/unistd.h      |    4 +---
 arch/powerpc/include/uapi/asm/unistd.h |    1 +
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index dea4a95..d61f9c9 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -391,3 +391,4 @@
 SYSCALL(statx)
 SYSCALL(pkey_alloc)
 SYSCALL(pkey_free)
+SYSCALL(pkey_mprotect)
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index e0273bc..daf1ba9 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -12,12 +12,10 @@
 #include <uapi/asm/unistd.h>
 
 
-#define NR_syscalls		386
+#define NR_syscalls		387
 
 #define __NR__exit __NR_exit
 
-#define __IGNORE_pkey_mprotect
-
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h
index 5db4385..389c36f 100644
--- a/arch/powerpc/include/uapi/asm/unistd.h
+++ b/arch/powerpc/include/uapi/asm/unistd.h
@@ -397,5 +397,6 @@
 #define __NR_statx		383
 #define __NR_pkey_alloc		384
 #define __NR_pkey_free		385
+#define __NR_pkey_mprotect	386
 
 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
-- 
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