Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 2/2] clk: imx: improve precision of AV PLL to 1 Hz
From: Fabio Estevam @ 2016-10-14 13:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <66f5967187f915fe7039f4dbfb77db88a2423094.1476267249.git.emil@limesaudio.com>

On Wed, Oct 12, 2016 at 7:31 AM, Emil Lundmark <emil@limesaudio.com> wrote:
> The audio and video PLLs are designed to have a precision of 1 Hz if some
> conditions are met. The current implementation only allows a precision that
> depends on the rate of the parent clock. E.g., if the parent clock is 24
> MHz, the precision will be 24 Hz; or more generally the precision will be
...
> I reckon this is the intention by the design of the clock rate formula.
>
> Signed-off-by: Emil Lundmark <emil@limesaudio.com>

Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>

^ permalink raw reply

* aarch64 ACPI boot regressed by commit 7ba5f605f3a0 ("arm64/numa: remove the limitation that cpu0 must bind to node0")
From: Andrew Jones @ 2016-10-14 13:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <04f22a79-301b-f05b-033d-c7a24c9f4084@redhat.com>

On Fri, Oct 14, 2016 at 03:18:00PM +0200, Laszlo Ersek wrote:
> On 10/14/16 10:05, Andrew Jones wrote:
> > On Fri, Oct 14, 2016 at 12:50:29AM +0200, Laszlo Ersek wrote:
> >> (4) Analysis (well, a lame attempt at that, because I have zero
> >> familiarity with this code). Let me quote the patch:
> >>
> >>> commit 7ba5f605f3a0d9495aad539eeb8346d726dfc183
> >>> Author: Zhen Lei <thunder.leizhen@huawei.com>
> >>> Date:   Thu Sep 1 14:55:04 2016 +0800
> >>>
> >>>     arm64/numa: remove the limitation that cpu0 must bind to node0
> >>>
> >>>     1. Remove the old binding code.
> >>>     2. Read the nid of cpu0 from dts.
> >>>     3. Fallback the nid of cpu0 to 0 when numa=off is set in bootargs.
> >>>
> >>>     Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
> >>>     Signed-off-by: Will Deacon <will.deacon@arm.com>
> >>>
> >>> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> >>> index c3c08368a685..8b048e6ec34a 100644
> >>> --- a/arch/arm64/kernel/smp.c
> >>> +++ b/arch/arm64/kernel/smp.c
> >>> @@ -624,6 +624,7 @@ static void __init of_parse_and_init_cpus(void)
> >>>  			}
> >>>
> >>>  			bootcpu_valid = true;
> >>> +			early_map_cpu_to_node(0, of_node_to_nid(dn));
> >>>
> >>>  			/*
> >>>  			 * cpu_logical_map has already been
> >>> diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
> >>> index 0a15f010b64a..778a985c8a70 100644
> >>> --- a/arch/arm64/mm/numa.c
> >>> +++ b/arch/arm64/mm/numa.c
> >>> @@ -116,16 +116,24 @@ static void __init setup_node_to_cpumask_map(void)
> >>>   */
> >>>  void numa_store_cpu_info(unsigned int cpu)
> >>>  {
> >>> -	map_cpu_to_node(cpu, numa_off ? 0 : cpu_to_node_map[cpu]);
> >>> +	map_cpu_to_node(cpu, cpu_to_node_map[cpu]);
> >>>  }
> >>>
> >>>  void __init early_map_cpu_to_node(unsigned int cpu, int nid)
> >>>  {
> >>>  	/* fallback to node 0 */
> >>> -	if (nid < 0 || nid >= MAX_NUMNODES)
> >>> +	if (nid < 0 || nid >= MAX_NUMNODES || numa_off)
> >>>  		nid = 0;
> > 
> > The ACPI equivalent code must be missing (at least) the above, because,
> > even with DT, mach-virt won't have cpu to node mappings unless numa
> > is configured on the command line. Can you try adding something like
> > 
> >     -m 512 -smp 4 \
> >     -numa node,mem=256M,cpus=0-1,nodeid=0 \
> >     -numa node,mem=256M,cpus=2-3,nodeid=1
> > 
> > to your QEMU command line?
> 
> I added the following to my domain XML, under <cpu>:
> 
>     <numa>
>       <cell id='0' cpus='0-1' memory='2097152' unit='KiB'/>
>       <cell id='1' cpus='2-3' memory='2097152' unit='KiB'/>
>     </numa>
> 
> (See <http://libvirt.org/formatdomain.html#elementsCPU>.)
> 
> With that, each NUMA node gets half of the VCPUs and half of the guest RAM.
> 
> (This is in a different guest now, one that has a bleeding edge Fedora kernel -- I didn't want to rebuild the upstream kernel yet again, just for this test. So, "4.9.0-0.rc0.git7.1.fc26.aarch64" is based on upstream v4.8-14109-g1573d2c, and it reproduces the problem too.)
> 
> > Then when you boot with ACPI you'll get a
> > SRAT.
> 
> Yes, that's confirmed by the guest kernel log (see below).
> 
> > If that works, then we're just missing the "no SRAT, nid = 0"
> > code (that should have been added with this patch)
> 
> It still crashes with the SRAT, with the following log:

Rats.

> Note the warning message (from wq_numa_init()):
> 
>   workqueue: NUMA node mapping not available for cpu0, disabling NUMA support
> 
> Something looks genuinely broken with the cpu <-> numa-node associations in the ACPI case -- it even seems to fail when the SRAT does exist.
> 
> So, perhaps, commit 7ba5f605f3a0 may not have introduced the bug, only exposed one in the ACPI code?...

The kernel's ACPI NUMA support used to work. It was the test case for
QEMU's SRAT generation code.

Two more experiments I wouldn't mind having you try, if you have time;
 1) confirm that this NUMA configured guest and this latest kernel works
    with DT. This is just for sanity, but I guess it will.
 2) If (1) succeeds, then try the last-known-good kernel with ACPI again,
    but this time with the NUMA configured guest.

If (2) fails then we may need to expand the bisection :-(

Thanks,
drew

^ permalink raw reply

* [PATCH v2 0/2] Assign RK3066 clocks at boot time
From: Paweł Jarosz @ 2016-10-14 14:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1569308.lsrqUgJ5m1@phil>

W dniu 14.10.2016 o 15:28, Heiko Stuebner pisze:
> changes look good. One thing to keep in mind is that we need clock-id
> additions in a separate patch (as they need to be on a shared branch).
>
> I can do this split of patch1 on my own here, so no need to resend the series
> and will do that after 4.9-rc1 (probably somewhere after sunday) as I need a
> stable base for that shared branch.
>
>
> Heiko

Thanks Heiko.

^ permalink raw reply

* [PATCH v2] arm64: dts: qcom: Fix broken interrupt trigger settings
From: Riku Voipio @ 2016-10-14 14:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1470937850-10492-1-git-send-email-marc.zyngier@arm.com>

On 11 August 2016 at 20:50, Marc Zyngier <marc.zyngier@arm.com> wrote:
> When a device uses the GIC as its interrupt controller and generates
> SPIs, only the values 1 (edge rising) and 4 (level high) are legal.
>
> Anything else is just plain wrong (can't be programmed into the HW),
> and leads to aborted driver probes (USB doesn't work with 4.8-rc1
> on a Dragonboard 410C).

Should this be sent to -stable as well? This fixes USB driver loading
for me on v4.8, but still don't seem to get the host usb ports working
on db410c.

Riku

> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
> * From v1:
>   - Fixed USB interrupts after review from Stephen
>
>  arch/arm64/boot/dts/qcom/msm8916.dtsi | 10 +++++-----
>  arch/arm64/boot/dts/qcom/msm8996.dtsi |  2 +-
>  2 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
> index 11bdc24..b010d33 100644
> --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
> +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
> @@ -483,7 +483,7 @@
>                         compatible = "qcom,ci-hdrc";
>                         reg = <0x78d9000 0x400>;
>                         dr_mode = "peripheral";
> -                       interrupts = <GIC_SPI 134 IRQ_TYPE_NONE>;
> +                       interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
>                         usb-phy = <&usb_otg>;
>                         status = "disabled";
>                 };
> @@ -491,7 +491,7 @@
>                 usb_host: ehci at 78d9000 {
>                         compatible = "qcom,ehci-host";
>                         reg = <0x78d9000 0x400>;
> -                       interrupts = <GIC_SPI 134 IRQ_TYPE_NONE>;
> +                       interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
>                         usb-phy = <&usb_otg>;
>                         status = "disabled";
>                 };
> @@ -499,8 +499,8 @@
>                 usb_otg: phy at 78d9000 {
>                         compatible = "qcom,usb-otg-snps";
>                         reg = <0x78d9000 0x400>;
> -                       interrupts = <GIC_SPI 134 IRQ_TYPE_EDGE_BOTH>,
> -                                    <GIC_SPI 140 IRQ_TYPE_EDGE_RISING>;
> +                       interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
> +                                    <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
>
>                         qcom,vdd-levels = <500000 1000000 1320000>;
>                         qcom,phy-init-sequence = <0x44 0x6B 0x24 0x13>;
> @@ -594,7 +594,7 @@
>                               <0x200a000 0x002100>;
>                         reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
>                         interrupt-names = "periph_irq";
> -                       interrupts = <GIC_SPI 190 IRQ_TYPE_NONE>;
> +                       interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
>                         qcom,ee = <0>;
>                         qcom,channel = <0>;
>                         #address-cells = <2>;
> diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
> index 55ec3e8..69ed6e1 100644
> --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
> +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
> @@ -339,7 +339,7 @@
>                               <0x400a000 0x002100>;
>                         reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
>                         interrupt-names = "periph_irq";
> -                       interrupts = <GIC_SPI 326 IRQ_TYPE_NONE>;
> +                       interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>;
>                         qcom,ee = <0>;
>                         qcom,channel = <0>;
>                         #address-cells = <2>;
> --
> 2.1.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v2] ARM: dts: rockchip: temporarily remove emmc hs200 speed from rk3288-veyron-speedy.
From: Heiko Stuebner @ 2016-10-14 14:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <87twd1vzc5.fsf@aikidev.net>

Am Dienstag, 27. September 2016, 13:53:46 CEST schrieb Vagrant Cascadian:
> This essentially mimics what was done with rk3288-veyron-minnie in
> commit 984926781122f034d5bc9962815d135b6c4a8e1d.
> 
> The eMMC of the speedy Chromebook also appears to need the same tuning
> workaround, as it frequently fails to recognize the eMMC without it.
> 
> Signed-off-by: Vagrant Cascadian <vagrantc@aikidev.net>

applied as fix for 4.9.

Your mail client mangled that patch a lot (tabs etc), so it didn't apply 
cleanly. As it is a quite small one, I fixed that up myself, but please try to 
make your mail client send correct patches in the future or use git send-email 
:-)


Thanks
Heiko

^ permalink raw reply

* [PATCH 0/3] thermal: Fix module autoload for drivers
From: Javier Martinez Canillas @ 2016-10-14 14:34 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This small series contains trivial fixes to allow modules to be autoloaded
when its correspoinding thermal device is registered.

Best regards,
Javier


Javier Martinez Canillas (3):
  thermal: max77620: Fix module autoload
  thermal: tango: Fix module autoload
  thermal: db8500: Fix module autoload

 drivers/thermal/db8500_thermal.c   | 1 +
 drivers/thermal/max77620_thermal.c | 1 +
 drivers/thermal/tango_thermal.c    | 1 +
 3 files changed, 3 insertions(+)

-- 
2.7.4

^ permalink raw reply

* [PATCH 2/3] thermal: tango: Fix module autoload
From: Javier Martinez Canillas @ 2016-10-14 14:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476455702-21748-1-git-send-email-javier@osg.samsung.com>

If the driver is built as a module, autoload won't work because the module
alias information is not filled. So user-space can't match the registered
device with the corresponding module.

Export the module alias information using the MODULE_DEVICE_TABLE() macro.

Before this patch:

$ modinfo drivers/thermal/tango_thermal.ko | grep alias
$

After this patch:

$ modinfo drivers/thermal/tango_thermal.ko | grep alias
alias:          of:N*T*Csigma,smp8758-thermalC*
alias:          of:N*T*Csigma,smp8758-thermal

Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---

 drivers/thermal/tango_thermal.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/thermal/tango_thermal.c b/drivers/thermal/tango_thermal.c
index 201304aeafeb..4e67795cb6ce 100644
--- a/drivers/thermal/tango_thermal.c
+++ b/drivers/thermal/tango_thermal.c
@@ -107,6 +107,7 @@ static const struct of_device_id tango_sensor_ids[] = {
 	},
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, tango_sensor_ids);
 
 static struct platform_driver tango_thermal_driver = {
 	.probe	= tango_thermal_probe,
-- 
2.7.4

^ permalink raw reply related

* aarch64 ACPI boot regressed by commit 7ba5f605f3a0 ("arm64/numa: remove the limitation that cpu0 must bind to node0")
From: Laszlo Ersek @ 2016-10-14 15:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <04f22a79-301b-f05b-033d-c7a24c9f4084@redhat.com>

On 10/14/16 15:18, Laszlo Ersek wrote:
> On 10/14/16 10:05, Andrew Jones wrote:
>> On Fri, Oct 14, 2016 at 12:50:29AM +0200, Laszlo Ersek wrote:
>>> (4) Analysis (well, a lame attempt at that, because I have zero
>>> familiarity with this code). Let me quote the patch:
>>>
>>>> commit 7ba5f605f3a0d9495aad539eeb8346d726dfc183
>>>> Author: Zhen Lei <thunder.leizhen@huawei.com>
>>>> Date:   Thu Sep 1 14:55:04 2016 +0800
>>>>
>>>>     arm64/numa: remove the limitation that cpu0 must bind to node0
>>>>
>>>>     1. Remove the old binding code.
>>>>     2. Read the nid of cpu0 from dts.
>>>>     3. Fallback the nid of cpu0 to 0 when numa=off is set in bootargs.
>>>>
>>>>     Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
>>>>     Signed-off-by: Will Deacon <will.deacon@arm.com>
>>>>
>>>> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
>>>> index c3c08368a685..8b048e6ec34a 100644
>>>> --- a/arch/arm64/kernel/smp.c
>>>> +++ b/arch/arm64/kernel/smp.c
>>>> @@ -624,6 +624,7 @@ static void __init of_parse_and_init_cpus(void)
>>>>  			}
>>>>
>>>>  			bootcpu_valid = true;
>>>> +			early_map_cpu_to_node(0, of_node_to_nid(dn));
>>>>
>>>>  			/*
>>>>  			 * cpu_logical_map has already been
>>>> diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
>>>> index 0a15f010b64a..778a985c8a70 100644
>>>> --- a/arch/arm64/mm/numa.c
>>>> +++ b/arch/arm64/mm/numa.c
>>>> @@ -116,16 +116,24 @@ static void __init setup_node_to_cpumask_map(void)
>>>>   */
>>>>  void numa_store_cpu_info(unsigned int cpu)
>>>>  {
>>>> -	map_cpu_to_node(cpu, numa_off ? 0 : cpu_to_node_map[cpu]);
>>>> +	map_cpu_to_node(cpu, cpu_to_node_map[cpu]);
>>>>  }
>>>>
>>>>  void __init early_map_cpu_to_node(unsigned int cpu, int nid)
>>>>  {
>>>>  	/* fallback to node 0 */
>>>> -	if (nid < 0 || nid >= MAX_NUMNODES)
>>>> +	if (nid < 0 || nid >= MAX_NUMNODES || numa_off)
>>>>  		nid = 0;
>>
>> The ACPI equivalent code must be missing (at least) the above,
>> because, even with DT, mach-virt won't have cpu to node mappings
>> unless numa is configured on the command line. Can you try adding
>> something like
>>
>>     -m 512 -smp 4 \
>>     -numa node,mem=256M,cpus=0-1,nodeid=0 \
>>     -numa node,mem=256M,cpus=2-3,nodeid=1
>>
>> to your QEMU command line?
>
> I added the following to my domain XML, under <cpu>:
>
>     <numa>
>       <cell id='0' cpus='0-1' memory='2097152' unit='KiB'/>
>       <cell id='1' cpus='2-3' memory='2097152' unit='KiB'/>
>     </numa>
>
> (See <http://libvirt.org/formatdomain.html#elementsCPU>.)
>
> With that, each NUMA node gets half of the VCPUs and half of the guest
> RAM.
>
> (This is in a different guest now, one that has a bleeding edge Fedora
> kernel -- I didn't want to rebuild the upstream kernel yet again, just
> for this test. So, "4.9.0-0.rc0.git7.1.fc26.aarch64" is based on
> upstream v4.8-14109-g1573d2c, and it reproduces the problem too.)
>
>> Then when you boot with ACPI you'll get a
>> SRAT.
>
> Yes, that's confirmed by the guest kernel log (see below).
>
>> If that works, then we're just missing the "no SRAT, nid = 0"
>> code (that should have been added with this patch)
>
> It still crashes with the SRAT, with the following log:
>
>> EFI stub: Booting Linux Kernel...
>> ConvertPages: Incompatible memory types
>> EFI stub: Using DTB from configuration table
>> EFI stub: Exiting boot services and installing virtual address map...
>> [    0.000000] Booting Linux on physical CPU 0x0
>> [    0.000000] Linux version 4.9.0-0.rc0.git7.1.fc26.aarch64 (mockbuild at buildvm-aarch64-01.arm.fedoraproject.org) (gcc version 6.2.1 20160916 (Red Hat 6.2.1-2) (GCC) ) #1 SMP Wed Oct 12 17:44:54 UTC 2016
>> [    0.000000] Boot CPU: AArch64 Processor [500f0000]
>> [    0.000000] efi: Getting EFI parameters from FDT:
>> [    0.000000] efi: EFI v2.60 by EDK II
>> [    0.000000] efi:  SMBIOS 3.0=0xbbdb0000  ACPI 2.0=0xb86d0000  MEMATTR=0xb936b018
>> [    0.000000] cma: Reserved 512 MiB at 0x00000000e0000000
>> [    0.000000] ACPI: Early table checksum verification disabled
>> [    0.000000] ACPI: RSDP 0x00000000B86D0000 000024 (v02 BOCHS )
>> [    0.000000] ACPI: XSDT 0x00000000B86C0000 000054 (v01 BOCHS  BXPCFACP 00000001      01000013)
>> [    0.000000] ACPI: FACP 0x00000000B83E0000 00010C (v05 BOCHS  BXPCFACP 00000001 BXPC 00000001)
>> [    0.000000] ACPI: DSDT 0x00000000B83F0000 0010E5 (v02 BOCHS  BXPCDSDT 00000001 BXPC 00000001)
>> [    0.000000] ACPI: APIC 0x00000000B83D0000 00018C (v03 BOCHS  BXPCAPIC 00000001 BXPC 00000001)
>> [    0.000000] ACPI: GTDT 0x00000000B83C0000 000060 (v02 BOCHS  BXPCGTDT 00000001 BXPC 00000001)
>> [    0.000000] ACPI: MCFG 0x00000000B83B0000 00003C (v01 BOCHS  BXPCMCFG 00000001 BXPC 00000001)
>> [    0.000000] ACPI: SPCR 0x00000000B83A0000 000050 (v02 BOCHS  BXPCSPCR 00000001 BXPC 00000001)
>> [    0.000000] ACPI: SRAT 0x00000000B8390000 0000C8 (v03 BOCHS  BXPCSRAT 00000001 BXPC 00000001)
>> [    0.000000] ACPI: SPCR: console: pl011,mmio,0x9000000,9600
>> [    0.000000] earlycon: pl11 at MMIO 0x0000000009000000 (options '9600')
>> [    0.000000] bootconsole [pl11] enabled
>> [    0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x0 -> Node 0
>> [    0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x1 -> Node 0
>> [    0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x2 -> Node 1
>> [    0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x3 -> Node 1
>> [    0.000000] NUMA: Adding memblock [0x40000000 - 0xbfffffff] on node 0
>> [    0.000000] ACPI: SRAT: Node 0 PXM 0 [mem 0x40000000-0xbfffffff]
>> [    0.000000] NUMA: Adding memblock [0xc0000000 - 0x13fffffff] on node 1
>> [    0.000000] ACPI: SRAT: Node 1 PXM 1 [mem 0xc0000000-0x13fffffff]
>> [    0.000000] NUMA: Initmem setup node 0 [mem 0x40000000-0xbfffffff]
>> [    0.000000] NUMA: NODE_DATA [mem 0xbfff2580-0xbfffffff]
>> [    0.000000] NUMA: Initmem setup node 1 [mem 0xc0000000-0x13fffffff]
>> [    0.000000] NUMA: NODE_DATA [mem 0x13fff2580-0x13fffffff]
>> [    0.000000] Zone ranges:
>> [    0.000000]   DMA      [mem 0x0000000040000000-0x00000000ffffffff]
>> [    0.000000]   Normal   [mem 0x0000000100000000-0x000000013fffffff]
>> [    0.000000] Movable zone start for each node
>> [    0.000000] Early memory node ranges
>> [    0.000000]   node   0: [mem 0x0000000040000000-0x00000000b838ffff]
>> [    0.000000]   node   0: [mem 0x00000000b8390000-0x00000000b83fffff]
>> [    0.000000]   node   0: [mem 0x00000000b8400000-0x00000000b841ffff]
>> [    0.000000]   node   0: [mem 0x00000000b8420000-0x00000000b874ffff]
>> [    0.000000]   node   0: [mem 0x00000000b8750000-0x00000000bbc1ffff]
>> [    0.000000]   node   0: [mem 0x00000000bbc20000-0x00000000bbffffff]
>> [    0.000000]   node   0: [mem 0x00000000bc000000-0x00000000bfffffff]
>> [    0.000000]   node   1: [mem 0x00000000c0000000-0x000000013fffffff]
>> [    0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x00000000bfffffff]
>> [    0.000000] Initmem setup node 1 [mem 0x00000000c0000000-0x000000013fffffff]
>> [    0.000000] psci: probing for conduit method from ACPI.
>> [    0.000000] psci: PSCIv0.2 detected in firmware.
>> [    0.000000] psci: Using standard PSCI v0.2 function IDs
>> [    0.000000] psci: Trusted OS migration not required
>> [    0.000000] percpu: Embedded 3 pages/cpu @fffffe007fda0000 s117832 r8192 d70584 u196608
>> [    0.000000] Detected PIPT I-cache on CPU0
>> [    0.000000] Built 2 zonelists in Node order, mobility grouping on.  Total pages: 65472
>> [    0.000000] Policy zone: Normal
>> [    0.000000] Kernel command line: BOOT_IMAGE=/vmlinuz-4.9.0-0.rc0.git7.1.fc26.aarch64 root=/dev/mapper/fedora-root ro rd.lvm.lv=fedora/root rd.lvm.lv=fedora/swap LANG=en_US.UTF-8 earlycon acpi=force
>> [    0.000000] PID hash table entries: 4096 (order: -1, 32768 bytes)
>> [    0.000000] software IO TLB [mem 0xdbff0000-0xdfff0000] (64MB) mapped at [fffffe009bff0000-fffffe009ffeffff]
>> [    0.000000] Memory: 3542976K/4194304K available (9148K kernel code, 1612K rwdata, 3776K rodata, 1600K init, 15899K bss, 127040K reserved, 524288K cma-reserved)
>> [    0.000000] Virtual kernel memory layout:
>> [    0.000000]     modules : 0xfffffc0000000000 - 0xfffffc0008000000   (   128 MB)
>>     vmalloc : 0xfffffc0008000000 - 0xfffffdff5fff0000   (  2045 GB)
>>       .text : 0xfffffc0008080000 - 0xfffffc0008970000   (  9152 KB)
>>     .rodata : 0xfffffc0008970000 - 0xfffffc0008d30000   (  3840 KB)
>>       .init : 0xfffffc0008d30000 - 0xfffffc0008ec0000   (  1600 KB)
>>       .data : 0xfffffc0008ec0000 - 0xfffffc0009053200   (  1613 KB)
>>        .bss : 0xfffffc0009053200 - 0xfffffc0009fda058   ( 15900 KB)
>>     fixed   : 0xfffffdff7e7d0000 - 0xfffffdff7ec00000   (  4288 KB)
>>     PCI I/O : 0xfffffdff7ee00000 - 0xfffffdff7fe00000   (    16 MB)
>>     vmemmap : 0xfffffdff80000000 - 0xfffffe0000000000   (     2 GB maximum)
>>               0xfffffdff80000000 - 0xfffffdff80400000   (     4 MB actual)
>>     memory  : 0xfffffe0000000000 - 0xfffffe0100000000   (  4096 MB)
>> [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=2
>> [    0.000000] Running RCU self tests
>> [    0.000000] Hierarchical RCU implementation.
>> [    0.000000] 	RCU lockdep checking is enabled.
>> [    0.000000] 	Build-time adjustment of leaf fanout to 64.
>> [    0.000000] 	RCU restricting CPUs from NR_CPUS=256 to nr_cpu_ids=4.
>> [    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=64, nr_cpu_ids=4
>> [    0.000000] kmemleak: Kernel memory leak detector disabled
>> [    0.000000] NR_IRQS:64 nr_irqs:64 0
>> [    0.000000] GICv2m: ACPI overriding V2M MSI_TYPER (base:80, num:64)
>> [    0.000000] GICv2m: range[mem 0x08020000-0x08020fff], SPI[80:143]
>> [    0.000000] GIC: PPI11 is secure or misconfigured
>> [    0.000000] arm_arch_timer: WARNING: Invalid trigger for IRQ3, assuming level low
>> [    0.000000] arm_arch_timer: WARNING: Please fix your firmware
>> [    0.000000] arm_arch_timer: Architected cp15 timer(s) running at 50.00MHz (virt).
>> [    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
>> [    0.000003] sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
>> [    0.002198] Console: colour dummy device 80x25
>> [    0.003319] Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar
>> [    0.005236] ... MAX_LOCKDEP_SUBCLASSES:  8
>> [    0.006183] ... MAX_LOCK_DEPTH:          48
>> [    0.007273] ... MAX_LOCKDEP_KEYS:        8191
>> [    0.008287] ... CLASSHASH_SIZE:          4096
>> [    0.009296] ... MAX_LOCKDEP_ENTRIES:     32768
>> [    0.010327] ... MAX_LOCKDEP_CHAINS:      65536
>> [    0.011318] ... CHAINHASH_SIZE:          32768
>> [    0.012453]  memory used by lock dependency info: 8159 kB
>> [    0.013736]  per task-struct memory footprint: 1920 bytes
>> [    0.015742] mempolicy: Enabling automatic NUMA balancing. Configure with numa_balancing= or the kernel.numa_balancing sysctl
>> [    0.018710] Calibrating delay loop (skipped), value calculated using timer frequency.. 100.00 BogoMIPS (lpj=50000)
>> [    0.021221] pid_max: default: 32768 minimum: 301
>> [    0.022806] ACPI: Core revision 20160831
>> [    0.027885] ACPI: 1 ACPI AML tables successfully acquired and loaded
>>
>> [    0.030252] Security Framework initialized
>> [    0.031355] Yama: becoming mindful.
>> [    0.032176] SELinux:  Initializing.
>> [    0.033925] Dentry cache hash table entries: 524288 (order: 6, 4194304 bytes)
>> [    0.037039] Inode-cache hash table entries: 262144 (order: 5, 2097152 bytes)
>> [    0.039383] Mount-cache hash table entries: 8192 (order: 0, 65536 bytes)
>> [    0.041135] Mountpoint-cache hash table entries: 8192 (order: 0, 65536 bytes)
>> [    0.044725] ftrace: allocating 29596 entries in 8 pages
>> [    0.080467] ASID allocator initialised with 65536 entries
>> [    0.082070] ------------[ cut here ]------------
>> [    0.083227] WARNING: CPU: 0 PID: 1 at kernel/workqueue.c:5458 wq_numa_init+0x178/0x21c
>> [    0.085304] Modules linked in:
>> [    0.086102]
>> [    0.086499] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.9.0-0.rc0.git7.1.fc26.aarch64 #1
>> [    0.088611] Hardware name: linux,dummy-virt (DT)
>> [    0.089816] task: fffffe00700aac00 task.stack: fffffe00f8044000
>> [    0.091375] PC is at wq_numa_init+0x178/0x21c
>> [    0.092514] LR is at wq_numa_init+0x14c/0x21c
>> [    0.093654] pc : [<fffffc0008d3f434>] lr : [<fffffc0008d3f408>] pstate: 60000045
>> [    0.095589] sp : fffffe00f8047cb0
>> [    0.096457] x29: fffffe00f8047cb0 [    0.097311] x28: 0000000000000000
>> [    0.098201]
>> [    0.098601] x27: 0000000000000000 [    0.099450] x26: fffffc0008ef4a28
>> [    0.100342]
>> [    0.100730] x25: fffffc0008ef3000 [    0.101576] x24: fffffc0008ef3574
>> [    0.102466]
>> [    0.102853] x23: 0000000000000000 [    0.103700] x22: fffffe007937de00
>> [    0.104593]
>> [    0.104982] x21: fffffc0008e887f8 [    0.105829] x20: fffffc0009091000
>> [    0.106723]
>> [    0.107111] x19: 0000000000000000 [    0.107956] x18: 0000000050642c6a
>> [    0.108847]
>> [    0.109234] x17: 0000000000000000 [    0.110078] x16: 0000000000000000
>> [    0.110968]
>> [    0.111363] x15: 00000000fcacdc89 [    0.112199] x14: 0000000000000000
>> [    0.113087]
>> [    0.113481] x13: 0000000000000000 [    0.114324] x12: 00000000fe2ce6e0
>> [    0.115204]
>> [    0.115597] x11: 0000000000000001 [    0.116439] x10: 0000000000000048
>> [    0.117328]
>> [    0.117716] x9 : 0000000000000000 [    0.118563] x8 : fffffe00f4010080
>> [    0.119453]
>> [    0.119833] x7 : 0000000000000000 [    0.120678] x6 : 0000000000000000
>> [    0.121571]
>> [    0.121959] x5 : 000000000000000f [    0.122804] x4 : 0000000000000000
>> [    0.123695]
>> [    0.124084] x3 : 0000000000000000 [    0.124922] x2 : 0000000000000000
>> [    0.125815]
>> [    0.126204] x1 : 0000000000000004 [    0.127055] x0 : 00000000ffffffff
>> [    0.127966]
>> [    0.128361]
>> [    0.128767] ---[ end trace 0000000000000000 ]---
>> [    0.129983] Call trace:
>> [    0.130629] Exception stack(0xfffffe00f8047ad0 to 0xfffffe00f8047c00)
>> [    0.132316] 7ac0:                                   0000000000000000 0000040000000000
>> [    0.134360] 7ae0: fffffe00f8047cb0 fffffc0008d3f434 0000000060000045 000000000000003d
>> [    0.136405] 7b00: fffffc0008ef4000 fffffe007937df00 0000000000000000 0000000000000000
>> [    0.138446] 7b20: fffffc0008bf4110 0000000000000189 0000000000000018 0000000000000028
>> [    0.140498] 7b40: fffffe00f8047b80 0000000000000000 fffffe0000000000 fffffc000848af30
>> [    0.142541] 7b60: fffffe00f8047ba0 fffffc0008134d24 fffffe00f8044000 0000000000000040
>> [    0.144558] 7b80: 00000000ffffffff 0000000000000004 0000000000000000 0000000000000000
>> [    0.146607] 7ba0: 0000000000000000 000000000000000f 0000000000000000 0000000000000000
>> [    0.148664] 7bc0: fffffe00f4010080 0000000000000000 0000000000000048 0000000000000001
>> [    0.150704] 7be0: 00000000fe2ce6e0 0000000000000000 0000000000000000 00000000fcacdc89
>> [    0.152752] [<fffffc0008d3f434>] wq_numa_init+0x178/0x21c
>> [    0.154160] [<fffffc0008d3f578>] init_workqueues+0xa0/0x4b8
>> [    0.155596] [<fffffc0008083594>] do_one_initcall+0x44/0x138
>> [    0.157059] [<fffffc0008d30d28>] kernel_init_freeable+0x178/0x2dc
>> [    0.158670] [<fffffc0008956f48>] kernel_init+0x18/0x110
>> [    0.160036] [<fffffc0008083330>] ret_from_fork+0x10/0x20
>> [    0.161440] workqueue: NUMA node mapping not available for cpu0, disabling NUMA support
>> [    0.165296] Remapping and enabling EFI services.
>> [    0.166586] Unable to handle kernel paging request at virtual address b91000006be8
>> [    0.168448] pgd = fffffc000a010000
>> [    0.169341] [b91000006be8] *pgd=0000000000000000[    0.170505] , *pud=0000000000000000
>> , *pmd=0000000000000000[    0.171942]
>> [    0.172332] Internal error: Oops: 96000004 [#1] SMP
>> [    0.173600] Modules linked in:
>> [    0.174407] CPU: 0 PID: 1 Comm: swapper/0 Tainted: G        W       4.9.0-0.rc0.git7.1.fc26.aarch64 #1
>> [    0.176836] Hardware name: linux,dummy-virt (DT)
>> [    0.178038] task: fffffe00700aac00 task.stack: fffffe00f8044000
>> [    0.179579] PC is at __ll_sc_atomic_add+0x20/0x40
>> [    0.180800] LR is at __lock_acquire+0xe8/0x698
>> [    0.181961] pc : [<fffffc0008487390>] lr : [<fffffc0008138c08>] pstate: 800000c5
>> [    0.183895] sp : fffffe00f8047820
>> [    0.184755] x29: fffffe00f8047820 [    0.185588] x28: fffffc0008ef3000
>> [    0.186479]
>> [    0.186868] x27: fffffc0008ef2358 [    0.187713] x26: fffffc0009ce6000
>> [    0.188606]
>> [    0.188997] x25: 0000000000000001 [    0.189857] x24: 0000000000000000
>> [    0.190731]
>> [    0.191115] x23: fffffe00700aac00 [    0.191951] x22: 0000000000000000
>> [    0.192843]
>> [    0.193231] x21: fffffe007fd9a018 [    0.194074] x20: 0000000000000000
>> [    0.194966]
>> [    0.195361] x19: fffffe007fd9a018 [    0.196192] x18: 0000000000000010
>> [    0.197077]
>> [    0.197476] x17: 0000000057181979 [    0.198325] x16: 0000000000000000
>> [    0.199209]
>> [    0.199604] x15: 0000000000000000 [    0.200450] x14: 0000000000000000
>> [    0.201337]
>> [    0.201723] x13: 0000000000000001 [    0.202555] x12: fffffe007fff2580
>> [    0.203432]
>> [    0.203819] x11: 0000000000000000 [    0.204664] x10: 0000000000000011
>> [    0.205550]
>> [    0.205937] x9 : 0000000000000001 [    0.206784] x8 : 0000b91000006be8
>> [    0.207678]
>> [    0.208062] x7 : fffffc0008299fcc [    0.208899] x6 : 0000000000000000
>> [    0.209787]
>> [    0.210176] x5 : 0000000000000080 [    0.211022] x4 : 0000b91000006a50
>> [    0.211913]
>> [    0.212307] x3 : 0000000000000000 [    0.213147] x2 : 000022c80000f420
>> [    0.214034]
>> [    0.214421] x1 : 0000b91000006be8 [    0.215251] x0 : fffffc0008138c08
>> [    0.216134]
>> [    0.216527]
>> [    0.216916] Process swapper/0 (pid: 1, stack limit = 0xfffffe00f8044020)
>> [    0.218671] Stack: (0xfffffe00f8047820 to 0xfffffe00f8048000)
>> [    0.220167] 7820: fffffe00f8047840 fffffc0008138c08 fffffe00f8044000 0000000000000001
>> [    0.222190] 7840: fffffe00f80478c0 fffffc0008139590 fffffe007fd9a018 0000000000000000
>> [    0.224238] 7860: 0000000000000000 0000000000000000 0000000000000001 0000000000000000
>> [    0.226284] 7880: fffffc0008299fcc 00000000000000c0 fffffc0008ef2358 fffffc0008ef3000
>> [    0.228318] 78a0: 0000000000000001 fffffc0009ce6000 0000000000000000 fffffe0000000000
>> [    0.230362] 78c0: fffffe00f8047930 fffffc000895f2c4 fffffe007fd9a000 fffffc0008299fcc
>> [    0.232394] 78e0: fffffe007fd9a000 fffffc000829ad94 fffffe007001db00 000000000000e8e8
>> [    0.234435] 7900: fffffe007001db00 fffffe007001dbf8 fffffe00fff3ef50 0000000000000000
>> [    0.236481] 7920: fffffe00f8047a20 fffffc0008ef2000 fffffe00f8047950 fffffc0008299fcc
>> [    0.238516] 7940: 00000000ffffffff fffffe007fd9a000 fffffe00f8047a70 fffffc000829aa68
>> [    0.240560] 7960: 00000000ffffffff 0000000000000001 00000000024000c0 fffffc000829ad94
>> [    0.242604] 7980: 0000000000210d00 000000000000e8e8 fffffe007001db00 fffffe007001dbf8
>> [    0.244634] 79a0: fffffe00fff3ef50 0000000000000000 fffffe00f8044000 0000000000000040
>> [    0.246678] 79c0: fffffc000828d620 fffffc0008ef3000 00000000026080c0 fffffe00fff3ef60
>> [    0.248733] 79e0: fffffe00f8047a00 fffffc00024000c0 fffffc0008f89000 0000000000000000
>> [    0.250783] 7a00: fffffe00f8047a20 fffffc000822f62c fffffc0009016b30 fffffe00f8047b40
>> [    0.252896] 7a20: fffffe00f8047ba0 fffffc000828d620 0000000000000000 fffffc0008ef0b28
>> [    0.255009] 7a40: fffffe007fff3c00 0000000000000000 0000000000000000 0000000000000000
>> [    0.257121] 7a60: fffffe00f8044000 0000000000000000 fffffe00f8047b90 fffffc000829ad94
>> [    0.259240] 7a80: 0000000000000040 fffffe007001db00 00000000024000c0 00000000ffffffff
>> [    0.261358] 7aa0: fffffc0008266284 fffffe00fff3ef50 0000000020000000 00e8000000000f07
>> [    0.263472] 7ac0: 0000000000000000 0000000000000400 fffffc0008f89000 0000000000000000
>> [    0.265662] 7ae0: fffffe00f8047b00 fffffc000822f62c fffffe00fff3ef60 0000000000000000
>> [    0.267787] 7b00: 0000001000000000 fffffc0008266284 fffffe00f8047b50 fffffc0008134d24
>> [    0.269905] 7b20: fffffe00f8044000 0000000000000040 fffffc0008bf4110 0000000000000189
>> [    0.272020] 7b40: fffffc0008ef4000 0000000000000000 fffffe00f8047b70 fffffc000810267c
>> [    0.274136] 7b60: fffffc0009016893 0000000000000000 fffffe00f8047ba0 fffffc0008102784
>> [    0.276250] 7b80: fffffe00f8047b90 fffffc000829ad7c fffffe00f8047bd0 fffffc000829b13c
>> [    0.278371] 7ba0: fffffe007001db00 00000000024000c0 fffffc0008266284 fffffe007001db00
>> [    0.280484] 7bc0: fffffc0008ef4000 0000000000000000 fffffe00f8047c30 fffffc0008266284
>> [    0.282600] 7be0: fffffdff801b0200 fffffe006c080000 000000006c080000 0000000020000000
>> [    0.284715] 7c00: fffffe00f0010008 0000000004000000 0000000020000000 00e8000000000f07
>> [    0.286831] 7c20: 0000000000000000 0000000000000000 fffffe00f8047c50 fffffc0008098e24
>> [    0.288948] 7c40: fffffdff801b0200 0000000000000001 fffffe00f8047c80 fffffc00080991d0
>> [    0.291062] 7c60: 0000000024000000 0000000000000001 0000000024000000 fffffc0008ef0b28
>> [    0.293178] 7c80: fffffe00f8047d00 fffffc0008d361cc fffffe0078416018 00e8000000000707
>> [    0.295296] 7ca0: fffffc0008ff6410 fffffc0008ef7000 0000000000000000 fffffc0008ff6410
>> [    0.297408] 7cc0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>> [    0.299523] 7ce0: 0000000000000000 00e8000000000f05 fffffc0008098dd0 0000000023ffffff
>> [    0.301636] 7d00: fffffe00f8047d10 fffffc0008d35020 fffffe00f8047d40 fffffc0008d88284
>> [    0.303748] 7d20: fffffe0078416018 fffffc0008ff6000 fffffc0008c87348 fffffc0008d8821c
>> [    0.305863] 7d40: fffffe00f8047d90 fffffc0008083594 fffffc0008d88154 fffffe00f8044000
>> [    0.307987] 7d60: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>> [    0.310099] 7d80: 0000000000000000 0000000004000000 fffffe00f8047e00 fffffc0008d30d28
>> [    0.312217] 7da0: fffffc0008e622d8 fffffc0008e622e0 0000000000000040 0000000000000000
>> [    0.314333] 7dc0: fffffe00f8047e00 fffffc0008d30d18 fffffc0008e62220 fffffc0008e622e0
>> [    0.316445] 7de0: 0000000000000040 0000000000000000 0000000000000000 fffffc0008e622e0
>> [    0.318572] 7e00: fffffe00f8047ea0 fffffc0008956f48 fffffc0008956f30 0000000000000000
>> [    0.320692] 7e20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>> [    0.322805] 7e40: 0000000000000000 0000000000000000 0000000000000000 0000000000000001
>> [    0.324914] 7e60: 0000000000000003 0000000000000000 0000000000000000 0000000000000000
>> [    0.327027] 7e80: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>> [    0.329139] 7ea0: 0000000000000000 fffffc0008083330 fffffc0008956f30 0000000000000000
>> [    0.331248] 7ec0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>> [    0.333361] 7ee0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>> [    0.335470] 7f00: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>> [    0.337585] 7f20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>> [    0.339695] 7f40: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>> [    0.341810] 7f60: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>> [    0.343923] 7f80: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>> [    0.346037] 7fa0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>> [    0.348154] 7fc0: 0000000000000000 0000000000000005 0000000000000000 0000000000000000
>> [    0.350272] 7fe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
>> [    0.352392] Call trace:
>> [    0.353049] Exception stack(0xfffffe00f8047650 to 0xfffffe00f8047780)
>> [    0.354792] 7640:                                   fffffe007fd9a018 0000040000000000
>> [    0.356910] 7660: fffffe00f8047820 fffffc0008487390 fffffe00f80476e0 fffffc0008131290
>> [    0.359025] 7680: fffffc000901690b fffffc0008f1e000 0000000000000001 fffffe00700aac00
>> [    0.361140] 76a0: fffffc000901690b fffffc0008f27a28 fffffe00fff3b700 fffffc0008e8b700
>> [    0.363255] 76c0: fffffe00fff3b700 fffffc0008ef1000 fffffe00f80476e0 00000000000000c0
>> [    0.365373] 76e0: fffffe00f8047720 fffffc000811a374 fffffc0008138c08 0000b91000006be8
>> [    0.367483] 7700: 000022c80000f420 0000000000000000 0000b91000006a50 0000000000000080
>> [    0.369593] 7720: 0000000000000000 fffffc0008299fcc 0000b91000006be8 0000000000000001
>> [    0.371702] 7740: 0000000000000011 0000000000000000 fffffe007fff2580 0000000000000001
>> [    0.373817] 7760: 0000000000000000 0000000000000000 0000000000000000 0000000057181979
>> [    0.375935] [<fffffc0008487390>] __ll_sc_atomic_add+0x20/0x40
>> [    0.377489] [<fffffc0008138c08>] __lock_acquire+0xe8/0x698
>> [    0.378960] [<fffffc0008139590>] lock_acquire+0xd8/0x2c0
>> [    0.380394] [<fffffc000895f2c4>] _raw_spin_lock+0x4c/0x60
>> [    0.381843] [<fffffc0008299fcc>] get_partial_node.isra.23+0x4c/0x440
>> [    0.383559] [<fffffc000829aa68>] ___slab_alloc+0x438/0x710
>> [    0.385031] [<fffffc000829ad94>] __slab_alloc+0x54/0xa0
>> [    0.386441] [<fffffc000829b13c>] kmem_cache_alloc+0x35c/0x428
>> [    0.387983] [<fffffc0008266284>] ptlock_alloc+0x2c/0x58
>> [    0.389394] [<fffffc0008098e24>] pgd_pgtable_alloc+0x54/0xd8
>> [    0.390912] [<fffffc00080991d0>] __create_pgd_mapping+0x158/0x2a8
>> [    0.392556] [<fffffc0008d361cc>] create_pgd_mapping+0x30/0x38
>> [    0.394100] [<fffffc0008d35020>] efi_create_mapping+0xfc/0x110
>> [    0.395682] [<fffffc0008d88284>] arm_enable_runtime_services+0x130/0x204
>> [    0.397501] [<fffffc0008083594>] do_one_initcall+0x44/0x138
>> [    0.399001] [<fffffc0008d30d28>] kernel_init_freeable+0x178/0x2dc
>> [    0.400646] [<fffffc0008956f48>] kernel_init+0x18/0x110
>> [    0.402053] [<fffffc0008083330>] ret_from_fork+0x10/0x20
>> [    0.403488] Code: aa1e03e0 aa0103e8 d503201f f9800111 (885f7d00)
>> [    0.405145] ---[ end trace f6be31446b0a9526 ]---
>> [    0.406286] note: swapper/0[1] exited with preempt_count 1
>> [    0.407687] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
>> [    0.407687]
>> [    0.410047] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
>> [    0.410047]
>>
>
> This log contains two call traces. The first is a WARNING in
> wq_numa_init(). The second is the unhandled page fault.
>
> Note the warning message (from wq_numa_init()):
>
>   workqueue: NUMA node mapping not available for cpu0, disabling NUMA support
>
> Something looks genuinely broken with the cpu <-> numa-node
> associations in the ACPI case -- it even seems to fail when the SRAT
> does exist.
>
> So, perhaps, commit 7ba5f605f3a0 may not have introduced the bug, only
> exposed one in the ACPI code?...

Okay, so let me repeat,

  smp_init_cpus()                    [arch/arm64/kernel/smp.c]
    acpi_table_parse_madt()          [drivers/acpi/tables.c]
      acpi_parse_gic_cpu_interface() [arch/arm64/kernel/smp.c]
        acpi_map_gic_cpu_interface() [arch/arm64/kernel/smp.c]
          early_map_cpu_to_node()    [arch/arm64/mm/numa.c]

We have acpi_map_gic_cpu_interface() being called for each GICC
structure in the MADT (signature "APIC"). This function is supposed to
set up a number of things for the CPU found, including its association
with a NUMA node. This should happen even if we have only one node (no
SRAT), and it should happen for CPU#0 as well.

acpi_map_gic_cpu_interface() uses the global variable "cpu_count" like
this:
(a) on input, it is the number of CPUs found previously, that is, the
    logical identifier of the CPU being added presently,
(b) on output, it is bumped by one, if the CPU got added / parsed
    correctly,
(c) in-between, we have expressions like:

> 	if (is_mpidr_duplicate(cpu_count, hwid)) {
> 		pr_err("duplicate CPU MPIDR 0x%llx in MADT\n", hwid);
> 		return;
> 	}

and

> 	if (cpu_count >= NR_CPUS)
> 		return;

(note: this implies that NR_CPUS is an exclusive limit)

and -- importantly --

> 	/* map the logical cpu id to cpu MPIDR */
> 	cpu_logical_map(cpu_count) = hwid;

and -- even more importantly --

> 	early_map_cpu_to_node(cpu_count, acpi_numa_get_nid(cpu_count, hwid));

A whole bunch of stuff seems to be wrong with this, when we try to
interpret it for CPU#0. Such as:

(1) the global variable "cpu_count" is initialized to one, not zero.
This dates back to the following commit:

> commit 0f0783365cbb7ec13a8f02198f6e1a146d94a5a9
> Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Date:   Wed May 13 14:12:47 2015 +0100
>
>     ARM64: kernel: unify ACPI and DT cpus initialization

It means that none of the above checks and assignments will be performed
for CPU#0.

It also means that should we actually find NR_CPUs CPUs, the last one
will be rejected, because at that point, cpu_count will equal NR_CPUs
*on input*.

(2) On arm64, cpu_logical_map() is implemented like this
[arch/arm64/include/asm/smp_plat.h]:

> /*
>  * Logical CPU mapping.
>  */
> extern u64 __cpu_logical_map[NR_CPUS];
> #define cpu_logical_map(cpu)    __cpu_logical_map[cpu]

So this is the declaration. The definition is back in
"arch/arm64/kernel/setup.c":

> u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };

where INVALID_HWID is ULONG_MAX.

This implies that

> 	/* map the logical cpu id to cpu MPIDR */
> 	cpu_logical_map(cpu_count) = hwid;

will never store a hwid different from INVALID_HWID to
__cpu_logical_map[0], because "cpu_count" -- the offset into that array,
for the assignment -- is never zero.

(3) early_map_cpu_to_node() will never set cpu_to_node_map[0] to any
NUMA node ID.

(If early_map_cpu_to_node() was called with cpu_count==0 (correctly), it
would call set_cpu_numa_node(), due to the change implemented by
7ba5f605f3a0:

> 	/*
> 	 * We should set the numa node of cpu0 as soon as possible, because it
> 	 * has already been set up online before. cpu_to_node(0) will soon be
> 	 * called.
> 	 */
> 	if (!cpu)
> 		set_cpu_numa_node(cpu, nid);

but I don't know what that would suffice for.)

(4) The acpi_numa_get_nid() function deserves separate treatment:

> int acpi_numa_get_nid(unsigned int cpu, u64 hwid)
> {
> 	int i;
>
> 	for (i = 0; i < cpus_in_srat; i++) {
> 		if (hwid == early_node_cpu_hwid[i].cpu_hwid)
> 			return early_node_cpu_hwid[i].node_id;
> 	}
>
> 	return NUMA_NO_NODE;
> }

So,

(4a) if we have no SRAT (because there's only one NUMA node), then this
function will invariably return NUMA_NO_NODE (value -1), which means
that *even if* early_map_cpu_to_node() was called with cpu_count==0
(which it is not, see (3) above), the assigned NUMA node ID would still
be NUMA_NO_NODE. That's wrong, it should be zero.

(4b) The acpi_numa_get_nid() function completely ignores its first
parameter, called "cpu" (set from "cpu_count" at the call site). This
has been the case since the birth of that function, namely

> commit d8b47fca8c233642d1a20fa4025579ebc8be6f1e
> Author: Hanjun Guo <hanjun.guo@linaro.org>
> Date:   Tue May 24 15:35:44 2016 -0700
>
>     arm64, ACPI, NUMA: NUMA support based on SRAT and SLIT

I guess if that parameter is unnecessary, it should be removed.


I'm sorry but I can't even begin to untangle this mess. Maybe the code I
tried to analyze in this email was never *meant* to associate CPU#0 with
any NUMA node at all (not even node 0); instead, other code -- for
example code removed by 7ba5f605f3a0 -- was meant to perform that
association.

If that's the case, then the code I listed here might even be correct,
for CPUs with logical IDs >= 1. The initialization of "cpu_count" to 1
does suggest that CPU#0 was never meant to be handled by
acpi_map_gic_cpu_interface(). I can't tell.

What I can tell is that 7ba5f605f3a0 breaks the ACPI boot. So
- either (parts of) it should be reverted please,
- or the ACPI boot path should be extended please, so that it handles
  CPU#0 as well (associating it with NUMA node #0 if there is no SRAT,
  and NUMA node #whatever, if there's an SRAT saying so).

Thanks,
Laszlo

^ permalink raw reply

* [PATCH 2/3] thermal: tango: Fix module autoload
From: Marc Gonzalez @ 2016-10-14 15:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476455702-21748-3-git-send-email-javier@osg.samsung.com>

On 14/10/2016 16:35, Javier Martinez Canillas wrote:

> If the driver is built as a module, autoload won't work because the module
> alias information is not filled. So user-space can't match the registered
> device with the corresponding module.
> 
> Export the module alias information using the MODULE_DEVICE_TABLE() macro.
> 
> Before this patch:
> 
> $ modinfo drivers/thermal/tango_thermal.ko | grep alias
> $
> 
> After this patch:
> 
> $ modinfo drivers/thermal/tango_thermal.ko | grep alias
> alias:          of:N*T*Csigma,smp8758-thermalC*
> alias:          of:N*T*Csigma,smp8758-thermal
> 
> Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
> ---
> 
>  drivers/thermal/tango_thermal.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/thermal/tango_thermal.c b/drivers/thermal/tango_thermal.c
> index 201304aeafeb..4e67795cb6ce 100644
> --- a/drivers/thermal/tango_thermal.c
> +++ b/drivers/thermal/tango_thermal.c
> @@ -107,6 +107,7 @@ static const struct of_device_id tango_sensor_ids[] = {
>  	},
>  	{ /* sentinel */ }
>  };
> +MODULE_DEVICE_TABLE(of, tango_sensor_ids);

Thanks for fixing it :-)

Acked-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>

Regards.

^ permalink raw reply

* aarch64 ACPI boot regressed by commit 7ba5f605f3a0 ("arm64/numa: remove the limitation that cpu0 must bind to node0")
From: Laszlo Ersek @ 2016-10-14 15:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <d26ea7ca-6b65-b3a6-591e-ab892f1815e7@redhat.com>

On 10/14/16 17:01, Laszlo Ersek wrote:

> Maybe the code I
> tried to analyze in this email was never *meant* to associate CPU#0 with
> any NUMA node at all (not even node 0); instead, other code -- for
> example code removed by 7ba5f605f3a0 -- was meant to perform that
> association.

Staring a bit more at the code, this looks very likely; in acpi_map_gic_cpu_interface() we have

> 	/* Check if GICC structure of boot CPU is available in the MADT */
> 	if (cpu_logical_map(0) == hwid) {
> 		if (bootcpu_valid) {
> 			pr_err("duplicate boot CPU MPIDR: 0x%llx in MADT\n",
> 			       hwid);
> 			return;
> 		}
> 		bootcpu_valid = true;
> 		return;
> 	}

which means that this callback function (for parsing the GICC structures in the MADT) expects to find the boot processor as well.

Upon finding the boot processor, we set bootcpu_valid to true, and that's it -- no association with any NUMA node, and no incrementing of "cpu_count".

Thanks
Laszlo

^ permalink raw reply

* aarch64 ACPI boot regressed by commit 7ba5f605f3a0 ("arm64/numa: remove the limitation that cpu0 must bind to node0")
From: Lorenzo Pieralisi @ 2016-10-14 15:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <b8b58d52-691c-11f0-2d26-a51e03430771@redhat.com>

On Fri, Oct 14, 2016 at 05:27:58PM +0200, Laszlo Ersek wrote:
> On 10/14/16 17:01, Laszlo Ersek wrote:
> 
> > Maybe the code I
> > tried to analyze in this email was never *meant* to associate CPU#0 with
> > any NUMA node at all (not even node 0); instead, other code -- for
> > example code removed by 7ba5f605f3a0 -- was meant to perform that
> > association.
> 
> Staring a bit more at the code, this looks very likely; in acpi_map_gic_cpu_interface() we have
> 
> > 	/* Check if GICC structure of boot CPU is available in the MADT */
> > 	if (cpu_logical_map(0) == hwid) {
> > 		if (bootcpu_valid) {
> > 			pr_err("duplicate boot CPU MPIDR: 0x%llx in MADT\n",
> > 			       hwid);
> > 			return;
> > 		}
> > 		bootcpu_valid = true;
> > 		return;
> > 	}
> 
> which means that this callback function (for parsing the GICC
> structures in the MADT) expects to find the boot processor as well.
> 
> Upon finding the boot processor, we set bootcpu_valid to true, and
> that's it -- no association with any NUMA node, and no incrementing of
> "cpu_count".

Yes, because that's to check the MADT contains the boot cpu hwid.

Does this help (compile tested only) ?

-- >8 -- 
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index d3f151c..8507703 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -544,6 +544,7 @@ static int __init smp_cpu_setup(int cpu)
 			return;
 		}
 		bootcpu_valid = true;
+		early_map_cpu_to_node(0, acpi_numa_get_nid(0, hwid));
 		return;
 	}
 

^ permalink raw reply related

* aarch64 ACPI boot regressed by commit 7ba5f605f3a0 ("arm64/numa: remove the limitation that cpu0 must bind to node0")
From: Laszlo Ersek @ 2016-10-14 15:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161014134411.cgba46xpznceucta@hawk.localdomain>

On 10/14/16 15:44, Andrew Jones wrote:
> On Fri, Oct 14, 2016 at 03:18:00PM +0200, Laszlo Ersek wrote:
>> On 10/14/16 10:05, Andrew Jones wrote:
>>> On Fri, Oct 14, 2016 at 12:50:29AM +0200, Laszlo Ersek wrote:
>>>> (4) Analysis (well, a lame attempt at that, because I have zero
>>>> familiarity with this code). Let me quote the patch:
>>>>
>>>>> commit 7ba5f605f3a0d9495aad539eeb8346d726dfc183
>>>>> Author: Zhen Lei <thunder.leizhen@huawei.com>
>>>>> Date:   Thu Sep 1 14:55:04 2016 +0800
>>>>>
>>>>>     arm64/numa: remove the limitation that cpu0 must bind to node0
>>>>>
>>>>>     1. Remove the old binding code.
>>>>>     2. Read the nid of cpu0 from dts.
>>>>>     3. Fallback the nid of cpu0 to 0 when numa=off is set in bootargs.
>>>>>
>>>>>     Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
>>>>>     Signed-off-by: Will Deacon <will.deacon@arm.com>
>>>>>
>>>>> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
>>>>> index c3c08368a685..8b048e6ec34a 100644
>>>>> --- a/arch/arm64/kernel/smp.c
>>>>> +++ b/arch/arm64/kernel/smp.c
>>>>> @@ -624,6 +624,7 @@ static void __init of_parse_and_init_cpus(void)
>>>>>  			}
>>>>>
>>>>>  			bootcpu_valid = true;
>>>>> +			early_map_cpu_to_node(0, of_node_to_nid(dn));
>>>>>
>>>>>  			/*
>>>>>  			 * cpu_logical_map has already been
>>>>> diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
>>>>> index 0a15f010b64a..778a985c8a70 100644
>>>>> --- a/arch/arm64/mm/numa.c
>>>>> +++ b/arch/arm64/mm/numa.c
>>>>> @@ -116,16 +116,24 @@ static void __init setup_node_to_cpumask_map(void)
>>>>>   */
>>>>>  void numa_store_cpu_info(unsigned int cpu)
>>>>>  {
>>>>> -	map_cpu_to_node(cpu, numa_off ? 0 : cpu_to_node_map[cpu]);
>>>>> +	map_cpu_to_node(cpu, cpu_to_node_map[cpu]);
>>>>>  }
>>>>>
>>>>>  void __init early_map_cpu_to_node(unsigned int cpu, int nid)
>>>>>  {
>>>>>  	/* fallback to node 0 */
>>>>> -	if (nid < 0 || nid >= MAX_NUMNODES)
>>>>> +	if (nid < 0 || nid >= MAX_NUMNODES || numa_off)
>>>>>  		nid = 0;
>>>
>>> The ACPI equivalent code must be missing (at least) the above, because,
>>> even with DT, mach-virt won't have cpu to node mappings unless numa
>>> is configured on the command line. Can you try adding something like
>>>
>>>     -m 512 -smp 4 \
>>>     -numa node,mem=256M,cpus=0-1,nodeid=0 \
>>>     -numa node,mem=256M,cpus=2-3,nodeid=1
>>>
>>> to your QEMU command line?
>>
>> I added the following to my domain XML, under <cpu>:
>>
>>     <numa>
>>       <cell id='0' cpus='0-1' memory='2097152' unit='KiB'/>
>>       <cell id='1' cpus='2-3' memory='2097152' unit='KiB'/>
>>     </numa>
>>
>> (See <http://libvirt.org/formatdomain.html#elementsCPU>.)
>>
>> With that, each NUMA node gets half of the VCPUs and half of the guest RAM.
>>
>> (This is in a different guest now, one that has a bleeding edge Fedora kernel -- I didn't want to rebuild the upstream kernel yet again, just for this test. So, "4.9.0-0.rc0.git7.1.fc26.aarch64" is based on upstream v4.8-14109-g1573d2c, and it reproduces the problem too.)
>>
>>> Then when you boot with ACPI you'll get a
>>> SRAT.
>>
>> Yes, that's confirmed by the guest kernel log (see below).
>>
>>> If that works, then we're just missing the "no SRAT, nid = 0"
>>> code (that should have been added with this patch)
>>
>> It still crashes with the SRAT, with the following log:
> 
> Rats.
> 
>> Note the warning message (from wq_numa_init()):
>>
>>   workqueue: NUMA node mapping not available for cpu0, disabling NUMA support
>>
>> Something looks genuinely broken with the cpu <-> numa-node associations in the ACPI case -- it even seems to fail when the SRAT does exist.
>>
>> So, perhaps, commit 7ba5f605f3a0 may not have introduced the bug, only exposed one in the ACPI code?...
> 
> The kernel's ACPI NUMA support used to work. It was the test case for
> QEMU's SRAT generation code.
> 
> Two more experiments I wouldn't mind having you try, if you have time;
>  1) confirm that this NUMA configured guest and this latest kernel works
>     with DT. This is just for sanity, but I guess it will.

Yes, it boots fine. It's at v4.8-14604-g29fbff8.

>  2) If (1) succeeds, then try the last-known-good kernel with ACPI again,
>     but this time with the NUMA configured guest.

v4.8, which was my known-good starting point in the acpi=force bisection -- at that time without using a NUMA configuration --, also boots fine under this two-node NUMA configuration, using acpi=force:

> EFI stub: Booting Linux Kernel...
> EFI stub: Using DTB from configuration table
> EFI stub: Exiting boot services and installing virtual address map...
> [    0.000000] Booting Linux on physical CPU 0x0
> [    0.000000] Linux version 4.8.0 (root at aarch64-vgpu-1) (gcc version 6.2.1 20160916 (Red Hat 6.2.1-2) (GCC) ) #2 SMP Thu Oct 13 17:17:59 CEST 2016
> [    0.000000] Boot CPU: AArch64 Processor [500f0000]
> [    0.000000] earlycon: pl11 at MMIO 0x0000000009000000 (options '')
> [    0.000000] bootconsole [pl11] enabled
> [    0.000000] debug: ignoring loglevel setting.
> [    0.000000] efi: Getting EFI parameters from FDT:
> [    0.000000] efi: EFI v2.60 by EDK II
> [    0.000000] efi:  SMBIOS 3.0=0x13bdb0000  ACPI 2.0=0x1386d0000  MEMATTR=0x13a665018
> [    0.000000] cma: Reserved 512 MiB at 0x00000000c0000000
> [    0.000000] ACPI: Early table checksum verification disabled
> [    0.000000] ACPI: RSDP 0x00000001386D0000 000024 (v02 BOCHS )
> [    0.000000] ACPI: XSDT 0x00000001386C0000 000054 (v01 BOCHS  BXPCFACP 00000001      01000013)
> [    0.000000] ACPI: FACP 0x0000000138410000 00010C (v05 BOCHS  BXPCFACP 00000001 BXPC 00000001)
> [    0.000000] ACPI: DSDT 0x0000000138420000 001159 (v02 BOCHS  BXPCDSDT 00000001 BXPC 00000001)
> [    0.000000] ACPI: APIC 0x0000000138400000 0002BC (v03 BOCHS  BXPCAPIC 00000001 BXPC 00000001)
> [    0.000000] ACPI: GTDT 0x00000001383F0000 000060 (v02 BOCHS  BXPCGTDT 00000001 BXPC 00000001)
> [    0.000000] ACPI: MCFG 0x00000001383E0000 00003C (v01 BOCHS  BXPCMCFG 00000001 BXPC 00000001)
> [    0.000000] ACPI: SPCR 0x00000001383D0000 000050 (v02 BOCHS  BXPCSPCR 00000001 BXPC 00000001)
> [    0.000000] ACPI: SRAT 0x00000001383C0000 000110 (v03 BOCHS  BXPCSRAT 00000001 BXPC 00000001)
> [    0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x0 -> Node 0
> [    0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x1 -> Node 0
> [    0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x2 -> Node 0
> [    0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x3 -> Node 0
> [    0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x4 -> Node 1
> [    0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x5 -> Node 1
> [    0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x6 -> Node 1
> [    0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x7 -> Node 1
> [    0.000000] NUMA: Adding memblock [0x40000000 - 0x13fffffff] on node 0
> [    0.000000] ACPI: SRAT: Node 0 PXM 0 [mem 0x40000000-0x13fffffff]
> [    0.000000] NUMA: Adding memblock [0x140000000 - 0x23fffffff] on node 1
> [    0.000000] ACPI: SRAT: Node 1 PXM 1 [mem 0x140000000-0x23fffffff]
> [    0.000000] NUMA: Initmem setup node 0 [mem 0x40000000-0x13fffffff]
> [    0.000000] NUMA: NODE_DATA [mem 0x13fff2580-0x13fffffff]
> [    0.000000] NUMA: Initmem setup node 1 [mem 0x140000000-0x23fffffff]
> [    0.000000] NUMA: NODE_DATA [mem 0x23fff2580-0x23fffffff]
> [    0.000000] Zone ranges:
> [    0.000000]   DMA      [mem 0x0000000040000000-0x00000000ffffffff]
> [    0.000000]   Normal   [mem 0x0000000100000000-0x000000023fffffff]
> [    0.000000] Movable zone start for each node
> [    0.000000] Early memory node ranges
> [    0.000000]   node   0: [mem 0x0000000040000000-0x00000000fffeffff]
> [    0.000000]   node   0: [mem 0x00000000ffff0000-0x00000000ffffffff]
> [    0.000000]   node   0: [mem 0x0000000100000000-0x00000001383bffff]
> [    0.000000]   node   0: [mem 0x00000001383c0000-0x000000013874ffff]
> [    0.000000]   node   0: [mem 0x0000000138750000-0x000000013bc1ffff]
> [    0.000000]   node   0: [mem 0x000000013bc20000-0x000000013bffffff]
> [    0.000000]   node   0: [mem 0x000000013c000000-0x000000013fffffff]
> [    0.000000]   node   1: [mem 0x0000000140000000-0x000000023fffffff]
> [    0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000013fffffff]
> [    0.000000] On node 0 totalpages: 65536
> [    0.000000]   DMA zone: 48 pages used for memmap
> [    0.000000]   DMA zone: 0 pages reserved
> [    0.000000]   DMA zone: 49152 pages, LIFO batch:1
> [    0.000000]   Normal zone: 16 pages used for memmap
> [    0.000000]   Normal zone: 16384 pages, LIFO batch:1
> [    0.000000] Initmem setup node 1 [mem 0x0000000140000000-0x000000023fffffff]
> [    0.000000] On node 1 totalpages: 65536
> [    0.000000]   Normal zone: 64 pages used for memmap
> [    0.000000]   Normal zone: 65536 pages, LIFO batch:1
> [    0.000000] psci: probing for conduit method from ACPI.
> [    0.000000] psci: PSCIv0.2 detected in firmware.
> [    0.000000] psci: Using standard PSCI v0.2 function IDs
> [    0.000000] psci: Trusted OS migration not required
> [    0.000000] percpu: Embedded 3 pages/cpu @fffffe01ffdc0000 s117320 r8192 d71096 u196608
> [    0.000000] pcpu-alloc: s117320 r8192 d71096 u196608 alloc=3*65536
> [    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0] 4 [0] 5 [0] 6 [0] 7
> [    0.000000] Detected PIPT I-cache on CPU0
> [    0.000000] Built 2 zonelists in Node order, mobility grouping on.  Total pages: 130944
> [    0.000000] Policy zone: Normal
> [    0.000000] Kernel command line: BOOT_IMAGE=/vmlinuz-4.8.0 root=/dev/mapper/fedora-root ro rd.lvm.lv=fedora/root rd.lvm.lv=fedora/swap console=ttyAMA0 earlyprintk=pl011,0x9000000 earlycon ignore_loglevel acpi=force
> [    0.000000] PID hash table entries: 4096 (order: -1, 32768 bytes)
> [    0.000000] software IO TLB [mem 0xfbfe0000-0xfffe0000] (64MB) mapped at [fffffe00bbfe0000-fffffe00bffdffff]
> [    0.000000] Memory: 7717184K/8388608K available (8956K kernel code, 1565K rwdata, 3712K rodata, 1536K init, 15876K bss, 147136K reserved, 524288K cma-reserved)
> [    0.000000] Virtual kernel memory layout:
> [    0.000000]     modules : 0xfffffc0000000000 - 0xfffffc0008000000   (   128 MB)
> [    0.000000]     vmalloc : 0xfffffc0008000000 - 0xfffffdff5fff0000   (  2045 GB)
> [    0.000000]       .text : 0xfffffc0008080000 - 0xfffffc0008940000   (  8960 KB)
> [    0.000000]     .rodata : 0xfffffc0008940000 - 0xfffffc0008cf0000   (  3776 KB)
> [    0.000000]       .init : 0xfffffc0008cf0000 - 0xfffffc0008e70000   (  1536 KB)
> [    0.000000]       .data : 0xfffffc0008e70000 - 0xfffffc0008ff7400   (  1565 KB)
> [    0.000000]        .bss : 0xfffffc0008ff7400 - 0xfffffc0009f78628   ( 15877 KB)
> [    0.000000]     fixed   : 0xfffffdff7e7d0000 - 0xfffffdff7ec00000   (  4288 KB)
> [    0.000000]     PCI I/O : 0xfffffdff7ee00000 - 0xfffffdff7fe00000   (    16 MB)
> [    0.000000]     vmemmap : 0xfffffdff80000000 - 0xfffffe0000000000   (     2 GB maximum)
> [    0.000000]               0xfffffdff80000000 - 0xfffffdff80800000   (     8 MB actual)
> [    0.000000]     memory  : 0xfffffe0000000000 - 0xfffffe0200000000   (  8192 MB)
> [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=8, Nodes=2
> [    0.000000] Running RCU self tests
> [    0.000000] Hierarchical RCU implementation.
> [    0.000000] 	RCU lockdep checking is enabled.
> [    0.000000] 	Build-time adjustment of leaf fanout to 64.
> [    0.000000] 	RCU restricting CPUs from NR_CPUS=256 to nr_cpu_ids=8.
> [    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=64, nr_cpu_ids=8
> [    0.000000] kmemleak: Kernel memory leak detector disabled
> [    0.000000] NR_IRQS:64 nr_irqs:64 0
> [    0.000000] GICv2m: ACPI overriding V2M MSI_TYPER (base:80, num:64)
> [    0.000000] GICv2m: range[mem 0x08020000-0x08020fff], SPI[80:143]
> [    0.000000] GIC: PPI11 is secure or misconfigured
> [    0.000000] arm_arch_timer: WARNING: Invalid trigger for IRQ3, assuming level low
> [    0.000000] arm_arch_timer: WARNING: Please fix your firmware
> [    0.000000] arm_arch_timer: Architected cp15 timer(s) running at 50.00MHz (virt).
> [    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0xb8812736b, max_idle_ns: 440795202655 ns
> [    0.000002] sched_clock: 56 bits at 50MHz, resolution 20ns, wraps every 4398046511100ns
> [    0.002263] Console: colour dummy device 80x25
> [    0.003385] Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar
> [    0.005291] ... MAX_LOCKDEP_SUBCLASSES:  8
> [    0.006233] ... MAX_LOCK_DEPTH:          48
> [    0.007335] ... MAX_LOCKDEP_KEYS:        8191
> [    0.008339] ... CLASSHASH_SIZE:          4096
> [    0.009334] ... MAX_LOCKDEP_ENTRIES:     32768
> [    0.010497] ... MAX_LOCKDEP_CHAINS:      65536
> [    0.011517] ... CHAINHASH_SIZE:          32768
> [    0.012541]  memory used by lock dependency info: 8159 kB
> [    0.013810]  per task-struct memory footprint: 1920 bytes
> [    0.015809] mempolicy: Enabling automatic NUMA balancing. Configure with numa_balancing= or the kernel.numa_balancing sysctl
> [    0.018762] Calibrating delay loop (skipped), value calculated using timer frequency.. 100.00 BogoMIPS (lpj=50000)
> [    0.021262] pid_max: default: 32768 minimum: 301
> [    0.022804] ACPI: Core revision 20160422
> [    0.027895] ACPI: 1 ACPI AML tables successfully acquired and loaded
> [    0.029485]
> [    0.030614] Security Framework initialized
> [    0.031599] Yama: becoming mindful.
> [    0.032422] SELinux:  Initializing.
> [    0.033949] SELinux:  Starting in permissive mode
> [    0.035498] Dentry cache hash table entries: 1048576 (order: 7, 8388608 bytes)
> [    0.039287] Inode-cache hash table entries: 524288 (order: 6, 4194304 bytes)
> [    0.042406] Mount-cache hash table entries: 16384 (order: 1, 131072 bytes)
> [    0.044138] Mountpoint-cache hash table entries: 16384 (order: 1, 131072 bytes)
> [    0.047820] ftrace: allocating 28926 entries in 8 pages
> [    0.082086] ASID allocator initialised with 65536 entries
> [    0.086231] Remapping and enabling EFI services.
> [    0.087582]   EFI remap 0x0000000004000000 => 0000000020000000
> [    0.089058]   EFI remap 0x0000000009010000 => 0000000024000000
> [    0.090486]   EFI remap 0x0000000138430000 => 0000000024010000
> [    0.091877]   EFI remap 0x0000000138490000 => 0000000024070000
> [    0.093269]   EFI remap 0x00000001384e0000 => 00000000240c0000
> [    0.094687]   EFI remap 0x0000000138530000 => 0000000024110000
> [    0.096076]   EFI remap 0x0000000138580000 => 0000000024160000
> [    0.097471]   EFI remap 0x00000001385d0000 => 00000000241b0000
> [    0.098855]   EFI remap 0x0000000138620000 => 0000000024200000
> [    0.100243]   EFI remap 0x0000000138670000 => 0000000024250000
> [    0.101638]   EFI remap 0x00000001386e0000 => 00000000242a0000
> [    0.103022]   EFI remap 0x000000013bc20000 => 0000000024310000
> [    0.104420]   EFI remap 0x000000013bdb0000 => 00000000244a0000
> [    0.120433] Detected PIPT I-cache on CPU1
> [    0.120539] CPU1: Booted secondary processor [500f0000]
> [    0.134831] Detected PIPT I-cache on CPU2
> [    0.134918] CPU2: Booted secondary processor [500f0000]
> [    0.149136] Detected PIPT I-cache on CPU3
> [    0.149226] CPU3: Booted secondary processor [500f0000]
> [    0.163487] Detected PIPT I-cache on CPU4
> [    0.163576] CPU4: Booted secondary processor [500f0000]
> [    0.177837] Detected PIPT I-cache on CPU5
> [    0.177926] CPU5: Booted secondary processor [500f0000]
> [    0.192172] Detected PIPT I-cache on CPU6
> [    0.192260] CPU6: Booted secondary processor [500f0000]
> [    0.206722] Detected PIPT I-cache on CPU7
> [    0.206811] CPU7: Booted secondary processor [500f0000]
> [    0.207003] Brought up 8 CPUs
> [    0.223904] SMP: Total of 8 processors activated.
> [    0.225110] CPU features: detected feature: 32-bit EL0 Support
> [    0.226534] CPU: All CPU(s) started at EL1
> [    0.319814] devtmpfs: initialized
> [    0.321977] SMBIOS 3.0.0 present.
> [    0.323394] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1911260446275000 ns
> [    0.331773] atomic64_test: passed
> [    0.332749] pinctrl core: initialized pinctrl subsystem
> [    0.335763] NET: Registered protocol family 16
> [    0.342141] cpuidle: using governor menu
> [    0.343192] PCCT header not found.
> [    0.344082] vdso: 2 pages (1 code @ fffffc0008960000, 1 data @ fffffc0008e90000)
> [    0.346114] hw-breakpoint: found 4 breakpoint and 4 watchpoint registers.
> [    0.349683] DMA: preallocated 256 KiB pool for atomic allocations
> [    0.351473] ACPI: bus type PCI registered
> [    0.352483] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5
> [    0.354595] Serial: AMBA PL011 UART driver
> [    0.373196] HugeTLB registered 2 MB page size, pre-allocated 0 pages
> [    0.374902] HugeTLB registered 512 MB page size, pre-allocated 0 pages
> [    0.380062] ACPI: Added _OSI(Module Device)
> [    0.381157] ACPI: Added _OSI(Processor Device)
> [    0.382200] ACPI: Added _OSI(3.0 _SCP Extensions)
> [    0.383303] ACPI: Added _OSI(Processor Aggregator Device)
> [    0.392501] ACPI: Interpreter enabled
> [    0.393484] ACPI: Using GIC for interrupt routing
> [    0.394751] ACPI: MCFG table detected, 1 entries
> [    0.414519] ARMH0011:00: ttyAMA0 at MMIO 0x9000000 (irq = 5, base_baud = 0) is a SBSA
> [    0.416591] console [ttyAMA0] enabled
> [    0.416591] console [ttyAMA0] enabled
> [    0.418231] bootconsole [pl11] disabled
> [    0.418231] bootconsole [pl11] disabled
> [    0.428624] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-0f])
> [    0.429962] acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI]
> [    0.432827] acpi PNP0A08:00: _OSC: OS now controls [PCIeHotplug PME AER PCIeCapability]
> [    0.434477] acpi PNP0A08:00: ECAM at [mem 0x3f000000-0x3fffffff] for [bus 00-0f]
> [    0.436078] Remapped I/O 0x000000003eff0000 to [io  0x0000-0xffff window]
> [    0.438129] PCI host bridge to bus 0000:00
> [    0.438987] pci_bus 0000:00: root bus resource [mem 0x10000000-0x3efeffff window]
> [    0.440462] pci_bus 0000:00: root bus resource [io  0x0000-0xffff window]
> [    0.441750] pci_bus 0000:00: root bus resource [mem 0x8000000000-0xffffffffff window]
> [    0.443252] pci_bus 0000:00: root bus resource [bus 00-0f]
> [    0.444377] pci 0000:00:00.0: [1b36:0008] type 00 class 0x060000
> [    0.446402] pci 0000:00:01.0: [8086:3420] type 01 class 0x060400
> [    0.489217] pci 0000:00:01.1: [8086:3420] type 01 class 0x060400
> [    0.528741] pci 0000:00:01.2: [8086:3420] type 01 class 0x060400
> [    0.567928] pci 0000:00:01.3: [8086:3420] type 01 class 0x060400
> [    0.613634] pci 0000:01:00.0: [1033:0194] type 00 class 0x0c0330
> [    0.614948] pci 0000:01:00.0: reg 0x10: [mem 0x10300000-0x10303fff 64bit]
> [    0.631100] pci 0000:02:00.0: [1af4:1048] type 00 class 0x010000
> [    0.679413] pci 0000:02:00.0: reg 0x14: [mem 0x10200000-0x10200fff]
> [    0.752358] pci 0000:02:00.0: reg 0x20: [mem 0x8000000000-0x80007fffff 64bit pref]
> [    0.793032] pci 0000:03:00.0: [1af4:1041] type 00 class 0x020000
> [    0.841238] pci 0000:03:00.0: reg 0x14: [mem 0x10100000-0x10100fff]
> [    0.914350] pci 0000:03:00.0: reg 0x20: [mem 0x8000800000-0x8000ffffff 64bit pref]
> [    0.939819] pci 0000:03:00.0: reg 0x30: [mem 0xfffc0000-0xffffffff pref]
> [    0.956386] pci 0000:04:00.0: [1af4:1050] type 00 class 0x038000
> [    1.004617] pci 0000:04:00.0: reg 0x14: [mem 0x10000000-0x10000fff]
> [    1.077643] pci 0000:04:00.0: reg 0x20: [mem 0x8001000000-0x80017fffff 64bit pref]
> [    1.213423] pci 0000:00:01.1: BAR 15: assigned [mem 0x8000000000-0x80007fffff 64bit pref]
> [    1.215037] pci 0000:00:01.2: BAR 15: assigned [mem 0x8000800000-0x8000ffffff 64bit pref]
> [    1.216626] pci 0000:00:01.3: BAR 15: assigned [mem 0x8001000000-0x80017fffff 64bit pref]
> [    1.219273] pci 0000:00:01.0: BAR 14: assigned [mem 0x10000000-0x101fffff]
> [    1.220663] pci 0000:00:01.0: BAR 15: assigned [mem 0x8001800000-0x80019fffff 64bit pref]
> [    1.222265] pci 0000:00:01.1: BAR 14: assigned [mem 0x10200000-0x103fffff]
> [    1.223605] pci 0000:00:01.2: BAR 14: assigned [mem 0x10400000-0x105fffff]
> [    1.224945] pci 0000:00:01.3: BAR 14: assigned [mem 0x10600000-0x107fffff]
> [    1.226270] pci 0000:00:01.0: BAR 13: assigned [io  0x1000-0x1fff]
> [    1.227475] pci 0000:00:01.1: BAR 13: assigned [io  0x2000-0x2fff]
> [    1.228668] pci 0000:00:01.2: BAR 13: assigned [io  0x3000-0x3fff]
> [    1.229853] pci 0000:00:01.3: BAR 13: assigned [io  0x4000-0x4fff]
> [    1.231064] pci 0000:01:00.0: BAR 0: assigned [mem 0x10000000-0x10003fff 64bit]
> [    1.232564] pci 0000:00:01.0: PCI bridge to [bus 01]
> [    1.233530] pci 0000:00:01.0:   bridge window [io  0x1000-0x1fff]
> [    1.253214] pci 0000:00:01.0:   bridge window [mem 0x10000000-0x101fffff]
> [    1.267540] pci 0000:00:01.0:   bridge window [mem 0x8001800000-0x80019fffff 64bit pref]
> [    1.294996] pci 0000:02:00.0: BAR 4: assigned [mem 0x8000000000-0x80007fffff 64bit pref]
> [    1.321082] pci 0000:02:00.0: BAR 1: assigned [mem 0x10200000-0x10200fff]
> [    1.323053] pci 0000:00:01.1: PCI bridge to [bus 02]
> [    1.324004] pci 0000:00:01.1:   bridge window [io  0x2000-0x2fff]
> [    1.344149] pci 0000:00:01.1:   bridge window [mem 0x10200000-0x103fffff]
> [    1.358181] pci 0000:00:01.1:   bridge window [mem 0x8000000000-0x80007fffff 64bit pref]
> [    1.384572] pci 0000:03:00.0: BAR 4: assigned [mem 0x8000800000-0x8000ffffff 64bit pref]
> [    1.410293] pci 0000:03:00.0: BAR 6: assigned [mem 0x10400000-0x1043ffff pref]
> [    1.412715] pci 0000:03:00.0: BAR 1: assigned [mem 0x10440000-0x10440fff]
> [    1.426032] pci 0000:00:01.2: PCI bridge to [bus 03]
> [    1.427117] pci 0000:00:01.2:   bridge window [io  0x3000-0x3fff]
> [    1.446229] pci 0000:00:01.2:   bridge window [mem 0x10400000-0x105fffff]
> [    1.460070] pci 0000:00:01.2:   bridge window [mem 0x8000800000-0x8000ffffff 64bit pref]
> [    1.486803] pci 0000:04:00.0: BAR 4: assigned [mem 0x8001000000-0x80017fffff 64bit pref]
> [    1.512454] pci 0000:04:00.0: BAR 1: assigned [mem 0x10600000-0x10600fff]
> [    1.526310] pci 0000:00:01.3: PCI bridge to [bus 04]
> [    1.527283] pci 0000:00:01.3:   bridge window [io  0x4000-0x4fff]
> [    1.546456] pci 0000:00:01.3:   bridge window [mem 0x10600000-0x107fffff]
> [    1.560368] pci 0000:00:01.3:   bridge window [mem 0x8001000000-0x80017fffff 64bit pref]
> [    1.587389] ACPI: PCI Interrupt Link [GSI0] (IRQs *35)
> [    1.588527] ACPI: PCI Interrupt Link [GSI1] (IRQs *36)
> [    1.589607] ACPI: PCI Interrupt Link [GSI2] (IRQs *37)
> [    1.590670] ACPI: PCI Interrupt Link [GSI3] (IRQs *38)
> [    1.594331] vgaarb: loaded
> [    1.595642] SCSI subsystem initialized
> [    1.596943] libata version 3.00 loaded.
> [    1.597907] ACPI: bus type USB registered
> [    1.598884] usbcore: registered new interface driver usbfs
> [    1.600034] usbcore: registered new interface driver hub
> [    1.601350] usbcore: registered new device driver usb
> [    1.604990] NetLabel: Initializing
> [    1.605716] NetLabel:  domain hash size = 128
> [    1.606524] NetLabel:  protocols = UNLABELED CIPSOv4
> [    1.607669] NetLabel:  unlabeled traffic allowed by default
> [    1.611142] DMA-API: preallocated 4096 debug entries
> [    1.612105] DMA-API: debugging enabled by kernel config
> [    1.705795] clocksource: Switched to clocksource arch_sys_counter
> [    1.787821] VFS: Disk quotas dquot_6.6.0
> [    1.789040] VFS: Dquot-cache hash table entries: 8192 (order 0, 65536 bytes)
> [    1.791938] pnp: PnP ACPI init
> [    1.793312] pnp: PnP ACPI: found 0 devices
> [    1.810253] NET: Registered protocol family 2
> [    1.813094] TCP established hash table entries: 65536 (order: 3, 524288 bytes)
> [    1.814846] TCP bind hash table entries: 65536 (order: 6, 4194304 bytes)
> [    1.822396] TCP: Hash tables configured (established 65536 bind 65536)
> [    1.823873] UDP hash table entries: 4096 (order: 3, 655360 bytes)
> [    1.825936] UDP-Lite hash table entries: 4096 (order: 3, 655360 bytes)
> [    1.828672] NET: Registered protocol family 1
> [    1.829673] pci 0000:01:00.0: enabling device (0000 -> 0002)
> [    1.837906] PCI: CLS 0 bytes, default 128
> [    1.839209] Unpacking initramfs...
> [    2.755342] Freeing initrd memory: 30400K (fffffe00f53c0000 - fffffe00f7170000)
> [    2.757373] kvm [1]: HYP mode not available
> [    2.758651] alg: No test for __ecb-aes-neon (__driver-ecb-aes-neon)
> [    2.760171] cryptomgr_test (75) used greatest stack depth: 13824 bytes left
> [    2.767725] modprobe (81) used greatest stack depth: 12944 bytes left
> [    2.772040] alg: No test for __ecb-aes-neon (cryptd(__driver-ecb-aes-neon))
> [    2.774374] cryptomgr_test (79) used greatest stack depth: 12368 bytes left
> [    2.777350] futex hash table entries: 2048 (order: 2, 262144 bytes)
> [    2.779027] audit: initializing netlink subsys (disabled)
> [    2.780231] audit: type=2000 audit(2.600:1): initialized
> [    2.782020] Initialise system trusted keyrings
> [    2.784150] workingset: timestamp_bits=37 max_order=17 bucket_order=0
> [    2.802041] zbud: loaded
> [    2.808395] Key type big_key registered
> [    2.809229] SELinux:  Registering netfilter hooks
> [    2.897252] alg: drbg: Test 0 failed for drbg_pr_ctr_aes128
> [    2.898554] cryptomgr_test (104) used greatest stack depth: 12016 bytes left
> [    2.908631] alg: drbg: Test 0 failed for drbg_nopr_ctr_aes128
> [    2.910204] alg: drbg: Test 0 failed for drbg_nopr_ctr_aes192
> [    2.911772] alg: drbg: Test 0 failed for drbg_nopr_ctr_aes256
> [    2.915338] NET: Registered protocol family 38
> [    2.916380] Key type asymmetric registered
> [    2.917318] Asymmetric key parser 'x509' registered
> [    2.918805] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 250)
> [    2.920707] io scheduler noop registered
> [    2.921443] io scheduler deadline registered
> [    2.923122] io scheduler cfq registered (default)
> [    2.924139] start plist test
> [    2.927415] end plist test
> [    2.931670] pl061_gpio ARMH0061:00: PL061 GPIO chip @0x0000000009030000 registered
> [    2.934507] ACPI: PCI Interrupt Link [GSI1] enabled at IRQ 36
> [    2.973148] aer 0000:00:01.0:pcie002: service driver aer loaded
> [    2.974725] aer 0000:00:01.1:pcie002: service driver aer loaded
> [    2.976977] aer 0000:00:01.2:pcie002: service driver aer loaded
> [    2.978502] aer 0000:00:01.3:pcie002: service driver aer loaded
> [    2.979878] pcieport 0000:00:01.0: Signaling PME through PCIe PME interrupt
> [    2.981335] pci 0000:01:00.0: Signaling PME through PCIe PME interrupt
> [    2.982761] pcie_pme 0000:00:01.0:pcie001: service driver pcie_pme loaded
> [    2.984298] pcieport 0000:00:01.1: Signaling PME through PCIe PME interrupt
> [    2.985781] pci 0000:02:00.0: Signaling PME through PCIe PME interrupt
> [    2.987087] pcie_pme 0000:00:01.1:pcie001: service driver pcie_pme loaded
> [    2.988619] pcieport 0000:00:01.2: Signaling PME through PCIe PME interrupt
> [    2.990050] pci 0000:03:00.0: Signaling PME through PCIe PME interrupt
> [    2.991448] pcie_pme 0000:00:01.2:pcie001: service driver pcie_pme loaded
> [    2.993019] pcieport 0000:00:01.3: Signaling PME through PCIe PME interrupt
> [    2.994518] pci 0000:04:00.0: Signaling PME through PCIe PME interrupt
> [    2.995867] pcie_pme 0000:00:01.3:pcie001: service driver pcie_pme loaded
> [    2.997328] pci_hotplug: PCI Hot Plug PCI Core version: 0.5
> [    2.998614] pciehp 0000:00:01.0:pcie004: Slot #0 AttnBtn+ PwrCtrl+ MRL- AttnInd+ PwrInd+ HotPlug+ Surprise+ Interlock+ NoCompl- LLActRep-
> [    3.001848] pciehp 0000:00:01.0:pcie004: service driver pciehp loaded
> [    3.003202] pciehp 0000:00:01.1:pcie004: Slot #0 AttnBtn+ PwrCtrl+ MRL- AttnInd+ PwrInd+ HotPlug+ Surprise+ Interlock+ NoCompl- LLActRep-
> [    3.006097] pciehp 0000:00:01.1:pcie004: service driver pciehp loaded
> [    3.007533] pciehp 0000:00:01.2:pcie004: Slot #0 AttnBtn+ PwrCtrl+ MRL- AttnInd+ PwrInd+ HotPlug+ Surprise+ Interlock+ NoCompl- LLActRep-
> [    3.010330] pciehp 0000:00:01.2:pcie004: service driver pciehp loaded
> [    3.011748] pciehp 0000:00:01.3:pcie004: Slot #0 AttnBtn+ PwrCtrl+ MRL- AttnInd+ PwrInd+ HotPlug+ Surprise+ Interlock+ NoCompl- LLActRep-
> [    3.014587] pciehp 0000:00:01.3:pcie004: service driver pciehp loaded
> [    3.015864] pciehp: PCI Express Hot Plug Controller Driver version: 0.4
> [    3.017707] efifb: invalid framebuffer address
> [    3.020376] Serial: 8250/16550 driver, 32 ports, IRQ sharing enabled
> [    3.033876] msm_serial: driver initialized
> [    3.035876] Failed to find cpu0 device node
> [    3.036713] Unable to detect cache hierarchy from DT for CPU 0
> [    3.038968] libphy: Fixed MDIO Bus: probed
> [    3.040219] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
> [    3.041636] ehci-pci: EHCI PCI platform driver
> [    3.042554] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
> [    3.043761] ohci-pci: OHCI PCI platform driver
> [    3.044666] uhci_hcd: USB Universal Host Controller Interface driver
> [    3.054963] xhci_hcd 0000:01:00.0: xHCI Host Controller
> [    3.056725] xhci_hcd 0000:01:00.0: new USB bus registered, assigned bus number 1
> [    3.060495] xhci_hcd 0000:01:00.0: hcc params 0x00087001 hci version 0x100 quirks 0x00000014
> [    3.064236] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
> [    3.065654] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> [    3.067032] usb usb1: Product: xHCI Host Controller
> [    3.067982] usb usb1: Manufacturer: Linux 4.8.0 xhci-hcd
> [    3.069014] usb usb1: SerialNumber: 0000:01:00.0
> [    3.071283] hub 1-0:1.0: USB hub found
> [    3.072298] hub 1-0:1.0: 4 ports detected
> [    3.074921] xhci_hcd 0000:01:00.0: xHCI Host Controller
> [    3.076485] xhci_hcd 0000:01:00.0: new USB bus registered, assigned bus number 2
> [    3.078304] usb usb2: We don't know the algorithms for LPM for this host, disabling LPM.
> [    3.080160] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003
> [    3.081526] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> [    3.082893] usb usb2: Product: xHCI Host Controller
> [    3.083821] usb usb2: Manufacturer: Linux 4.8.0 xhci-hcd
> [    3.084825] usb usb2: SerialNumber: 0000:01:00.0
> [    3.086840] hub 2-0:1.0: USB hub found
> [    3.087745] hub 2-0:1.0: 4 ports detected
> [    3.090180] usbcore: registered new interface driver usbserial
> [    3.091473] usbcore: registered new interface driver usbserial_generic
> [    3.093048] usbserial: USB Serial support registered for generic
> [    3.094847] mousedev: PS/2 mouse device common for all mice
> [    3.097427] rtc-efi rtc-efi: rtc core: registered rtc-efi as rtc0
> [    3.099602] device-mapper: uevent: version 1.0.3
> [    3.101336] device-mapper: ioctl: 4.35.0-ioctl (2016-06-23) initialised: dm-devel at redhat.com
> [    3.104534] EFI Variables Facility v0.08 2004-May-17
> [    3.107690] hidraw: raw HID events driver (C) Jiri Kosina
> [    3.109001] usbcore: registered new interface driver usbhid
> [    3.110141] usbhid: USB HID core driver
> [    3.111920] drop_monitor: Initializing network drop monitor service
> [    3.113583] ip_tables: (C) 2000-2006 Netfilter Core Team
> [    3.114948] Initializing XFRM netlink socket
> [    3.117302] NET: Registered protocol family 10
> [    3.120493] mip6: Mobile IPv6
> [    3.121237] NET: Registered protocol family 17
> [    3.123363] registered taskstats version 1
> [    3.124289] Loading compiled-in X.509 certificates
> [    3.132881] alg: No test for pkcs1pad(rsa,sha256) (pkcs1pad(rsa-generic,sha256))
> [    3.136159] Loaded X.509 cert 'Build time autogenerated kernel key: 646bee5e17f26888c6e6ef5950998cb2000dfbae'
> [    3.138723] zswap: loaded using pool lzo/zbud
> [    3.166483] rtc-efi rtc-efi: setting system clock to 2016-10-14 15:41:17 UTC (1476459677)
> [    3.168727] PM: Hibernation image not present or could not be loaded.
> [    3.170839] Freeing unused kernel memory: 1536K (fffffe0000cf0000 - fffffe0000e70000)
> [    3.190833] random: systemd: uninitialized urandom read (16 bytes read)
> [    3.194327] random: systemd: uninitialized urandom read (16 bytes read)
> [    3.213481] systemd[1]: systemd 229 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
> [    3.217655] systemd[1]: Detected virtualization kvm.
> [    3.218614] systemd[1]: Detected architecture arm64.
> [    3.219547] systemd[1]: Running in initial RAM disk.
>
> Welcome to Fedora 24 (Server Edition) dracut-044-20.fc24 (Initramfs)!

> If (2) fails then we may need to expand the bisection :-(

Thankfully, it didn't fail.

Thanks
Laszlo

^ permalink raw reply

* aarch64 ACPI boot regressed by commit 7ba5f605f3a0 ("arm64/numa: remove the limitation that cpu0 must bind to node0")
From: Laszlo Ersek @ 2016-10-14 16:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161014154231.GA4411@red-moon>

On 10/14/16 17:42, Lorenzo Pieralisi wrote:
> On Fri, Oct 14, 2016 at 05:27:58PM +0200, Laszlo Ersek wrote:
>> On 10/14/16 17:01, Laszlo Ersek wrote:
>>
>>> Maybe the code I
>>> tried to analyze in this email was never *meant* to associate CPU#0 with
>>> any NUMA node at all (not even node 0); instead, other code -- for
>>> example code removed by 7ba5f605f3a0 -- was meant to perform that
>>> association.
>>
>> Staring a bit more at the code, this looks very likely; in acpi_map_gic_cpu_interface() we have
>>
>>> 	/* Check if GICC structure of boot CPU is available in the MADT */
>>> 	if (cpu_logical_map(0) == hwid) {
>>> 		if (bootcpu_valid) {
>>> 			pr_err("duplicate boot CPU MPIDR: 0x%llx in MADT\n",
>>> 			       hwid);
>>> 			return;
>>> 		}
>>> 		bootcpu_valid = true;
>>> 		return;
>>> 	}
>>
>> which means that this callback function (for parsing the GICC
>> structures in the MADT) expects to find the boot processor as well.
>>
>> Upon finding the boot processor, we set bootcpu_valid to true, and
>> that's it -- no association with any NUMA node, and no incrementing of
>> "cpu_count".
> 
> Yes, because that's to check the MADT contains the boot cpu hwid.
> 
> Does this help (compile tested only) ?
> 
> -- >8 -- 
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index d3f151c..8507703 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -544,6 +544,7 @@ static int __init smp_cpu_setup(int cpu)
>  			return;
>  		}
>  		bootcpu_valid = true;
> +		early_map_cpu_to_node(0, acpi_numa_get_nid(0, hwid));
>  		return;
>  	}
>  
> 

Your patch applies to the tree at v4.8-14604-g29fbff8698fc, but the function the hunk modifies is not smp_cpu_setup(), it is acpi_map_gic_cpu_interface():

> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index d3f151cfd4a1..8507703dabe4 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -544,6 +544,7 @@ acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
>  			return;
>  		}
>  		bootcpu_valid = true;
> +		early_map_cpu_to_node(0, acpi_numa_get_nid(0, hwid));
>  		return;
>  	}
> 

Anyway, your patch works with both the two-node NUMA configuration Drew suggested for testing, and with the single-node config that I originally used for the bisection. Therefore:

Tested-by: Laszlo Ersek <lersek@redhat.com>
Reported-by: Laszlo Ersek <lersek@redhat.com>

Thank you very much for the quick bugfix! And, I think your patch (when you send it for real) should carry

Fixes: 7ba5f605f3a0d9495aad539eeb8346d726dfc183

too, because it supplies the cpu#0<->node#xxx association that 7ba5f605f3a0 removed not just for DT, but also for ACPI.

Cheers!
Laszlo

^ permalink raw reply

* [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1
From: Suzuki K Poulose @ 2016-10-14 16:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <912acc88-fbaf-2576-8048-1fcc67439600@codeaurora.org>

On 13/10/16 20:37, Baicar, Tyler wrote:
> Hello Suzuki,
>
> On 10/13/2016 2:50 AM, Suzuki K Poulose wrote:
>> On 12/10/16 23:10, Baicar, Tyler wrote:

>>>> Please could you keep the people who reviewed/commented on your series in the past,
>>>> whenever you post a new version ?
>>> Do you mean to just send the new version to their e-mail directly in addition to the lists? If so, I will do that next time.
>>
>> If you send a new version of a series to the list, it is a good idea to keep
>> the people who commented (significantly) on your previous version in Cc, especially
>> when you have addressed their feedback. That will help them to keep track of the
>> series. People can always see the new version in the list, but then it is so easy
>> to miss something in the 100s of emails you get each day. I am sure people have
>> special filters for the emails based on if they are in Cc/To etc.
>>
> Okay, understood. I'll make sure to add those who have commented in the cc/to list to avoid the e-mail filters.

Thanks !

>> Is it always the same endianness as that of the CPU ?
> It is a fair assumption that the firmware populating this record will use a CPU of the same endianness. There is no mechanism in the spec to indicate otherwise.

Yep, you are right. The EFI expects the EL2/EL1 to be of the same endianness

Cheers
Suzuki

^ permalink raw reply

* [PATCH V3 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1
From: Mark Rutland @ 2016-10-14 16:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <38c7c9ac-e8ad-6fb5-3ee9-3ba85e4b8299@arm.com>

On Fri, Oct 14, 2016 at 05:28:58PM +0100, Suzuki K Poulose wrote:
> On 13/10/16 20:37, Baicar, Tyler wrote:
> >On 10/13/2016 2:50 AM, Suzuki K Poulose wrote:
> >>Is it always the same endianness as that of the CPU ?
> >
> >It is a fair assumption that the firmware populating this record will
> >use a CPU of the same endianness. There is no mechanism in the spec
> >to indicate otherwise.
> 
> Yep, you are right. The EFI expects the EL2/EL1 to be of the same endianness

To be clear, it is specifically required in the ACPI spec that elements
are in little-endian. Per the ACPI 6.1 spec, page 109:

	All numeric values in ACPI-defined tables, blocks, and
	structures are always encoded in little endian
	format.

Given that CPER, HEST, etc are defined within the ACPI specification,
they are covered by this requirement.

Elements outside of the ACPI spec are not necessarily covered by this
requirement, but their specifications should state their endianness.

Thanks,
Mark.

^ permalink raw reply

* aarch64 ACPI boot regressed by commit 7ba5f605f3a0 ("arm64/numa: remove the limitation that cpu0 must bind to node0")
From: Lorenzo Pieralisi @ 2016-10-14 16:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <c8b9f6fc-3a4b-f74a-c930-f500bcc00a1d@redhat.com>

On Fri, Oct 14, 2016 at 06:22:55PM +0200, Laszlo Ersek wrote:
> On 10/14/16 17:42, Lorenzo Pieralisi wrote:
> > On Fri, Oct 14, 2016 at 05:27:58PM +0200, Laszlo Ersek wrote:
> >> On 10/14/16 17:01, Laszlo Ersek wrote:
> >>
> >>> Maybe the code I
> >>> tried to analyze in this email was never *meant* to associate CPU#0 with
> >>> any NUMA node at all (not even node 0); instead, other code -- for
> >>> example code removed by 7ba5f605f3a0 -- was meant to perform that
> >>> association.
> >>
> >> Staring a bit more at the code, this looks very likely; in acpi_map_gic_cpu_interface() we have
> >>
> >>> 	/* Check if GICC structure of boot CPU is available in the MADT */
> >>> 	if (cpu_logical_map(0) == hwid) {
> >>> 		if (bootcpu_valid) {
> >>> 			pr_err("duplicate boot CPU MPIDR: 0x%llx in MADT\n",
> >>> 			       hwid);
> >>> 			return;
> >>> 		}
> >>> 		bootcpu_valid = true;
> >>> 		return;
> >>> 	}
> >>
> >> which means that this callback function (for parsing the GICC
> >> structures in the MADT) expects to find the boot processor as well.
> >>
> >> Upon finding the boot processor, we set bootcpu_valid to true, and
> >> that's it -- no association with any NUMA node, and no incrementing of
> >> "cpu_count".
> > 
> > Yes, because that's to check the MADT contains the boot cpu hwid.
> > 
> > Does this help (compile tested only) ?
> > 
> > -- >8 -- 
> > diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> > index d3f151c..8507703 100644
> > --- a/arch/arm64/kernel/smp.c
> > +++ b/arch/arm64/kernel/smp.c
> > @@ -544,6 +544,7 @@ static int __init smp_cpu_setup(int cpu)
> >  			return;
> >  		}
> >  		bootcpu_valid = true;
> > +		early_map_cpu_to_node(0, acpi_numa_get_nid(0, hwid));
> >  		return;
> >  	}
> >  
> > 
> 
> Your patch applies to the tree at v4.8-14604-g29fbff8698fc, but the function the hunk modifies is not smp_cpu_setup(), it is acpi_map_gic_cpu_interface():
> 
> > diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> > index d3f151cfd4a1..8507703dabe4 100644
> > --- a/arch/arm64/kernel/smp.c
> > +++ b/arch/arm64/kernel/smp.c
> > @@ -544,6 +544,7 @@ acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
> >  			return;
> >  		}
> >  		bootcpu_valid = true;
> > +		early_map_cpu_to_node(0, acpi_numa_get_nid(0, hwid));
> >  		return;
> >  	}
> > 
> 
> Anyway, your patch works with both the two-node NUMA configuration
> Drew suggested for testing, and with the single-node config that I
> originally used for the bisection. Therefore:
> 
> Tested-by: Laszlo Ersek <lersek@redhat.com>
> Reported-by: Laszlo Ersek <lersek@redhat.com>
> 
> Thank you very much for the quick bugfix! And, I think your patch
> (when you send it for real) should carry
> 
> Fixes: 7ba5f605f3a0d9495aad539eeb8346d726dfc183
> 
> too, because it supplies the cpu#0<->node#xxx association that
> 7ba5f605f3a0 removed not just for DT, but also for ACPI.

Sure, will do, I will send it out on Monday.

Cheers,
Lorenzo

^ permalink raw reply

* [PATCH v3 0/8] PM / Domains: DT support for domain idle states & atomic PM domains
From: Lina Iyer @ 2016-10-14 17:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

Changes since v2 [3] -
- Addressed review comments from v2.
	- domain-idle-states documentation updated
	- fixed compiler issues with imx driver
	- minor code change in pm_domains.c
- The series is available at [4].

Changes since v1 [2] -
- Addressed review comments from v1.
        - Fixes around dynamic allocation of genpd states
        - Used OF method for iterating phandles
        - Updated documentation, examples
        - Rename state variable (provider -> fwnode)
- The series is available at [3].

The changes from [1] are -
- Allocating memory for domain idle states dynamically
- Conform to naming conventions for internal and exported genpd functions
- DT binding example for domain-idle-state
- Use fwnode instead of of_node
- Handle atomic case for removal of PM Domain
- Rebase on top of Rafael's pm/genpd tree

Thanks,
Lina

Lina Iyer (8):
  PM / Domains: Make genpd state allocation dynamic
  PM / Domain: Add residency property to genpd states
  PM / Domains: Allow domain power states to be read from DT
  PM / Domains: Save the fwnode in genpd_power_state
  dt/bindings: Update binding for PM domain idle states
  PM / Domains: Abstract genpd locking
  PM / Domains: Support IRQ safe PM domains
  PM / doc: Update device documentation for devices in IRQ safe PM
    domains

 .../devicetree/bindings/power/power_domain.txt     |  43 +++
 Documentation/power/devices.txt                    |   9 +-
 arch/arm/mach-imx/gpc.c                            |  17 +-
 drivers/base/power/domain.c                        | 358 +++++++++++++++++----
 include/linux/pm_domain.h                          |  28 +-
 5 files changed, 383 insertions(+), 72 deletions(-)

-- 
2.7.4

[1]. https://www.spinics.net/lists/arm-kernel/msg526814.html
[2]. http://www.spinics.net/lists/arm-kernel/msg535106.html
[3]. https://git.linaro.org/people/lina.iyer/linux-next.git/shortlog/refs/heads/genpd-v2
[4]. https://git.linaro.org/people/lina.iyer/linux-next.git/shortlog/refs/heads/genpd-v3

^ permalink raw reply

* [PATCH v3 1/8] PM / Domains: Make genpd state allocation dynamic
From: Lina Iyer @ 2016-10-14 17:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476467276-75094-1-git-send-email-lina.iyer@linaro.org>

Allow PM Domain states to be defined dynamically by the drivers. This
removes the limitation on the maximum number of states possible for a
domain.

Cc: Axel Haslam <ahaslam+renesas@baylibre.com>
Suggested-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 arch/arm/mach-imx/gpc.c     | 17 ++++++++++-------
 drivers/base/power/domain.c | 35 +++++++++++++++++++++++------------
 include/linux/pm_domain.h   |  5 ++---
 3 files changed, 35 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 0df062d..57a410b 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -380,13 +380,6 @@ static struct pu_domain imx6q_pu_domain = {
 		.name = "PU",
 		.power_off = imx6q_pm_pu_power_off,
 		.power_on = imx6q_pm_pu_power_on,
-		.states = {
-			[0] = {
-				.power_off_latency_ns = 25000,
-				.power_on_latency_ns = 2000000,
-			},
-		},
-		.state_count = 1,
 	},
 };
 
@@ -430,6 +423,16 @@ static int imx_gpc_genpd_init(struct device *dev, struct regulator *pu_reg)
 	if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS))
 		return 0;
 
+	imx6q_pu_domain.base.states = devm_kzalloc(dev,
+					sizeof(*imx6q_pu_domain.base.states),
+					GFP_KERNEL);
+	if (!imx6q_pu_domain.base.states)
+		return -ENOMEM;
+
+	imx6q_pu_domain.base.states[0].power_off_latency_ns = 25000;
+	imx6q_pu_domain.base.states[0].power_on_latency_ns = 2000000;
+	imx6q_pu_domain.base.state_count = 1;
+
 	pm_genpd_init(&imx6q_pu_domain.base, NULL, false);
 	return of_genpd_add_provider_onecell(dev->of_node,
 					     &imx_gpc_onecell_data);
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index e023066..37ab7f1 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1282,6 +1282,21 @@ out:
 }
 EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);
 
+static int genpd_set_default_power_state(struct generic_pm_domain *genpd)
+{
+	struct genpd_power_state *state;
+
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return -ENOMEM;
+
+	genpd->states = state;
+	genpd->state_count = 1;
+	genpd->free = state;
+
+	return 0;
+}
+
 /**
  * pm_genpd_init - Initialize a generic I/O PM domain object.
  * @genpd: PM domain object to initialize.
@@ -1293,6 +1308,8 @@ EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);
 int pm_genpd_init(struct generic_pm_domain *genpd,
 		  struct dev_power_governor *gov, bool is_off)
 {
+	int ret;
+
 	if (IS_ERR_OR_NULL(genpd))
 		return -EINVAL;
 
@@ -1325,19 +1342,12 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
 		genpd->dev_ops.start = pm_clk_resume;
 	}
 
-	if (genpd->state_idx >= GENPD_MAX_NUM_STATES) {
-		pr_warn("Initial state index out of bounds.\n");
-		genpd->state_idx = GENPD_MAX_NUM_STATES - 1;
-	}
-
-	if (genpd->state_count > GENPD_MAX_NUM_STATES) {
-		pr_warn("Limiting states to  %d\n", GENPD_MAX_NUM_STATES);
-		genpd->state_count = GENPD_MAX_NUM_STATES;
-	}
-
 	/* Use only one "off" state if there were no states declared */
-	if (genpd->state_count == 0)
-		genpd->state_count = 1;
+	if (genpd->state_count == 0) {
+		ret = genpd_set_default_power_state(genpd);
+		if (ret)
+			return ret;
+	}
 
 	mutex_lock(&gpd_list_lock);
 	list_add(&genpd->gpd_list_node, &gpd_list);
@@ -1377,6 +1387,7 @@ static int genpd_remove(struct generic_pm_domain *genpd)
 	list_del(&genpd->gpd_list_node);
 	mutex_unlock(&genpd->lock);
 	cancel_work_sync(&genpd->power_off_work);
+	kfree(genpd->free);
 	pr_debug("%s: removed %s\n", __func__, genpd->name);
 
 	return 0;
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index a09fe5c..de1d8f3 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -19,8 +19,6 @@
 /* Defines used for the flags field in the struct generic_pm_domain */
 #define GENPD_FLAG_PM_CLK	(1U << 0) /* PM domain uses PM clk */
 
-#define GENPD_MAX_NUM_STATES	8 /* Number of possible low power states */
-
 enum gpd_status {
 	GPD_STATE_ACTIVE = 0,	/* PM domain is active */
 	GPD_STATE_POWER_OFF,	/* PM domain is off */
@@ -70,9 +68,10 @@ struct generic_pm_domain {
 	void (*detach_dev)(struct generic_pm_domain *domain,
 			   struct device *dev);
 	unsigned int flags;		/* Bit field of configs for genpd */
-	struct genpd_power_state states[GENPD_MAX_NUM_STATES];
+	struct genpd_power_state *states;
 	unsigned int state_count; /* number of states */
 	unsigned int state_idx; /* state that genpd will go to when off */
+	void *free; /* Free the state that was allocated for default */
 
 };
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 2/8] PM / Domain: Add residency property to genpd states
From: Lina Iyer @ 2016-10-14 17:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476467276-75094-1-git-send-email-lina.iyer@linaro.org>

Residency of a domain's idle state indicates that the minimum idle time
for the domain's idle state to be beneficial for power. Add the
parameter to the state node. Future patches, will use the residency
value in the genpd governor to determine if it is worth while to enter
an idle state.

Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 include/linux/pm_domain.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index de1d8f3..f4492eb 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -38,6 +38,7 @@ struct gpd_dev_ops {
 struct genpd_power_state {
 	s64 power_off_latency_ns;
 	s64 power_on_latency_ns;
+	s64 residency_ns;
 };
 
 struct generic_pm_domain {
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 3/8] PM / Domains: Allow domain power states to be read from DT
From: Lina Iyer @ 2016-10-14 17:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476467276-75094-1-git-send-email-lina.iyer@linaro.org>

This patch allows domains to define idle states in the DT. SoC's can
define domain idle states in DT using the "domain-idle-states" property
of the domain provider. Add API to read the idle states from DT that can
be set in the genpd object.

This patch is based on the original patch by Marc Titinger.

Signed-off-by: Marc Titinger <mtitinger+renesas@baylibre.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
---
 drivers/base/power/domain.c | 94 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/pm_domain.h   |  8 ++++
 2 files changed, 102 insertions(+)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 37ab7f1..9af75ba 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1916,6 +1916,100 @@ out:
 	return ret ? -EPROBE_DEFER : 0;
 }
 EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
+
+static const struct of_device_id idle_state_match[] = {
+	{ .compatible = "arm,idle-state", },
+	{ }
+};
+
+static int genpd_parse_state(struct genpd_power_state *genpd_state,
+				    struct device_node *state_node)
+{
+	int err;
+	u32 residency;
+	u32 entry_latency, exit_latency;
+	const struct of_device_id *match_id;
+
+	match_id = of_match_node(idle_state_match, state_node);
+	if (!match_id)
+		return -EINVAL;
+
+	err = of_property_read_u32(state_node, "entry-latency-us",
+						&entry_latency);
+	if (err) {
+		pr_debug(" * %s missing entry-latency-us property\n",
+						state_node->full_name);
+		return -EINVAL;
+	}
+
+	err = of_property_read_u32(state_node, "exit-latency-us",
+						&exit_latency);
+	if (err) {
+		pr_debug(" * %s missing exit-latency-us property\n",
+						state_node->full_name);
+		return -EINVAL;
+	}
+
+	err = of_property_read_u32(state_node, "min-residency-us", &residency);
+	if (!err)
+		genpd_state->residency_ns = 1000 * residency;
+
+	genpd_state->power_on_latency_ns = 1000 * exit_latency;
+	genpd_state->power_off_latency_ns = 1000 * entry_latency;
+
+	return 0;
+}
+
+/**
+ * of_genpd_parse_idle_states: Return array of idle states for the genpd.
+ *
+ * @dn: The genpd device node
+ * @states: The pointer to which the state array will be saved.
+ * @n: The count of elements in the array returned from this function.
+ *
+ * Returns the device states parsed from the OF node. The memory for the states
+ * is allocated by this function and is the responsibility of the caller to
+ * free the memory after use.
+ */
+int of_genpd_parse_idle_states(struct device_node *dn,
+			struct genpd_power_state **states, int *n)
+{
+	struct genpd_power_state *st;
+	struct device_node *np;
+	int i = 0;
+	int err, ret;
+	int count;
+	struct of_phandle_iterator it;
+
+	count = of_count_phandle_with_args(dn, "domain-idle-states", NULL);
+	if (!count)
+		return -EINVAL;
+
+	st = kcalloc(count, sizeof(*st), GFP_KERNEL);
+	if (!st)
+		return -ENOMEM;
+
+	/* Loop over the phandles until all the requested entry is found */
+	of_for_each_phandle(&it, err, dn, "domain-idle-states", NULL, 0) {
+		np = it.node;
+		ret = genpd_parse_state(&st[i++], np);
+		if (ret) {
+			pr_err
+			("Parsing idle state node %s failed with err %d\n",
+							np->full_name, ret);
+			of_node_put(np);
+			kfree(st);
+			return ret;
+		}
+	}
+
+	*n = count;
+	*states = st;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_genpd_parse_idle_states);
+
 #endif /* CONFIG_PM_GENERIC_DOMAINS_OF */
 
 
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index f4492eb..b489496 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -205,6 +205,8 @@ extern int of_genpd_add_device(struct of_phandle_args *args,
 extern int of_genpd_add_subdomain(struct of_phandle_args *parent,
 				  struct of_phandle_args *new_subdomain);
 extern struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
+extern int of_genpd_parse_idle_states(struct device_node *dn,
+			struct genpd_power_state **states, int *n);
 
 int genpd_dev_pm_attach(struct device *dev);
 #else /* !CONFIG_PM_GENERIC_DOMAINS_OF */
@@ -234,6 +236,12 @@ static inline int of_genpd_add_subdomain(struct of_phandle_args *parent,
 	return -ENODEV;
 }
 
+static inline int of_genpd_parse_idle_states(struct device_node *dn,
+			struct genpd_power_state **states, int *n)
+{
+	return -ENODEV;
+}
+
 static inline int genpd_dev_pm_attach(struct device *dev)
 {
 	return -ENODEV;
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 4/8] PM / Domains: Save the fwnode in genpd_power_state
From: Lina Iyer @ 2016-10-14 17:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476467276-75094-1-git-send-email-lina.iyer@linaro.org>

Save the fwnode for the genpd state in the state node. PM Domain clients
may use the fwnode to read in the platform specific domain state
properties and associate them with the state.

Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/base/power/domain.c | 1 +
 include/linux/pm_domain.h   | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 9af75ba..1a6073aa 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1956,6 +1956,7 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state,
 
 	genpd_state->power_on_latency_ns = 1000 * exit_latency;
 	genpd_state->power_off_latency_ns = 1000 * entry_latency;
+	genpd_state->fwnode = &state_node->fwnode;
 
 	return 0;
 }
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index b489496..6a89881 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -39,6 +39,7 @@ struct genpd_power_state {
 	s64 power_off_latency_ns;
 	s64 power_on_latency_ns;
 	s64 residency_ns;
+	struct fwnode_handle *fwnode;
 };
 
 struct generic_pm_domain {
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 5/8] dt/bindings: Update binding for PM domain idle states
From: Lina Iyer @ 2016-10-14 17:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476467276-75094-1-git-send-email-lina.iyer@linaro.org>

Update DT bindings to describe idle states of PM domains.

This patch is based on the original patch by Marc Titinger.

Cc: <devicetree@vger.kernel.org>
Signed-off-by: Marc Titinger <mtitinger+renesas@baylibre.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/power/power_domain.txt     | 43 ++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt
index 025b5e7..e165036 100644
--- a/Documentation/devicetree/bindings/power/power_domain.txt
+++ b/Documentation/devicetree/bindings/power/power_domain.txt
@@ -29,6 +29,15 @@ Optional properties:
    specified by this binding. More details about power domain specifier are
    available in the next section.
 
+- domain-idle-states : A phandle of an idle-state that shall be soaked into a
+                generic domain power state. The idle state definitions are
+                compatible with arm,idle-state specified in [1].
+  The domain-idle-state property reflects the idle state of this PM domain and
+  not the idle states of the devices or sub-domains in the PM domain. Devices
+  and sub-domains have their own idle-states independent of the parent
+  domain's idle states. In the absence of this property, the domain would be
+  considered as capable of being powered-on or powered-off.
+
 Example:
 
 	power: power-controller at 12340000 {
@@ -59,6 +68,38 @@ The nodes above define two power controllers: 'parent' and 'child'.
 Domains created by the 'child' power controller are subdomains of '0' power
 domain provided by the 'parent' power controller.
 
+Example 3:
+	parent: power-controller at 12340000 {
+		compatible = "foo,power-controller";
+		reg = <0x12340000 0x1000>;
+		#power-domain-cells = <0>;
+		domain-idle-states = <&DOMAIN_RET>, <&DOMAIN_PWR_DN>;
+	};
+
+	child: power-controller at 12341000 {
+		compatible = "foo,power-controller";
+		reg = <0x12341000 0x1000>;
+		power-domains = <&parent 0>;
+		#power-domain-cells = <0>;
+		domain-idle-states = <&DOMAIN_PWR_DN>;
+	};
+
+	DOMAIN_RET: state at 0 {
+		compatible = "arm,idle-state";
+		reg = <0x0>;
+		entry-latency-us = <1000>;
+		exit-latency-us = <2000>;
+		min-residency-us = <10000>;
+	};
+
+	DOMAIN_PWR_DN: state at 1 {
+		compatible = "arm,idle-state";
+		reg = <0x1>;
+		entry-latency-us = <5000>;
+		exit-latency-us = <8000>;
+		min-residency-us = <7000>;
+	};
+
 ==PM domain consumers==
 
 Required properties:
@@ -76,3 +117,5 @@ Example:
 The node above defines a typical PM domain consumer device, which is located
 inside a PM domain with index 0 of a power controller represented by a node
 with the label "power".
+
+[1]. Documentation/devicetree/bindings/arm/idle-states.txt
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 6/8] PM / Domains: Abstract genpd locking
From: Lina Iyer @ 2016-10-14 17:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476467276-75094-1-git-send-email-lina.iyer@linaro.org>

Abstract genpd lock/unlock calls, in preparation for domain specific
locks added in the following patches.

Cc: Kevin Hilman <khilman@kernel.org>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/base/power/domain.c | 121 +++++++++++++++++++++++++++++---------------
 include/linux/pm_domain.h   |   5 +-
 2 files changed, 85 insertions(+), 41 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 1a6073aa..4194012 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -39,6 +39,46 @@
 static LIST_HEAD(gpd_list);
 static DEFINE_MUTEX(gpd_list_lock);
 
+struct genpd_lock_ops {
+	void (*lock)(struct generic_pm_domain *genpd);
+	void (*lock_nested)(struct generic_pm_domain *genpd, int depth);
+	int (*lock_interruptible)(struct generic_pm_domain *genpd);
+	void (*unlock)(struct generic_pm_domain *genpd);
+};
+
+static void genpd_lock_mtx(struct generic_pm_domain *genpd)
+{
+	mutex_lock(&genpd->mlock);
+}
+
+static void genpd_lock_nested_mtx(struct generic_pm_domain *genpd,
+					int depth)
+{
+	mutex_lock_nested(&genpd->mlock, depth);
+}
+
+static int genpd_lock_interruptible_mtx(struct generic_pm_domain *genpd)
+{
+	return mutex_lock_interruptible(&genpd->mlock);
+}
+
+static void genpd_unlock_mtx(struct generic_pm_domain *genpd)
+{
+	return mutex_unlock(&genpd->mlock);
+}
+
+static const struct genpd_lock_ops genpd_mtx_ops = {
+	.lock = genpd_lock_mtx,
+	.lock_nested = genpd_lock_nested_mtx,
+	.lock_interruptible = genpd_lock_interruptible_mtx,
+	.unlock = genpd_unlock_mtx,
+};
+
+#define genpd_lock(p)			p->lock_ops->lock(p)
+#define genpd_lock_nested(p, d)		p->lock_ops->lock_nested(p, d)
+#define genpd_lock_interruptible(p)	p->lock_ops->lock_interruptible(p)
+#define genpd_unlock(p)			p->lock_ops->unlock(p)
+
 /*
  * Get the generic PM domain for a particular struct device.
  * This validates the struct device pointer, the PM domain pointer,
@@ -200,9 +240,9 @@ static int genpd_poweron(struct generic_pm_domain *genpd, unsigned int depth)
 
 		genpd_sd_counter_inc(master);
 
-		mutex_lock_nested(&master->lock, depth + 1);
+		genpd_lock_nested(master, depth + 1);
 		ret = genpd_poweron(master, depth + 1);
-		mutex_unlock(&master->lock);
+		genpd_unlock(master);
 
 		if (ret) {
 			genpd_sd_counter_dec(master);
@@ -255,9 +295,9 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
 		spin_unlock_irq(&dev->power.lock);
 
 		if (!IS_ERR(genpd)) {
-			mutex_lock(&genpd->lock);
+			genpd_lock(genpd);
 			genpd->max_off_time_changed = true;
-			mutex_unlock(&genpd->lock);
+			genpd_unlock(genpd);
 		}
 
 		dev = dev->parent;
@@ -354,9 +394,9 @@ static void genpd_power_off_work_fn(struct work_struct *work)
 
 	genpd = container_of(work, struct generic_pm_domain, power_off_work);
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 	genpd_poweroff(genpd, true);
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 }
 
 /**
@@ -472,9 +512,9 @@ static int genpd_runtime_suspend(struct device *dev)
 	if (dev->power.irq_safe)
 		return 0;
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 	genpd_poweroff(genpd, false);
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 
 	return 0;
 }
@@ -509,9 +549,9 @@ static int genpd_runtime_resume(struct device *dev)
 		goto out;
 	}
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 	ret = genpd_poweron(genpd, 0);
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 
 	if (ret)
 		return ret;
@@ -547,9 +587,9 @@ err_stop:
 	genpd_stop_dev(genpd, dev);
 err_poweroff:
 	if (!dev->power.irq_safe) {
-		mutex_lock(&genpd->lock);
+		genpd_lock(genpd);
 		genpd_poweroff(genpd, 0);
-		mutex_unlock(&genpd->lock);
+		genpd_unlock(genpd);
 	}
 
 	return ret;
@@ -732,20 +772,20 @@ static int pm_genpd_prepare(struct device *dev)
 	if (resume_needed(dev, genpd))
 		pm_runtime_resume(dev);
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 
 	if (genpd->prepared_count++ == 0)
 		genpd->suspended_count = 0;
 
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 
 	ret = pm_generic_prepare(dev);
 	if (ret) {
-		mutex_lock(&genpd->lock);
+		genpd_lock(genpd);
 
 		genpd->prepared_count--;
 
-		mutex_unlock(&genpd->lock);
+		genpd_unlock(genpd);
 	}
 
 	return ret;
@@ -936,13 +976,13 @@ static void pm_genpd_complete(struct device *dev)
 
 	pm_generic_complete(dev);
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 
 	genpd->prepared_count--;
 	if (!genpd->prepared_count)
 		genpd_queue_power_off_work(genpd);
 
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 }
 
 /**
@@ -1071,7 +1111,7 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
 	if (IS_ERR(gpd_data))
 		return PTR_ERR(gpd_data);
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 
 	if (genpd->prepared_count > 0) {
 		ret = -EAGAIN;
@@ -1088,7 +1128,7 @@ static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
 	list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
 
  out:
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 
 	if (ret)
 		genpd_free_dev_data(dev, gpd_data);
@@ -1130,7 +1170,7 @@ static int genpd_remove_device(struct generic_pm_domain *genpd,
 	gpd_data = to_gpd_data(pdd);
 	dev_pm_qos_remove_notifier(dev, &gpd_data->nb);
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 
 	if (genpd->prepared_count > 0) {
 		ret = -EAGAIN;
@@ -1145,14 +1185,14 @@ static int genpd_remove_device(struct generic_pm_domain *genpd,
 
 	list_del_init(&pdd->list_node);
 
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 
 	genpd_free_dev_data(dev, gpd_data);
 
 	return 0;
 
  out:
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 	dev_pm_qos_add_notifier(dev, &gpd_data->nb);
 
 	return ret;
@@ -1187,8 +1227,8 @@ static int genpd_add_subdomain(struct generic_pm_domain *genpd,
 	if (!link)
 		return -ENOMEM;
 
-	mutex_lock(&subdomain->lock);
-	mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
+	genpd_lock(subdomain);
+	genpd_lock_nested(genpd, SINGLE_DEPTH_NESTING);
 
 	if (genpd->status == GPD_STATE_POWER_OFF
 	    &&  subdomain->status != GPD_STATE_POWER_OFF) {
@@ -1211,8 +1251,8 @@ static int genpd_add_subdomain(struct generic_pm_domain *genpd,
 		genpd_sd_counter_inc(genpd);
 
  out:
-	mutex_unlock(&genpd->lock);
-	mutex_unlock(&subdomain->lock);
+	genpd_unlock(genpd);
+	genpd_unlock(subdomain);
 	if (ret)
 		kfree(link);
 	return ret;
@@ -1250,8 +1290,8 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
 	if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
 		return -EINVAL;
 
-	mutex_lock(&subdomain->lock);
-	mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
+	genpd_lock(subdomain);
+	genpd_lock_nested(genpd, SINGLE_DEPTH_NESTING);
 
 	if (!list_empty(&subdomain->master_links) || subdomain->device_count) {
 		pr_warn("%s: unable to remove subdomain %s\n", genpd->name,
@@ -1275,8 +1315,8 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
 	}
 
 out:
-	mutex_unlock(&genpd->lock);
-	mutex_unlock(&subdomain->lock);
+	genpd_unlock(genpd);
+	genpd_unlock(subdomain);
 
 	return ret;
 }
@@ -1316,7 +1356,8 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
 	INIT_LIST_HEAD(&genpd->master_links);
 	INIT_LIST_HEAD(&genpd->slave_links);
 	INIT_LIST_HEAD(&genpd->dev_list);
-	mutex_init(&genpd->lock);
+	mutex_init(&genpd->mlock);
+	genpd->lock_ops = &genpd_mtx_ops;
 	genpd->gov = gov;
 	INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
 	atomic_set(&genpd->sd_count, 0);
@@ -1364,16 +1405,16 @@ static int genpd_remove(struct generic_pm_domain *genpd)
 	if (IS_ERR_OR_NULL(genpd))
 		return -EINVAL;
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 
 	if (genpd->has_provider) {
-		mutex_unlock(&genpd->lock);
+		genpd_unlock(genpd);
 		pr_err("Provider present, unable to remove %s\n", genpd->name);
 		return -EBUSY;
 	}
 
 	if (!list_empty(&genpd->master_links) || genpd->device_count) {
-		mutex_unlock(&genpd->lock);
+		genpd_unlock(genpd);
 		pr_err("%s: unable to remove %s\n", __func__, genpd->name);
 		return -EBUSY;
 	}
@@ -1385,7 +1426,7 @@ static int genpd_remove(struct generic_pm_domain *genpd)
 	}
 
 	list_del(&genpd->gpd_list_node);
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 	cancel_work_sync(&genpd->power_off_work);
 	kfree(genpd->free);
 	pr_debug("%s: removed %s\n", __func__, genpd->name);
@@ -1909,9 +1950,9 @@ int genpd_dev_pm_attach(struct device *dev)
 	dev->pm_domain->detach = genpd_dev_pm_detach;
 	dev->pm_domain->sync = genpd_dev_pm_sync;
 
-	mutex_lock(&pd->lock);
+	genpd_lock(pd);
 	ret = genpd_poweron(pd, 0);
-	mutex_unlock(&pd->lock);
+	genpd_unlock(pd);
 out:
 	return ret ? -EPROBE_DEFER : 0;
 }
@@ -2064,7 +2105,7 @@ static int pm_genpd_summary_one(struct seq_file *s,
 	char state[16];
 	int ret;
 
-	ret = mutex_lock_interruptible(&genpd->lock);
+	ret = genpd_lock_interruptible(genpd);
 	if (ret)
 		return -ERESTARTSYS;
 
@@ -2101,7 +2142,7 @@ static int pm_genpd_summary_one(struct seq_file *s,
 
 	seq_puts(s, "\n");
 exit:
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 
 	return 0;
 }
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 6a89881..811b968 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -42,13 +42,14 @@ struct genpd_power_state {
 	struct fwnode_handle *fwnode;
 };
 
+struct genpd_lock_ops;
+
 struct generic_pm_domain {
 	struct dev_pm_domain domain;	/* PM domain operations */
 	struct list_head gpd_list_node;	/* Node in the global PM domains list */
 	struct list_head master_links;	/* Links with PM domain as a master */
 	struct list_head slave_links;	/* Links with PM domain as a slave */
 	struct list_head dev_list;	/* List of devices */
-	struct mutex lock;
 	struct dev_power_governor *gov;
 	struct work_struct power_off_work;
 	struct fwnode_handle *provider;	/* Identity of the domain provider */
@@ -74,6 +75,8 @@ struct generic_pm_domain {
 	unsigned int state_count; /* number of states */
 	unsigned int state_idx; /* state that genpd will go to when off */
 	void *free; /* Free the state that was allocated for default */
+	const struct genpd_lock_ops *lock_ops;
+	struct mutex mlock;
 
 };
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 7/8] PM / Domains: Support IRQ safe PM domains
From: Lina Iyer @ 2016-10-14 17:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476467276-75094-1-git-send-email-lina.iyer@linaro.org>

Generic Power Domains currently support turning on/off only in process
context. This prevents the usage of PM domains for domains that could be
powered on/off in a context where IRQs are disabled. Many such domains
exist today and do not get powered off, when the IRQ safe devices in
that domain are powered off, because of this limitation.

However, not all domains can operate in IRQ safe contexts. Genpd
therefore, has to support both cases where the domain may or may not
operate in IRQ safe contexts. Configuring genpd to use an appropriate
lock for that domain, would allow domains that have IRQ safe devices to
runtime suspend and resume, in atomic context.

To achieve domain specific locking, set the domain's ->flag to
GENPD_FLAG_IRQ_SAFE while defining the domain. This indicates that genpd
should use a spinlock instead of a mutex for locking the domain. Locking
is abstracted through genpd_lock() and genpd_unlock() functions that use
the flag to determine the appropriate lock to be used for that domain.

Domains that have lower latency to suspend and resume and can operate
with IRQs disabled may now be able to save power, when the component
devices and sub-domains are idle at runtime.

The restriction this imposes on the domain hierarchy is that non-IRQ
safe domains may not have IRQ-safe subdomains, but IRQ safe domains may
have IRQ safe and non-IRQ safe subdomains and devices.

Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Kevin Hilman <khilman@kernel.org>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 drivers/base/power/domain.c | 111 ++++++++++++++++++++++++++++++++++++++++----
 include/linux/pm_domain.h   |  10 +++-
 2 files changed, 110 insertions(+), 11 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 4194012..aac656a 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -74,11 +74,70 @@ static const struct genpd_lock_ops genpd_mtx_ops = {
 	.unlock = genpd_unlock_mtx,
 };
 
+static void genpd_lock_spin(struct generic_pm_domain *genpd)
+	__acquires(&genpd->slock)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&genpd->slock, flags);
+	genpd->lock_flags = flags;
+}
+
+static void genpd_lock_nested_spin(struct generic_pm_domain *genpd,
+					int depth)
+	__acquires(&genpd->slock)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave_nested(&genpd->slock, flags, depth);
+	genpd->lock_flags = flags;
+}
+
+static int genpd_lock_interruptible_spin(struct generic_pm_domain *genpd)
+	__acquires(&genpd->slock)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&genpd->slock, flags);
+	genpd->lock_flags = flags;
+	return 0;
+}
+
+static void genpd_unlock_spin(struct generic_pm_domain *genpd)
+	__releases(&genpd->slock)
+{
+	spin_unlock_irqrestore(&genpd->slock, genpd->lock_flags);
+}
+
+static const struct genpd_lock_ops genpd_spin_ops = {
+	.lock = genpd_lock_spin,
+	.lock_nested = genpd_lock_nested_spin,
+	.lock_interruptible = genpd_lock_interruptible_spin,
+	.unlock = genpd_unlock_spin,
+};
+
 #define genpd_lock(p)			p->lock_ops->lock(p)
 #define genpd_lock_nested(p, d)		p->lock_ops->lock_nested(p, d)
 #define genpd_lock_interruptible(p)	p->lock_ops->lock_interruptible(p)
 #define genpd_unlock(p)			p->lock_ops->unlock(p)
 
+#define genpd_is_irq_safe(genpd)	(genpd->flags & GENPD_FLAG_IRQ_SAFE)
+
+static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev,
+		struct generic_pm_domain *genpd)
+{
+	bool ret;
+
+	ret = pm_runtime_is_irq_safe(dev) && !genpd_is_irq_safe(genpd);
+
+	/* Warn once for each IRQ safe dev in no sleep domain */
+	if (ret)
+		dev_warn_once(dev, "PM domain %s will not be powered off\n",
+				genpd->name);
+
+	return ret;
+}
+
 /*
  * Get the generic PM domain for a particular struct device.
  * This validates the struct device pointer, the PM domain pointer,
@@ -343,7 +402,12 @@ static int genpd_poweroff(struct generic_pm_domain *genpd, bool is_async)
 		if (stat > PM_QOS_FLAGS_NONE)
 			return -EBUSY;
 
-		if (!pm_runtime_suspended(pdd->dev) || pdd->dev->power.irq_safe)
+		/*
+		 * Do not allow PM domain to be powered off, when an IRQ safe
+		 * device is part of a non-IRQ safe domain.
+		 */
+		if (!pm_runtime_suspended(pdd->dev) ||
+			irq_safe_dev_in_no_sleep_domain(pdd->dev, genpd))
 			not_suspended++;
 	}
 
@@ -506,10 +570,10 @@ static int genpd_runtime_suspend(struct device *dev)
 	}
 
 	/*
-	 * If power.irq_safe is set, this routine will be run with interrupts
-	 * off, so it can't use mutexes.
+	 * If power.irq_safe is set, this routine may be run with
+	 * IRQs disabled, so suspend only if the PM domain also is irq_safe.
 	 */
-	if (dev->power.irq_safe)
+	if (irq_safe_dev_in_no_sleep_domain(dev, genpd))
 		return 0;
 
 	genpd_lock(genpd);
@@ -543,8 +607,11 @@ static int genpd_runtime_resume(struct device *dev)
 	if (IS_ERR(genpd))
 		return -EINVAL;
 
-	/* If power.irq_safe, the PM domain is never powered off. */
-	if (dev->power.irq_safe) {
+	/*
+	 * As we don't power off a non IRQ safe domain, which holds
+	 * an IRQ safe device, we don't need to restore power to it.
+	 */
+	if (irq_safe_dev_in_no_sleep_domain(dev, genpd)) {
 		timed = false;
 		goto out;
 	}
@@ -586,7 +653,8 @@ static int genpd_runtime_resume(struct device *dev)
 err_stop:
 	genpd_stop_dev(genpd, dev);
 err_poweroff:
-	if (!dev->power.irq_safe) {
+	if (!pm_runtime_is_irq_safe(dev) ||
+		(pm_runtime_is_irq_safe(dev) && genpd_is_irq_safe(genpd))) {
 		genpd_lock(genpd);
 		genpd_poweroff(genpd, 0);
 		genpd_unlock(genpd);
@@ -1223,6 +1291,17 @@ static int genpd_add_subdomain(struct generic_pm_domain *genpd,
 	    || genpd == subdomain)
 		return -EINVAL;
 
+	/*
+	 * If the domain can be powered on/off in an IRQ safe
+	 * context, ensure that the subdomain can also be
+	 * powered on/off in that context.
+	 */
+	if (!genpd_is_irq_safe(genpd) && genpd_is_irq_safe(subdomain)) {
+		WARN("Parent %s of subdomain %s must be IRQ safe\n",
+				genpd->name, subdomain->name);
+		return -EINVAL;
+	}
+
 	link = kzalloc(sizeof(*link), GFP_KERNEL);
 	if (!link)
 		return -ENOMEM;
@@ -1337,6 +1416,17 @@ static int genpd_set_default_power_state(struct generic_pm_domain *genpd)
 	return 0;
 }
 
+static void genpd_lock_init(struct generic_pm_domain *genpd)
+{
+	if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
+		spin_lock_init(&genpd->slock);
+		genpd->lock_ops = &genpd_spin_ops;
+	} else {
+		mutex_init(&genpd->mlock);
+		genpd->lock_ops = &genpd_mtx_ops;
+	}
+}
+
 /**
  * pm_genpd_init - Initialize a generic I/O PM domain object.
  * @genpd: PM domain object to initialize.
@@ -1356,8 +1446,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd,
 	INIT_LIST_HEAD(&genpd->master_links);
 	INIT_LIST_HEAD(&genpd->slave_links);
 	INIT_LIST_HEAD(&genpd->dev_list);
-	mutex_init(&genpd->mlock);
-	genpd->lock_ops = &genpd_mtx_ops;
+	genpd_lock_init(genpd);
 	genpd->gov = gov;
 	INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
 	atomic_set(&genpd->sd_count, 0);
@@ -2131,7 +2220,9 @@ static int pm_genpd_summary_one(struct seq_file *s,
 	}
 
 	list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
-		kobj_path = kobject_get_path(&pm_data->dev->kobj, GFP_KERNEL);
+		kobj_path = kobject_get_path(&pm_data->dev->kobj,
+				genpd_is_irq_safe(genpd) ?
+				GFP_ATOMIC : GFP_KERNEL);
 		if (kobj_path == NULL)
 			continue;
 
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 811b968..81ece61 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -15,9 +15,11 @@
 #include <linux/err.h>
 #include <linux/of.h>
 #include <linux/notifier.h>
+#include <linux/spinlock.h>
 
 /* Defines used for the flags field in the struct generic_pm_domain */
 #define GENPD_FLAG_PM_CLK	(1U << 0) /* PM domain uses PM clk */
+#define GENPD_FLAG_IRQ_SAFE	(1U << 1) /* PM domain operates in atomic */
 
 enum gpd_status {
 	GPD_STATE_ACTIVE = 0,	/* PM domain is active */
@@ -76,7 +78,13 @@ struct generic_pm_domain {
 	unsigned int state_idx; /* state that genpd will go to when off */
 	void *free; /* Free the state that was allocated for default */
 	const struct genpd_lock_ops *lock_ops;
-	struct mutex mlock;
+	union {
+		struct mutex mlock;
+		struct {
+			spinlock_t slock;
+			unsigned long lock_flags;
+		};
+	};
 
 };
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 8/8] PM / doc: Update device documentation for devices in IRQ safe PM domains
From: Lina Iyer @ 2016-10-14 17:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476467276-75094-1-git-send-email-lina.iyer@linaro.org>

Update documentation to reflect the changes made to support IRQ safe PM
domains.

Signed-off-by: Lina Iyer <lina.iyer@linaro.org>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
---
 Documentation/power/devices.txt | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
index 8ba6625..0401b53 100644
--- a/Documentation/power/devices.txt
+++ b/Documentation/power/devices.txt
@@ -607,7 +607,14 @@ individually.  Instead, a set of devices sharing a power resource can be put
 into a low-power state together at the same time by turning off the shared
 power resource.  Of course, they also need to be put into the full-power state
 together, by turning the shared power resource on.  A set of devices with this
-property is often referred to as a power domain.
+property is often referred to as a power domain. A power domain may also be
+nested inside another power domain.
+
+Devices and PM domains may be defined as IRQ-safe, if they can be powered
+on/off even when the IRQs are disabled. An IRQ-safe device in a domain will
+disallow power management on the domain, unless the domain is also defined as
+IRQ-safe. The restriction this framework imposes on the parent domain of an
+IRQ-safe domain is that it must also be defined as IRQ-safe.
 
 Support for power domains is provided through the pm_domain field of struct
 device.  This field is a pointer to an object of type struct dev_pm_domain,
-- 
2.7.4

^ 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