* Re: [PATCH v04 1/5] powerpc/drmem: Export 'dynamic-memory' loader
From: Nathan Fontenot @ 2018-10-10 16:54 UTC (permalink / raw)
To: Michael Bringmann, linuxppc-dev; +Cc: Juliet Kim, Thomas Falcon, Tyrel Datwyler
In-Reply-To: <20181009203541.26091.11334.stgit@ltcalpine2-lp9.aus.stglabs.ibm.com>
On 10/09/2018 03:36 PM, Michael Bringmann wrote:
> powerpc/drmem: Export many of the functions of DRMEM to parse
> "ibm,dynamic-memory" and "ibm,dynamic-memory-v2" during hotplug
> operations and for Post Migration events.
>
> Also modify the DRMEM initialization code to allow it to,
>
> * Be called after system initialization
> * Provide a separate user copy of the LMB array that is produces
> * Free the user copy upon request
>
> In addition, a couple of changes were made to make the creation
> of additional copies of the LMB array more useful including,
>
> * Add new iterator to work through a pair of drmem_info arrays.
> * Modify DRMEM code to replace usages of dt_root_addr_cells, and
> dt_mem_next_cell, as these are only available at first boot.
>
> Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/drmem.h | 15 ++++++++
> arch/powerpc/mm/drmem.c | 75 ++++++++++++++++++++++++++++----------
> 2 files changed, 70 insertions(+), 20 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/drmem.h b/arch/powerpc/include/asm/drmem.h
> index 7c1d8e7..1fbb684 100644
> --- a/arch/powerpc/include/asm/drmem.h
> +++ b/arch/powerpc/include/asm/drmem.h
> @@ -35,6 +35,18 @@ struct drmem_lmb_info {
> &drmem_info->lmbs[0], \
> &drmem_info->lmbs[drmem_info->n_lmbs - 1])
>
> +#define for_each_dinfo_lmb(dinfo, lmb) \
> + for_each_drmem_lmb_in_range((lmb), \
> + &dinfo->lmbs[0], \
> + &dinfo->lmbs[dinfo->n_lmbs - 1])
> +
> +#define for_each_pair_dinfo_lmb(dinfo1, lmb1, dinfo2, lmb2) \
> + for ((lmb1) = (&dinfo1->lmbs[0]), \
> + (lmb2) = (&dinfo2->lmbs[0]); \
> + ((lmb1) <= (&dinfo1->lmbs[dinfo1->n_lmbs - 1])) && \
> + ((lmb2) <= (&dinfo2->lmbs[dinfo2->n_lmbs - 1])); \
> + (lmb1)++, (lmb2)++)
> +
The macros for traversing seem to be getting a bit unwieldy with these
updates. I wonder if we should move to just using walk routine
for all traversing of the drmem lmbs.
> /*
> * The of_drconf_cell_v1 struct defines the layout of the LMB data
> * specified in the ibm,dynamic-memory device tree property.
> @@ -94,6 +106,9 @@ void __init walk_drmem_lmbs(struct device_node *dn,
> void (*func)(struct drmem_lmb *, const __be32 **));
> int drmem_update_dt(void);
>
> +struct drmem_lmb_info *drmem_lmbs_init(struct property *prop);
> +void drmem_lmbs_free(struct drmem_lmb_info *dinfo);
> +
> #ifdef CONFIG_PPC_PSERIES
> void __init walk_drmem_lmbs_early(unsigned long node,
> void (*func)(struct drmem_lmb *, const __be32 **));
> diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c
> index 3f18036..13d2abb 100644
> --- a/arch/powerpc/mm/drmem.c
> +++ b/arch/powerpc/mm/drmem.c
> @@ -20,6 +20,7 @@
>
> static struct drmem_lmb_info __drmem_info;
> struct drmem_lmb_info *drmem_info = &__drmem_info;
> +static int n_root_addr_cells;
>
> u64 drmem_lmb_memory_max(void)
> {
> @@ -193,12 +194,13 @@ int drmem_update_dt(void)
> return rc;
> }
>
> -static void __init read_drconf_v1_cell(struct drmem_lmb *lmb,
> +static void read_drconf_v1_cell(struct drmem_lmb *lmb,
> const __be32 **prop)
> {
> const __be32 *p = *prop;
>
> - lmb->base_addr = dt_mem_next_cell(dt_root_addr_cells, &p);
> + lmb->base_addr = of_read_number(p, n_root_addr_cells);
> + p += n_root_addr_cells;
Any reason this can't just be
lmb->base_addr= dt_mem_next_cell(n_root_addr_cells, &p);
> lmb->drc_index = of_read_number(p++, 1);
>
> p++; /* skip reserved field */
> @@ -209,7 +211,7 @@ static void __init read_drconf_v1_cell(struct drmem_lmb *lmb,
> *prop = p;
> }
>
> -static void __init __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm,
> +static void __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm,
> void (*func)(struct drmem_lmb *, const __be32 **))
> {
> struct drmem_lmb lmb;
> @@ -225,13 +227,14 @@ static void __init __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm,
> }
> }
>
> -static void __init read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
> +static void read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
> const __be32 **prop)
> {
> const __be32 *p = *prop;
>
> dr_cell->seq_lmbs = of_read_number(p++, 1);
> - dr_cell->base_addr = dt_mem_next_cell(dt_root_addr_cells, &p);
> + dr_cell->base_addr = of_read_number(p, n_root_addr_cells);
> + p += n_root_addr_cells;
Same here.
-Nathan
> dr_cell->drc_index = of_read_number(p++, 1);
> dr_cell->aa_index = of_read_number(p++, 1);
> dr_cell->flags = of_read_number(p++, 1);
> @@ -239,7 +242,7 @@ static void __init read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
> *prop = p;
> }
>
> -static void __init __walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm,
> +static void __walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm,
> void (*func)(struct drmem_lmb *, const __be32 **))
> {
> struct of_drconf_cell_v2 dr_cell;
> @@ -275,6 +278,9 @@ void __init walk_drmem_lmbs_early(unsigned long node,
> const __be32 *prop, *usm;
> int len;
>
> + if (n_root_addr_cells == 0)
> + n_root_addr_cells = dt_root_addr_cells;
> +
> prop = of_get_flat_dt_prop(node, "ibm,lmb-size", &len);
> if (!prop || len < dt_root_size_cells * sizeof(__be32))
> return;
> @@ -353,24 +359,26 @@ void __init walk_drmem_lmbs(struct device_node *dn,
> }
> }
>
> -static void __init init_drmem_v1_lmbs(const __be32 *prop)
> +static void init_drmem_v1_lmbs(const __be32 *prop,
> + struct drmem_lmb_info *dinfo)
> {
> struct drmem_lmb *lmb;
>> - drmem_info->n_lmbs = of_read_number(prop++, 1);
> - if (drmem_info->n_lmbs == 0)
> + dinfo->n_lmbs = of_read_number(prop++, 1);
> + if (dinfo->n_lmbs == 0)
> return;
>
> - drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb),
> + dinfo->lmbs = kcalloc(dinfo->n_lmbs, sizeof(*lmb),
> GFP_KERNEL);
> - if (!drmem_info->lmbs)
> + if (!dinfo->lmbs)
> return;
>
> - for_each_drmem_lmb(lmb)
> + for_each_dinfo_lmb(dinfo, lmb)
> read_drconf_v1_cell(lmb, &prop);
> }
>
> -static void __init init_drmem_v2_lmbs(const __be32 *prop)
> +static void init_drmem_v2_lmbs(const __be32 *prop,
> + struct drmem_lmb_info *dinfo)
> {
> struct drmem_lmb *lmb;
> struct of_drconf_cell_v2 dr_cell;
> @@ -386,12 +394,12 @@ static void __init init_drmem_v2_lmbs(const __be32 *prop)
> p = prop;
> for (i = 0; i < lmb_sets; i++) {
> read_drconf_v2_cell(&dr_cell, &p);
> - drmem_info->n_lmbs += dr_cell.seq_lmbs;
> + dinfo->n_lmbs += dr_cell.seq_lmbs;
> }
>
> - drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb),
> + dinfo->lmbs = kcalloc(dinfo->n_lmbs, sizeof(*lmb),
> GFP_KERNEL);
> - if (!drmem_info->lmbs)
> + if (!dinfo->lmbs)
> return;
>
> /* second pass, read in the LMB information */
> @@ -402,10 +410,10 @@ static void __init init_drmem_v2_lmbs(const __be32 *prop)
> read_drconf_v2_cell(&dr_cell, &p);
>
> for (j = 0; j < dr_cell.seq_lmbs; j++) {
> - lmb = &drmem_info->lmbs[lmb_index++];
> + lmb = &dinfo->lmbs[lmb_index++];
>
> lmb->base_addr = dr_cell.base_addr;
> - dr_cell.base_addr += drmem_info->lmb_size;
> + dr_cell.base_addr += dinfo->lmb_size;
>
> lmb->drc_index = dr_cell.drc_index;
> dr_cell.drc_index++;
> @@ -416,11 +424,38 @@ static void __init init_drmem_v2_lmbs(const __be32 *prop)
> }
> }
>
> +void drmem_lmbs_free(struct drmem_lmb_info *dinfo)
> +{
> + if (dinfo) {
> + kfree(dinfo->lmbs);
> + kfree(dinfo);
> + }
> +}
> +
> +struct drmem_lmb_info *drmem_lmbs_init(struct property *prop)
> +{
> + struct drmem_lmb_info *dinfo;
> +
> + dinfo = kzalloc(sizeof(*dinfo), GFP_KERNEL);
> + if (!dinfo)
> + return NULL;
> +
> + if (!strcmp("ibm,dynamic-memory", prop->name))
> + init_drmem_v1_lmbs(prop->value, dinfo);
> + else if (!strcmp("ibm,dynamic-memory-v2", prop->name))
> + init_drmem_v2_lmbs(prop->value, dinfo);
> +
> + return dinfo;
> +}
> +
> static int __init drmem_init(void)
> {
> struct device_node *dn;
> const __be32 *prop;
>
> + if (n_root_addr_cells == 0)
> + n_root_addr_cells = dt_root_addr_cells;
> +
> dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
> if (!dn) {
> pr_info("No dynamic reconfiguration memory found\n");
> @@ -434,11 +469,11 @@ static int __init drmem_init(void)
>
> prop = of_get_property(dn, "ibm,dynamic-memory", NULL);
> if (prop) {
> - init_drmem_v1_lmbs(prop);
> + init_drmem_v1_lmbs(prop, drmem_info);
> } else {
> prop = of_get_property(dn, "ibm,dynamic-memory-v2", NULL);
> if (prop)
> - init_drmem_v2_lmbs(prop);
> + init_drmem_v2_lmbs(prop, drmem_info);
> }
>
> of_node_put(dn);
>
^ permalink raw reply
* Re: [PATCH 13/36] dt-bindings: arm: Convert PMU binding to json-schema
From: Will Deacon @ 2018-10-10 16:50 UTC (permalink / raw)
To: Rob Herring
Cc: Mark Rutland, devicetree, Kumar Gala, Grant Likely, Arnd Bergmann,
Tom Rini, Frank Rowand, Linus Walleij, Pantelis Antoniou,
linux-kernel@vger.kernel.org, Bjorn Andersson, Mark Brown,
Geert Uytterhoeven, Jonathan Cameron, Olof Johansson,
linuxppc-dev,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <CAL_JsqLeG3WUa2peOWFGUoMuonWaWJoU-7A6d8cqXp-_e3B3XA@mail.gmail.com>
On Tue, Oct 09, 2018 at 01:14:02PM -0500, Rob Herring wrote:
> On Tue, Oct 9, 2018 at 6:57 AM Will Deacon <will.deacon@arm.com> wrote:
> >
> > Hi Rob,
> >
> > On Fri, Oct 05, 2018 at 11:58:25AM -0500, Rob Herring wrote:
> > > Convert ARM PMU binding to DT schema format using json-schema.
> > >
> > > Cc: Will Deacon <will.deacon@arm.com>
> > > Cc: Mark Rutland <mark.rutland@arm.com>
> > > Cc: linux-arm-kernel@lists.infradead.org
> > > Cc: devicetree@vger.kernel.org
> > > Signed-off-by: Rob Herring <robh@kernel.org>
> > > ---
> > > Documentation/devicetree/bindings/arm/pmu.txt | 70 --------------
> > > .../devicetree/bindings/arm/pmu.yaml | 96 +++++++++++++++++++
> > > 2 files changed, 96 insertions(+), 70 deletions(-)
> > > delete mode 100644 Documentation/devicetree/bindings/arm/pmu.txt
> > > create mode 100644 Documentation/devicetree/bindings/arm/pmu.yaml
> >
> > [...]
> >
> > > -- interrupts : 1 combined interrupt or 1 per core. If the interrupt is a per-cpu
> > > - interrupt (PPI) then 1 interrupt should be specified.
> >
> > [...]
> >
> > > + interrupts:
> > > + oneOf:
> > > + - maxItems: 1
> > > + - minItems: 2
> > > + maxItems: 8
> > > + description: 1 interrupt per core.
> > > +
> > > + interrupts-extended:
> > > + $ref: '#/properties/interrupts'
> >
> > This seems like a semantic different between the two representations, or am
> > I missing something here? Specifically, both the introduction of
> > interrupts-extended and also dropping any mention of using a single per-cpu
> > interrupt (the single combined case is no longer support by Linux; not sure
> > if you want to keep it in the binding).
>
> 'interrupts-extended' was implied before as it is always supported and
> outside the scope of the binding. But now it is needed to validate
> bindings. There must be some use of it and that's why I added it.
> However, thinking some more about this, I think it may be better to
> have the tools add this in automatically whenever we have an
> interrupts property.
To be honest, if you'd included that in the commit message I'd have been
happy :)
> I guess the single interrupt case is less obvious now with no
> description (it's the first list item of 'oneOf'). The schema If the
> single interrupt is not supported, then we can drop it here.
Well the description says "1 interrupt per core" which is incorrect. I also
don't understand why maxItems is 8.
Will
^ permalink raw reply
* Re: [PATCH] powerpc/pseries: Export maximum memory value
From: Naveen N. Rao @ 2018-10-10 16:49 UTC (permalink / raw)
To: Aravinda Prasad, linuxppc-dev, mpe, Nathan Fontenot
In-Reply-To: <0c429575-93e1-0ca9-9c75-29dec1e4105c@linux.vnet.ibm.com>
Nathan Fontenot wrote:
> On 10/10/2018 05:22 AM, Aravinda Prasad wrote:
>> This patch exports the maximum possible amount of memory
>> configured on the system via /proc/powerpc/lparcfg.
>>
>> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
>> ---
>> arch/powerpc/platforms/pseries/lparcfg.c | 13 +++++++++++++
>> 1 file changed, 13 insertions(+)
>>
>> diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c
>> index 7c872dc..aa82f55 100644
>> --- a/arch/powerpc/platforms/pseries/lparcfg.c
>> +++ b/arch/powerpc/platforms/pseries/lparcfg.c
>> @@ -26,6 +26,7 @@
>> #include <linux/seq_file.h>
>> #include <linux/slab.h>
>> #include <linux/uaccess.h>
>> +#include <linux/hugetlb.h>
>> #include <asm/lppaca.h>
>> #include <asm/hvcall.h>
>> #include <asm/firmware.h>
>> @@ -36,6 +37,7 @@
>> #include <asm/vio.h>
>> #include <asm/mmu.h>
>> #include <asm/machdep.h>
>> +#include <asm/drmem.h>
>>
>> #include "pseries.h"
>>
>> @@ -433,6 +435,16 @@ static void parse_em_data(struct seq_file *m)
>> seq_printf(m, "power_mode_data=%016lx\n", retbuf[0]);
>> }
>>
>> +static void maxmem_data(struct seq_file *m)
>> +{
>> + unsigned long maxmem = 0;
>> +
>> + maxmem += drmem_info->n_lmbs * drmem_info->lmb_size;
>> + maxmem += hugetlb_total_pages() * PAGE_SIZE;
>> +
>> + seq_printf(m, "MaxMem=%ld\n", maxmem);
>
> Should this be MaxPossibleMem?
>
> At least for the drmem memory the value calculated is the maximum possible
> memory. I wonder if calling it MaxMem would lead users to think they have
> that much memory available to them.
That's a good point. This seems to be referred to as just 'maximum
memory' in the LPAR configuration as well as in the lparstat
documentation, but it shouldn't hurt to rename it here.
- Naveen
^ permalink raw reply
* Re: [PATCH 1/2] powerpc/pseries: PAPR persistent memory support
From: Nathan Fontenot @ 2018-10-10 16:36 UTC (permalink / raw)
To: Oliver O'Halloran, linuxppc-dev; +Cc: linux-nvdimm
In-Reply-To: <20181010060812.20068-2-oohall@gmail.com>
On 10/10/2018 01:08 AM, Oliver O'Halloran wrote:
> This patch implements support for discovering storage class memory
> devices at boot and for handling hotplug of new regions via RTAS
> hotplug events.
>
> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
> ---
> arch/powerpc/include/asm/firmware.h | 3 ++-
> arch/powerpc/include/asm/hvcall.h | 10 +++++++++-
> arch/powerpc/include/asm/rtas.h | 2 ++
> arch/powerpc/kernel/rtasd.c | 2 ++
> arch/powerpc/platforms/pseries/Makefile | 2 +-
> arch/powerpc/platforms/pseries/dlpar.c | 4 ++++
> arch/powerpc/platforms/pseries/firmware.c | 1 +
> arch/powerpc/platforms/pseries/pseries.h | 5 +++++
> arch/powerpc/platforms/pseries/ras.c | 3 ++-
> 9 files changed, 28 insertions(+), 4 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h
> index 7a051bd21f87..113c64d5d394 100644
> --- a/arch/powerpc/include/asm/firmware.h
> +++ b/arch/powerpc/include/asm/firmware.h
> @@ -52,6 +52,7 @@
> #define FW_FEATURE_PRRN ASM_CONST(0x0000000200000000)
> #define FW_FEATURE_DRMEM_V2 ASM_CONST(0x0000000400000000)
> #define FW_FEATURE_DRC_INFO ASM_CONST(0x0000000800000000)
> +#define FW_FEATURE_PAPR_SCM ASM_CONST(0x0000001000000000)
>
> #ifndef __ASSEMBLY__
>
> @@ -69,7 +70,7 @@ enum {
> FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY |
> FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN |
> FW_FEATURE_HPT_RESIZE | FW_FEATURE_DRMEM_V2 |
> - FW_FEATURE_DRC_INFO,
> + FW_FEATURE_DRC_INFO | FW_FEATURE_PAPR_SCM,
> FW_FEATURE_PSERIES_ALWAYS = 0,
> FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL,
> FW_FEATURE_POWERNV_ALWAYS = 0,
> diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
> index a0b17f9f1ea4..0e81ef83b35a 100644
> --- a/arch/powerpc/include/asm/hvcall.h
> +++ b/arch/powerpc/include/asm/hvcall.h
> @@ -295,7 +295,15 @@
> #define H_INT_ESB 0x3C8
> #define H_INT_SYNC 0x3CC
> #define H_INT_RESET 0x3D0
> -#define MAX_HCALL_OPCODE H_INT_RESET
> +#define H_SCM_READ_METADATA 0x3E4
> +#define H_SCM_WRITE_METADATA 0x3E8
> +#define H_SCM_BIND_MEM 0x3EC
> +#define H_SCM_UNBIND_MEM 0x3F0
> +#define H_SCM_QUERY_BLOCK_MEM_BINDING 0x3F4
> +#define H_SCM_QUERY_LOGICAL_MEM_BINDING 0x3F8
> +#define H_SCM_MEM_QUERY 0x3FC
> +#define H_SCM_BLOCK_CLEAR 0x400
> +#define MAX_HCALL_OPCODE H_SCM_BLOCK_CLEAR
>
> /* H_VIOCTL functions */
> #define H_GET_VIOA_DUMP_SIZE 0x01
> diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
> index 71e393c46a49..1e81f3d55457 100644
> --- a/arch/powerpc/include/asm/rtas.h
> +++ b/arch/powerpc/include/asm/rtas.h
> @@ -125,6 +125,7 @@ struct rtas_suspend_me_data {
> #define RTAS_TYPE_INFO 0xE2
> #define RTAS_TYPE_DEALLOC 0xE3
> #define RTAS_TYPE_DUMP 0xE4
> +#define RTAS_TYPE_HOTPLUG 0xE5
> /* I don't add PowerMGM events right now, this is a different topic */
> #define RTAS_TYPE_PMGM_POWER_SW_ON 0x60
> #define RTAS_TYPE_PMGM_POWER_SW_OFF 0x61
> @@ -316,6 +317,7 @@ struct pseries_hp_errorlog {
> #define PSERIES_HP_ELOG_RESOURCE_MEM 2
> #define PSERIES_HP_ELOG_RESOURCE_SLOT 3
> #define PSERIES_HP_ELOG_RESOURCE_PHB 4
> +#define PSERIES_HP_ELOG_RESOURCE_PMEM 6
>
> #define PSERIES_HP_ELOG_ACTION_ADD 1
> #define PSERIES_HP_ELOG_ACTION_REMOVE 2
> diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
> index 6fafc82c04b0..fad0baddfcba 100644
> --- a/arch/powerpc/kernel/rtasd.c
> +++ b/arch/powerpc/kernel/rtasd.c
> @@ -91,6 +91,8 @@ static char *rtas_event_type(int type)
> return "Dump Notification Event";
> case RTAS_TYPE_PRRN:
> return "Platform Resource Reassignment Event";
> + case RTAS_TYPE_HOTPLUG:
> + return "Hotplug Event";
> }
>
> return rtas_type[0];
> diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
> index 7e89d5c47068..892b27ced973 100644
> --- a/arch/powerpc/platforms/pseries/Makefile
> +++ b/arch/powerpc/platforms/pseries/Makefile
> @@ -13,7 +13,7 @@ obj-$(CONFIG_KEXEC_CORE) += kexec.o
> obj-$(CONFIG_PSERIES_ENERGY) += pseries_energy.o
>
> obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o
> -obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o
> +obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o pmem.o
>
> obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
> obj-$(CONFIG_HVCS) += hvcserver.o
> diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
> index a0b20c03f078..795996fefdb9 100644
> --- a/arch/powerpc/platforms/pseries/dlpar.c
> +++ b/arch/powerpc/platforms/pseries/dlpar.c
> @@ -357,6 +357,10 @@ static int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog)
> case PSERIES_HP_ELOG_RESOURCE_CPU:
> rc = dlpar_cpu(hp_elog);
> break;
> + case PSERIES_HP_ELOG_RESOURCE_PMEM:
> + rc = dlpar_hp_pmem(hp_elog);
You reference a dlpar handler for pmem here but I am not finding a handler
defined when CONFIG_MEMORY_HOTPLUG is defined. The update to pseries.h below
only provides a definition when it is not defined.
Also, do we need to handle dlpar of pmem memory? There have been discussion of
supporting this in the future but I did not thin it was currently supported.
-Nathan
> + break;
> +
> default:
> pr_warn_ratelimited("Invalid resource (%d) specified\n",
> hp_elog->resource);
> diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
> index a3bbeb43689e..4927de57d8ee 100644
> --- a/arch/powerpc/platforms/pseries/firmware.c
> +++ b/arch/powerpc/platforms/pseries/firmware.c
> @@ -65,6 +65,7 @@ hypertas_fw_features_table[] = {
> {FW_FEATURE_SET_MODE, "hcall-set-mode"},
> {FW_FEATURE_BEST_ENERGY, "hcall-best-energy-1*"},
> {FW_FEATURE_HPT_RESIZE, "hcall-hpt-resize"},
> + {FW_FEATURE_PAPR_SCM, "hcall-scm"},
> };
>
> /* Build up the firmware features bitmask using the contents of
> diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
> index 60db2ee511fb..d0829677c896 100644
> --- a/arch/powerpc/platforms/pseries/pseries.h
> +++ b/arch/powerpc/platforms/pseries/pseries.h
> @@ -63,11 +63,16 @@ void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog,
> struct completion *hotplug_done, int *rc);
> #ifdef CONFIG_MEMORY_HOTPLUG
> int dlpar_memory(struct pseries_hp_errorlog *hp_elog);
> +int dlpar_hp_pmem(struct pseries_hp_errorlog *hp_elog);
> #else
> static inline int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
> {
> return -EOPNOTSUPP;
> }
> +int dlpar_hp_pmem(struct pseries_hp_errorlog *hp_elog)
> +{
> + return -EOPNOTSUPP;
> +};
> #endif
>
> #ifdef CONFIG_HOTPLUG_CPU
> diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
> index 851ce326874a..ae22fc007276 100644
> --- a/arch/powerpc/platforms/pseries/ras.c
> +++ b/arch/powerpc/platforms/pseries/ras.c
> @@ -237,7 +237,8 @@ static irqreturn_t ras_hotplug_interrupt(int irq, void *dev_id)
> * hotplug events on the ras_log_buf to be handled by rtas_errd.
> */
> if (hp_elog->resource == PSERIES_HP_ELOG_RESOURCE_MEM ||
> - hp_elog->resource == PSERIES_HP_ELOG_RESOURCE_CPU)
> + hp_elog->resource == PSERIES_HP_ELOG_RESOURCE_CPU ||
> + hp_elog->resource == PSERIES_HP_ELOG_RESOURCE_PMEM)
> queue_hotplug_event(hp_elog, NULL, NULL);
> else
> log_error(ras_log_buf, ERR_TYPE_RTAS_LOG, 0);
>
^ permalink raw reply
* Re: [PATCH 0/2] sriov enablement on s390
From: Bjorn Helgaas @ 2018-10-10 16:26 UTC (permalink / raw)
To: Sebastian Ott
Cc: Arnd Bergmann, linux-pci, Paul Mackerras, Bjorn Helgaas,
linuxppc-dev
In-Reply-To: <alpine.LFD.2.21.1810101451310.32089@schleppi.aag-de.ibmmobiledemo.com>
On Wed, Oct 10, 2018 at 02:55:07PM +0200, Sebastian Ott wrote:
> Hello Bjorn,
>
> On Wed, 12 Sep 2018, Bjorn Helgaas wrote:
> > On Wed, Sep 12, 2018 at 02:34:09PM +0200, Sebastian Ott wrote:
> > > On s390 we currently handle SRIOV within firmware. Which means
> > > that the PF is under firmware control and not visible to operating
> > > systems. SRIOV enablement happens within firmware and VFs are
> > > passed through to logical partitions.
> > >
> > > I'm working on a new mode were the PF is under operating system
> > > control (including SRIOV enablement). However we still need
> > > firmware support to access the VFs. The way this is supposed
> > > to work is that when firmware traps the SRIOV enablement it
> > > will present machine checks to the logical partition that
> > > triggered the SRIOV enablement and provide the VFs via hotplug
> > > events.
> > >
> > > The problem I'm faced with is that the VF detection code in
> > > sriov_enable leads to unusable functions in s390.
> >
> > We're moving away from the weak function implementation style. Can
> > you take a look at Arnd's work here, which uses pci_host_bridge
> > callbacks instead?
> >
> > https://lkml.kernel.org/r/20180817102645.3839621-1-arnd@arndb.de
>
> What's the status of Arnd's patches - will they go upstream in the next
> couple of versions?
I hope so [1]. IIRC Arnd mentioned doing some minor updates, so I'm
waiting on that.
> What about my patches that I rebased on Arnd's branch
> will they be considered?
Definitely. From my point of view they're just lined up behind Arnd's
patches.
[1] https://lore.kernel.org/linux-pci/20181002205903.GD120535@bhelgaas-glaptop.roam.corp.google.com
^ permalink raw reply
* Re: [PATCH v02] powerpc/mobility: Extend start/stop topology update scope
From: Nathan Fontenot @ 2018-10-10 16:24 UTC (permalink / raw)
To: Michael Bringmann, linuxppc-dev; +Cc: Juliet Kim, Thomas Falcon, Tyrel Datwyler
In-Reply-To: <20181009195504.22636.20595.stgit@ltcalpine2-lp9.aus.stglabs.ibm.com>
On 10/09/2018 03:12 PM, Michael Bringmann wrote:
> The PPC mobility code may receive RTAS requests to perform PRRN
> topology changes at any time, including during LPAR migration
> operations. In some configurations where the affinity of CPUs
> or memory is being changed on that platform, the PRRN requests
> may apply or refer to outdated information prior to the complete
> update of the device-tree. This patch changes the duration for
> which topology updates are suppressed during LPAR migrations from
> just the rtas_ibm_suspend_me / 'ibm,suspend-me' call(s) to cover
> the entire 'migration_store' operation to allow all changes to
> the device-tree to be applied prior to accepting and applying any
> PRRN requests.
>
> For tracking purposes, pr_info notices are added to the functions
> start_topology_update() and stop_topology_update() of 'numa.c'.
>
> Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
Reviewed-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
> ---
> Changes in v02:
> -- Rebase to latest powerpc next tree.
> ---
> arch/powerpc/kernel/rtas.c | 2 --
> arch/powerpc/mm/numa.c | 6 ++++++
> arch/powerpc/platforms/pseries/mobility.c | 5 +++++
> 3 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
> index 2c7ed31..e02ac37 100644
> --- a/arch/powerpc/kernel/rtas.c
> +++ b/arch/powerpc/kernel/rtas.c
> @@ -982,7 +982,6 @@ int rtas_ibm_suspend_me(u64 handle)
> }
>
> cpu_hotplug_disable();
> - stop_topology_update();
>
> /* Call function on all CPUs. One of us will make the
> * rtas call
> @@ -995,7 +994,6 @@ int rtas_ibm_suspend_me(u64 handle)
> if (atomic_read(&data.error) != 0)
> printk(KERN_ERR "Error doing global join\n");
>
> - start_topology_update();
> cpu_hotplug_enable();
>
> /* Take down CPUs not online prior to suspend */
> diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
> index b5a71ba..0ade0a1 100644
> --- a/arch/powerpc/mm/numa.c
> +++ b/arch/powerpc/mm/numa.c
> @@ -1518,6 +1518,10 @@ int start_topology_update(void)
> }
> }
>
> + pr_info("Starting topology update%s%s\n",
> + (prrn_enabled ? " prrn_enabled" : ""),
> + (vphn_enabled ? " vphn_enabled" : ""));
> +
> return rc;
> }
>
> @@ -1539,6 +1543,8 @@ int stop_topology_update(void)
> rc = del_timer_sync(&topology_timer);
> }
>
> + pr_info("Stopping topology update\n");
> +
> return rc;
> }
>
> diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
> index 2f0f512..7da222d 100644
> --- a/arch/powerpc/platforms/pseries/mobility.c
> +++ b/arch/powerpc/platforms/pseries/mobility.c
> @@ -367,6 +367,8 @@ static ssize_t migration_store(struct class *class,
> if (rc)
> return rc;
>
> + stop_topology_update();
> +
> do {
> rc = rtas_ibm_suspend_me(streamid);
> if (rc == -EAGAIN)
> @@ -377,6 +379,9 @@ static ssize_t migration_store(struct class *class,
> return rc;
>
> post_mobility_fixup();
> +
> + start_topology_update();
> +
> return count;
> }
>
>
^ permalink raw reply
* Re: [PATCH] powerpc/pseries: Export maximum memory value
From: Nathan Fontenot @ 2018-10-10 16:20 UTC (permalink / raw)
To: Aravinda Prasad, mpe, linuxppc-dev; +Cc: naveen.n.rao
In-Reply-To: <153916697991.21165.5694207762066031403.stgit@aravinda>
On 10/10/2018 05:22 AM, Aravinda Prasad wrote:
> This patch exports the maximum possible amount of memory
> configured on the system via /proc/powerpc/lparcfg.
>
> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
> ---
> arch/powerpc/platforms/pseries/lparcfg.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c
> index 7c872dc..aa82f55 100644
> --- a/arch/powerpc/platforms/pseries/lparcfg.c
> +++ b/arch/powerpc/platforms/pseries/lparcfg.c
> @@ -26,6 +26,7 @@
> #include <linux/seq_file.h>
> #include <linux/slab.h>
> #include <linux/uaccess.h>
> +#include <linux/hugetlb.h>
> #include <asm/lppaca.h>
> #include <asm/hvcall.h>
> #include <asm/firmware.h>
> @@ -36,6 +37,7 @@
> #include <asm/vio.h>
> #include <asm/mmu.h>
> #include <asm/machdep.h>
> +#include <asm/drmem.h>
>
> #include "pseries.h"
>
> @@ -433,6 +435,16 @@ static void parse_em_data(struct seq_file *m)
> seq_printf(m, "power_mode_data=%016lx\n", retbuf[0]);
> }
>
> +static void maxmem_data(struct seq_file *m)
> +{
> + unsigned long maxmem = 0;
> +
> + maxmem += drmem_info->n_lmbs * drmem_info->lmb_size;
> + maxmem += hugetlb_total_pages() * PAGE_SIZE;
> +
> + seq_printf(m, "MaxMem=%ld\n", maxmem);
Should this be MaxPossibleMem?
At least for the drmem memory the value calculated is the maximum possible
memory. I wonder if calling it MaxMem would lead users to think they have
that much memory available to them.
-Nathan
> +}
> +
> static int pseries_lparcfg_data(struct seq_file *m, void *v)
> {
> int partition_potential_processors;
> @@ -491,6 +503,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
> seq_printf(m, "slb_size=%d\n", mmu_slb_size);
> #endif
> parse_em_data(m);
> + maxmem_data(m);
>
> return 0;
> }
>
^ permalink raw reply
* Re: [PATCH v3 -next] powerpc/pseries/memory-hotplug: Fix return value type of find_aa_index
From: Nathan Fontenot @ 2018-10-10 16:11 UTC (permalink / raw)
To: YueHaibing, benh, paulus, mpe; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20181009135913.14616-1-yuehaibing@huawei.com>
On 10/09/2018 08:59 AM, YueHaibing wrote:
> 'aa_index' is defined as an unsigned value, but find_aa_index
> may return -1 when dlpar_clone_property fails. So change
> find_aa_index return value type to bool, which indicate 'aa_index'
> whether found or not.
>
> Fixes: c05a5a40969e ("powerpc/pseries: Dynamic add entires to associativity lookup array")
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Reviewed-by: Nathan Fontenot nfont@linux.vnet.ibm.com>
> ---
> v3: change find_aa_index return type to bool
> v2: use 'rc' track the validation of aa_index
> ---
> arch/powerpc/platforms/pseries/hotplug-memory.c | 61 ++++++++++++-------------
> 1 file changed, 28 insertions(+), 33 deletions(-)
>
> diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
> index d26a771..4db510f 100644
> --- a/arch/powerpc/platforms/pseries/hotplug-memory.c
> +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
> @@ -101,11 +101,12 @@ static struct property *dlpar_clone_property(struct property *prop,
> return new_prop;
> }
>
> -static u32 find_aa_index(struct device_node *dr_node,
> - struct property *ala_prop, const u32 *lmb_assoc)
> +static bool find_aa_index(struct device_node *dr_node,
> + struct property *ala_prop,
> + const u32 *lmb_assoc, u32 *aa_index)
> {
> - u32 *assoc_arrays;
> - u32 aa_index;
> + u32 *assoc_arrays, new_prop_size;
> + struct property *new_prop;
> int aa_arrays, aa_array_entries, aa_array_sz;
> int i, index;
>
> @@ -121,46 +122,39 @@ static u32 find_aa_index(struct device_node *dr_node,
> aa_array_entries = be32_to_cpu(assoc_arrays[1]);
> aa_array_sz = aa_array_entries * sizeof(u32);
>
> - aa_index = -1;
> for (i = 0; i < aa_arrays; i++) {
> index = (i * aa_array_entries) + 2;
>
> if (memcmp(&assoc_arrays[index], &lmb_assoc[1], aa_array_sz))
> continue;
>
> - aa_index = i;
> - break;
> + *aa_index = i;
> + return true;
> }
>
> - if (aa_index == -1) {
> - struct property *new_prop;
> - u32 new_prop_size;
> -
> - new_prop_size = ala_prop->length + aa_array_sz;
> - new_prop = dlpar_clone_property(ala_prop, new_prop_size);
> - if (!new_prop)
> - return -1;
> -
> - assoc_arrays = new_prop->value;
> + new_prop_size = ala_prop->length + aa_array_sz;
> + new_prop = dlpar_clone_property(ala_prop, new_prop_size);
> + if (!new_prop)
> + return false;
>
> - /* increment the number of entries in the lookup array */
> - assoc_arrays[0] = cpu_to_be32(aa_arrays + 1);
> + assoc_arrays = new_prop->value;
>
> - /* copy the new associativity into the lookup array */
> - index = aa_arrays * aa_array_entries + 2;
> - memcpy(&assoc_arrays[index], &lmb_assoc[1], aa_array_sz);
> + /* increment the number of entries in the lookup array */
> + assoc_arrays[0] = cpu_to_be32(aa_arrays + 1);
>
> - of_update_property(dr_node, new_prop);
> + /* copy the new associativity into the lookup array */
> + index = aa_arrays * aa_array_entries + 2;
> + memcpy(&assoc_arrays[index], &lmb_assoc[1], aa_array_sz);
>
> - /*
> - * The associativity lookup array index for this lmb is
> - * number of entries - 1 since we added its associativity
> - * to the end of the lookup array.
> - */
> - aa_index = be32_to_cpu(assoc_arrays[0]) - 1;
> - }
> + of_update_property(dr_node, new_prop);
>
> - return aa_index;
> + /*
> + * The associativity lookup array index for this lmb is
> + * number of entries - 1 since we added its associativity
> + * to the end of the lookup array.
> + */
> + *aa_index = be32_to_cpu(assoc_arrays[0]) - 1;
> + return true;
> }
>
> static int update_lmb_associativity_index(struct drmem_lmb *lmb)
> @@ -169,6 +163,7 @@ static int update_lmb_associativity_index(struct drmem_lmb *lmb)
> struct property *ala_prop;
> const u32 *lmb_assoc;
> u32 aa_index;
> + bool is_found;
>
> parent = of_find_node_by_path("/");
> if (!parent)
> @@ -200,11 +195,11 @@ static int update_lmb_associativity_index(struct drmem_lmb *lmb)
> return -ENODEV;
> }
>
> - aa_index = find_aa_index(dr_node, ala_prop, lmb_assoc);
> + is_found = find_aa_index(dr_node, ala_prop, lmb_assoc, &aa_index);
>
> dlpar_free_cc_nodes(lmb_node);
>
> - if (aa_index < 0) {
> + if (!is_found) {
> pr_err("Could not find LMB associativity\n");
> return -1;
> }
>
^ permalink raw reply
* Re: [PATCH 4/4] powerpc: Add -Wimplicit-fallthrough to arch CFLAGS
From: Kees Cook @ 2018-10-10 14:47 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, maddy, Gustavo A. R. Silva
In-Reply-To: <20181010051308.25422-4-mpe@ellerman.id.au>
On Tue, Oct 9, 2018 at 10:13 PM, Michael Ellerman <mpe@ellerman.id.au> wrote:
> Warn whenever a switch statement has a fallthrough without a comment
> annotating it.
>
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Yes please. :)
Reviewed-by: Kees Cook <keescook@chromium.org>
-Kees
> ---
> arch/powerpc/Kbuild | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/powerpc/Kbuild b/arch/powerpc/Kbuild
> index 86b261d6bde5..ef625f1db576 100644
> --- a/arch/powerpc/Kbuild
> +++ b/arch/powerpc/Kbuild
> @@ -1,4 +1,5 @@
> subdir-ccflags-y := $(call cc-option, -Wvla)
> +subdir-ccflags-y += $(call cc-option, -Wimplicit-fallthrough)
> subdir-ccflags-$(CONFIG_PPC_WERROR) += -Werror
>
> obj-y += kernel/
> --
> 2.17.1
>
--
Kees Cook
Pixel Security
^ permalink raw reply
* Re: [PATCH 3/4] powerpc: Add -Wvla to arch CFLAGS
From: Kees Cook @ 2018-10-10 14:45 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, maddy
In-Reply-To: <20181010051308.25422-3-mpe@ellerman.id.au>
On Tue, Oct 9, 2018 at 10:13 PM, Michael Ellerman <mpe@ellerman.id.au> wrote:
> Upstream has declared that Variable Length Array's (VLAs) are a bad
> idea, and eventually -Wvla will be added to the top-level Makefile. We
> can go one better and make sure we don't introduce any more by adding
> it to the arch Makefile.
>
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> ---
> arch/powerpc/Kbuild | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/Kbuild b/arch/powerpc/Kbuild
> index 1625a06802ca..86b261d6bde5 100644
> --- a/arch/powerpc/Kbuild
> +++ b/arch/powerpc/Kbuild
> @@ -1,4 +1,5 @@
> -subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
> +subdir-ccflags-y := $(call cc-option, -Wvla)
> +subdir-ccflags-$(CONFIG_PPC_WERROR) += -Werror
>
> obj-y += kernel/
> obj-y += mm/
-Wvla will be going into the top-level Makefile in the merge window
(see linux-next), so this will be redundant.
-Kees
--
Kees Cook
Pixel Security
^ permalink raw reply
* Re: [PATCH 0/2] sriov enablement on s390
From: Sebastian Ott @ 2018-10-10 12:55 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Arnd Bergmann, linux-pci, Paul Mackerras, Bjorn Helgaas,
linuxppc-dev
In-Reply-To: <20180912130205.GG118330@bhelgaas-glaptop.roam.corp.google.com>
Hello Bjorn,
On Wed, 12 Sep 2018, Bjorn Helgaas wrote:
> On Wed, Sep 12, 2018 at 02:34:09PM +0200, Sebastian Ott wrote:
> > On s390 we currently handle SRIOV within firmware. Which means
> > that the PF is under firmware control and not visible to operating
> > systems. SRIOV enablement happens within firmware and VFs are
> > passed through to logical partitions.
> >
> > I'm working on a new mode were the PF is under operating system
> > control (including SRIOV enablement). However we still need
> > firmware support to access the VFs. The way this is supposed
> > to work is that when firmware traps the SRIOV enablement it
> > will present machine checks to the logical partition that
> > triggered the SRIOV enablement and provide the VFs via hotplug
> > events.
> >
> > The problem I'm faced with is that the VF detection code in
> > sriov_enable leads to unusable functions in s390.
>
> We're moving away from the weak function implementation style. Can
> you take a look at Arnd's work here, which uses pci_host_bridge
> callbacks instead?
>
> https://lkml.kernel.org/r/20180817102645.3839621-1-arnd@arndb.de
What's the status of Arnd's patches - will they go upstream in the next
couple of versions? What about my patches that I rebased on Arnd's branch
will they be considered?
Regards,
Sebastian
^ permalink raw reply
* Re: [PATCH 1/2] powerpc/boot: Expose Kconfig symbols to wrapper
From: Michael Ellerman @ 2018-10-10 12:28 UTC (permalink / raw)
To: Joel Stanley, linuxppc-dev; +Cc: Oliver O'Halloran
In-Reply-To: <20181009232803.15072-2-joel@jms.id.au>
Joel Stanley <joel@jms.id.au> writes:
> diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
> index 0fb96c26136f..eeed74e0dfca 100644
> --- a/arch/powerpc/boot/Makefile
> +++ b/arch/powerpc/boot/Makefile
> @@ -197,9 +197,14 @@ $(obj)/empty.c:
> $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S
> $(Q)cp $< $@
>
> +$(obj)/serial.c: $(obj)/autoconf.h
> +
> +$(obj)/autoconf.h: $(obj)/%: $(srctree)/include/generated/%
> + $(Q)cp $< $@
> +
This gives me:
make[2]: *** No rule to make target '../include/generated/autoconf.h', needed by 'arch/powerpc/boot/autoconf.h'. Stop.
The ../ is $(srctree).
cheers
^ permalink raw reply
* Re: [PATCH 1/2] powerpc/boot: Disable vector instructions
From: Michael Ellerman @ 2018-10-10 12:11 UTC (permalink / raw)
To: Joel Stanley, linuxppc-dev; +Cc: Oliver O'Halloran
In-Reply-To: <20181010024523.4921-2-joel@jms.id.au>
Joel Stanley <joel@jms.id.au> writes:
> This will avoid auto-vectorisation when building with higher
> optimisation levels.
>
> We don't know if the machine can support VSX and even if it's present
> it's probably not going to be enabled at this point in boot.
>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
> arch/powerpc/boot/Makefile | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
> index 0fb96c26136f..739ef8d43b91 100644
> --- a/arch/powerpc/boot/Makefile
> +++ b/arch/powerpc/boot/Makefile
> @@ -32,8 +32,8 @@ else
> endif
>
> BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
> - -fno-strict-aliasing -Os -msoft-float -pipe \
> - -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
> + -fno-strict-aliasing -Os -msoft-float -mno-altivec -mno-vsx \
That's going to break if the compiler doesn't understand -mno-vsx isn't it?
I'm not sure if "support" a compiler that old though.
cheers
^ permalink raw reply
* Re: [PATCH] memblock: stop using implicit alignement to SMP_CACHE_BYTES
From: Michael Ellerman @ 2018-10-10 12:04 UTC (permalink / raw)
To: Mike Rapoport, linux-mm
Cc: linux-mips, Michal Hocko, linux-ia64, Catalin Marinas,
Richard Weinberger, Russell King, Ingo Molnar, Geert Uytterhoeven,
Matt Turner, linux-um, linux-m68k, Mike Rapoport, Thomas Gleixner,
Guan Xuetao, linux-arm-kernel, Chris Zankel, Michal Simek,
Tony Luck, linux-kernel, Paul Burton, linux-alpha, Andrew Morton,
linuxppc-dev
In-Reply-To: <1538687224-17535-1-git-send-email-rppt@linux.vnet.ibm.com>
Mike Rapoport <rppt@linux.vnet.ibm.com> writes:
> When a memblock allocation APIs are called with align = 0, the alignment is
> implicitly set to SMP_CACHE_BYTES.
>
> Replace all such uses of memblock APIs with the 'align' parameter explicitly
> set to SMP_CACHE_BYTES and stop implicit alignment assignment in the
> memblock internal allocation functions.
>
> For the case when memblock APIs are used via helper functions, e.g. like
> iommu_arena_new_node() in Alpha, the helper functions were detected with
> Coccinelle's help and then manually examined and updated where appropriate.
>
> The direct memblock APIs users were updated using the semantic patch below:
>
> @@
> expression size, min_addr, max_addr, nid;
> @@
> (
> |
> - memblock_alloc_try_nid_raw(size, 0, min_addr, max_addr, nid)
> + memblock_alloc_try_nid_raw(size, SMP_CACHE_BYTES, min_addr, max_addr,
> nid)
> |
> - memblock_alloc_try_nid_nopanic(size, 0, min_addr, max_addr, nid)
> + memblock_alloc_try_nid_nopanic(size, SMP_CACHE_BYTES, min_addr, max_addr,
> nid)
> |
> - memblock_alloc_try_nid(size, 0, min_addr, max_addr, nid)
> + memblock_alloc_try_nid(size, SMP_CACHE_BYTES, min_addr, max_addr, nid)
> |
> - memblock_alloc(size, 0)
> + memblock_alloc(size, SMP_CACHE_BYTES)
> |
> - memblock_alloc_raw(size, 0)
> + memblock_alloc_raw(size, SMP_CACHE_BYTES)
> |
> - memblock_alloc_from(size, 0, min_addr)
> + memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr)
> |
> - memblock_alloc_nopanic(size, 0)
> + memblock_alloc_nopanic(size, SMP_CACHE_BYTES)
> |
> - memblock_alloc_low(size, 0)
> + memblock_alloc_low(size, SMP_CACHE_BYTES)
> |
> - memblock_alloc_low_nopanic(size, 0)
> + memblock_alloc_low_nopanic(size, SMP_CACHE_BYTES)
> |
> - memblock_alloc_from_nopanic(size, 0, min_addr)
> + memblock_alloc_from_nopanic(size, SMP_CACHE_BYTES, min_addr)
> |
> - memblock_alloc_node(size, 0, nid)
> + memblock_alloc_node(size, SMP_CACHE_BYTES, nid)
> )
>
> Suggested-by: Michal Hocko <mhocko@suse.com>
> Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
> ---
...
> arch/powerpc/kernel/pci_32.c | 3 ++-
> arch/powerpc/lib/alloc.c | 2 +-
> arch/powerpc/mm/mmu_context_nohash.c | 7 +++---
> arch/powerpc/platforms/powermac/nvram.c | 2 +-
> arch/powerpc/platforms/powernv/pci-ioda.c | 6 ++---
> arch/powerpc/sysdev/msi_bitmap.c | 2 +-
The powerpc changes all look fine.
I'm not quite clear on how SMP_CACHE_BYTES is getting included.
I think it's: memblock.h -> mm.h -> mmzone.h -> cache.h
So that's probably fine.
Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc)
cheers
^ permalink raw reply
* [PATCH] powerpc/pseries: Export maximum memory value
From: Aravinda Prasad @ 2018-10-10 10:22 UTC (permalink / raw)
To: mpe, linuxppc-dev; +Cc: nfont, naveen.n.rao, aravinda
This patch exports the maximum possible amount of memory
configured on the system via /proc/powerpc/lparcfg.
Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
---
arch/powerpc/platforms/pseries/lparcfg.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c
index 7c872dc..aa82f55 100644
--- a/arch/powerpc/platforms/pseries/lparcfg.c
+++ b/arch/powerpc/platforms/pseries/lparcfg.c
@@ -26,6 +26,7 @@
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
+#include <linux/hugetlb.h>
#include <asm/lppaca.h>
#include <asm/hvcall.h>
#include <asm/firmware.h>
@@ -36,6 +37,7 @@
#include <asm/vio.h>
#include <asm/mmu.h>
#include <asm/machdep.h>
+#include <asm/drmem.h>
#include "pseries.h"
@@ -433,6 +435,16 @@ static void parse_em_data(struct seq_file *m)
seq_printf(m, "power_mode_data=%016lx\n", retbuf[0]);
}
+static void maxmem_data(struct seq_file *m)
+{
+ unsigned long maxmem = 0;
+
+ maxmem += drmem_info->n_lmbs * drmem_info->lmb_size;
+ maxmem += hugetlb_total_pages() * PAGE_SIZE;
+
+ seq_printf(m, "MaxMem=%ld\n", maxmem);
+}
+
static int pseries_lparcfg_data(struct seq_file *m, void *v)
{
int partition_potential_processors;
@@ -491,6 +503,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
seq_printf(m, "slb_size=%d\n", mmu_slb_size);
#endif
parse_em_data(m);
+ maxmem_data(m);
return 0;
}
^ permalink raw reply related
* Re: [PATCH 32/36] dt-bindings: arm: Convert ST STi board/soc bindings to json-schema
From: Patrice CHOTARD @ 2018-10-10 9:19 UTC (permalink / raw)
To: Rob Herring, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linuxppc-dev@lists.ozlabs.org
Cc: Mark Rutland, Tom Rini, Kumar Gala, Grant Likely, Arnd Bergmann,
Linus Walleij, Pantelis Antoniou, Bjorn Andersson, Mark Brown,
Geert Uytterhoeven, Olof Johansson, Frank Rowand,
Jonathan Cameron
In-Reply-To: <20181005165848.3474-33-robh@kernel.org>
Hi Rob
On 10/05/2018 06:58 PM, Rob Herring wrote:
> Convert ST STi SoC bindings to DT schema format using json-schema.
>
> Cc: Patrice Chotard <patrice.chotard@st.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
> Documentation/devicetree/bindings/arm/sti.txt | 23 -------------------
> .../devicetree/bindings/arm/sti.yaml | 23 +++++++++++++++++++
> 2 files changed, 23 insertions(+), 23 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/arm/sti.txt
> create mode 100644 Documentation/devicetree/bindings/arm/sti.yaml
>
> diff --git a/Documentation/devicetree/bindings/arm/sti.txt b/Documentation/devicetree/bindings/arm/sti.txt
> deleted file mode 100644
> index 8d27f6b084c7..000000000000
> --- a/Documentation/devicetree/bindings/arm/sti.txt
> +++ /dev/null
> @@ -1,23 +0,0 @@
> -ST STi Platforms Device Tree Bindings
> ----------------------------------------
> -
> -Boards with the ST STiH415 SoC shall have the following properties:
> -Required root node property:
> -compatible = "st,stih415";
> -
> -Boards with the ST STiH416 SoC shall have the following properties:
> -Required root node property:
> -compatible = "st,stih416";
> -
> -Boards with the ST STiH407 SoC shall have the following properties:
> -Required root node property:
> -compatible = "st,stih407";
> -
> -Boards with the ST STiH410 SoC shall have the following properties:
> -Required root node property:
> -compatible = "st,stih410";
> -
> -Boards with the ST STiH418 SoC shall have the following properties:
> -Required root node property:
> -compatible = "st,stih418";
> -
> diff --git a/Documentation/devicetree/bindings/arm/sti.yaml b/Documentation/devicetree/bindings/arm/sti.yaml
> new file mode 100644
> index 000000000000..10814334cfc9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/sti.yaml
> @@ -0,0 +1,23 @@
> +# SPDX-License-Identifier: None
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/bindings/arm/sti.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ST STi Platforms Device Tree Bindings
> +
> +maintainers:
> + - Maxime Coquelin <maxime.coquelin@st.com>
Maxime has left STMicroelectronics, you can replace its email by mine
Patrice Chotard <patrice.chotard@st.com>
Thanks
Patrice
> +
> +properties:
> + $nodename:
> + const: '/'
> + compatible:
> + items:
> + - enum:
> + - st,stih415
> + - st,stih416
> + - st,stih407
> + - st,stih410
> + - st,stih418
> +...
>
^ permalink raw reply
* Re: [PATCH] memblock: stop using implicit alignement to SMP_CACHE_BYTES
From: Michal Hocko @ 2018-10-10 7:58 UTC (permalink / raw)
To: Mike Rapoport
Cc: linux-mips, linux-ia64, Catalin Marinas, linux-mm,
Richard Weinberger, Russell King, Ingo Molnar, Geert Uytterhoeven,
Matt Turner, linux-um, linux-m68k, Thomas Gleixner, Guan Xuetao,
linux-arm-kernel, Chris Zankel, Michal Simek, Tony Luck,
linux-kernel, Paul Burton, linux-alpha, Andrew Morton,
linuxppc-dev
In-Reply-To: <1538687224-17535-1-git-send-email-rppt@linux.vnet.ibm.com>
On Fri 05-10-18 00:07:04, Mike Rapoport wrote:
> When a memblock allocation APIs are called with align = 0, the alignment is
> implicitly set to SMP_CACHE_BYTES.
I would add something like
"
Implicit alignment is done deep in the memblock allocator and it can
come as a surprise. Not that such an alignment would be wrong even when
used incorrectly but it is better to be explicit for the sake of clarity
and the prinicple of the least surprise.
"
> Replace all such uses of memblock APIs with the 'align' parameter explicitly
> set to SMP_CACHE_BYTES and stop implicit alignment assignment in the
> memblock internal allocation functions.
>
> For the case when memblock APIs are used via helper functions, e.g. like
> iommu_arena_new_node() in Alpha, the helper functions were detected with
> Coccinelle's help and then manually examined and updated where appropriate.
>
> The direct memblock APIs users were updated using the semantic patch below:
>
> @@
> expression size, min_addr, max_addr, nid;
> @@
> (
> |
> - memblock_alloc_try_nid_raw(size, 0, min_addr, max_addr, nid)
> + memblock_alloc_try_nid_raw(size, SMP_CACHE_BYTES, min_addr, max_addr,
> nid)
> |
> - memblock_alloc_try_nid_nopanic(size, 0, min_addr, max_addr, nid)
> + memblock_alloc_try_nid_nopanic(size, SMP_CACHE_BYTES, min_addr, max_addr,
> nid)
> |
> - memblock_alloc_try_nid(size, 0, min_addr, max_addr, nid)
> + memblock_alloc_try_nid(size, SMP_CACHE_BYTES, min_addr, max_addr, nid)
> |
> - memblock_alloc(size, 0)
> + memblock_alloc(size, SMP_CACHE_BYTES)
> |
> - memblock_alloc_raw(size, 0)
> + memblock_alloc_raw(size, SMP_CACHE_BYTES)
> |
> - memblock_alloc_from(size, 0, min_addr)
> + memblock_alloc_from(size, SMP_CACHE_BYTES, min_addr)
> |
> - memblock_alloc_nopanic(size, 0)
> + memblock_alloc_nopanic(size, SMP_CACHE_BYTES)
> |
> - memblock_alloc_low(size, 0)
> + memblock_alloc_low(size, SMP_CACHE_BYTES)
> |
> - memblock_alloc_low_nopanic(size, 0)
> + memblock_alloc_low_nopanic(size, SMP_CACHE_BYTES)
> |
> - memblock_alloc_from_nopanic(size, 0, min_addr)
> + memblock_alloc_from_nopanic(size, SMP_CACHE_BYTES, min_addr)
> |
> - memblock_alloc_node(size, 0, nid)
> + memblock_alloc_node(size, SMP_CACHE_BYTES, nid)
> )
>
> Suggested-by: Michal Hocko <mhocko@suse.com>
> Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com>
I do agree that this is an improvement. I would also add WARN_ON_ONCE on
0 alignment to catch some left overs. If we ever grown a user which
would explicitly require the zero alignment (I would be surprised) then
we can remove the warning.
Acked-by: Michal Hocko <mhocko@suse.com>
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* Re: [PATCH 05.1/16] of:overlay: missing name, phandle, linux, phandle in new nodes
From: Frank Rowand @ 2018-10-10 6:49 UTC (permalink / raw)
To: Rob Herring, Pantelis Antoniou, Michael Ellerman,
Benjamin Herrenschmidt, Paul Mackerras, Alan Tull, Moritz Fischer
Cc: devicetree, linux-fpga, linuxppc-dev, linux-kernel
In-Reply-To: <1539151495-8110-1-git-send-email-frowand.list@gmail.com>
On 10/09/18 23:04, frowand.list@gmail.com wrote:
> From: Frank Rowand <frank.rowand@sony.com>
>
>
> "of: overlay: use prop add changeset entry for property in new nodes"
> fixed a problem where an 'update property' changeset entry was
> created for properties contained in nodes added by a changeset.
> The fix was to use an 'add property' changeset entry.
>
> This exposed more bugs in the apply overlay code. The properties
> 'name', 'phandle', and 'linux,phandle' were filtered out by
> add_changeset_property() as special properties. Change the filter
> to be only for existing nodes, not newly added nodes.
>
> The second bug is that the 'name' property does not exist in the
> newest FDT version, and has to be constructed from the node's
> full_name. Construct an 'add property' changeset entry for
> newly added nodes.
>
> Signed-off-by: Frank Rowand <frank.rowand@sony.com>
> ---
>
>
> Hi Alan,
>
> Thanks for reporting the problem with missing node names.
>
> I was able to replicate the problem, and have created this preliminary
> version of a patch to fix the problem.
>
> I have not extensively reviewed the patch yet, but would appreciate
> if you can confirm this fixes your problem.
>
> I created this patch as patch 17 of the series, but have also
> applied it as patch 05.1, immediately after patch 05/16, and
> built the kernel, booted, and verified name and phandle for
> one of the nodes in a unittest overlay for both cases. So
> minimal testing so far on my part.
>
> I have not verified whether the series builds and boots after
> each of patches 06..16 if this patch is applied as patch 05.1.
>
> There is definitely more work needed for me to complete this
> patch because it allocates some more memory, but does not yet
> free it when the overlay is released.
>
> -Frank
>
>
> drivers/of/overlay.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 67 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
> index 0b0904f44bc7..9746cea2aa91 100644
> --- a/drivers/of/overlay.c
> +++ b/drivers/of/overlay.c
> @@ -301,10 +301,11 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
> struct property *new_prop = NULL, *prop;
> int ret = 0;
>
> - if (!of_prop_cmp(overlay_prop->name, "name") ||
> - !of_prop_cmp(overlay_prop->name, "phandle") ||
> - !of_prop_cmp(overlay_prop->name, "linux,phandle"))
> - return 0;
> + if (target->in_livetree)
> + if (!of_prop_cmp(overlay_prop->name, "name") ||
> + !of_prop_cmp(overlay_prop->name, "phandle") ||
> + !of_prop_cmp(overlay_prop->name, "linux,phandle"))
> + return 0;
This is a big hammer patch.
Nobody should waste time reviewing this patch.
The following part should not be needed (though the above section might have
to become _slightly_ more complex).
-Frank
>
> if (target->in_livetree)
> prop = of_find_property(target->np, overlay_prop->name, NULL);
> @@ -443,10 +444,13 @@ static int build_changeset_next_level(struct overlay_changeset *ovcs,
> struct target *target, const struct device_node *overlay_node)
> {
> struct device_node *child;
> - struct property *prop;
> + struct property *prop, *name_prop;
> + bool has_name = false;
> int ret;
>
> for_each_property_of_node(overlay_node, prop) {
> + if (!strcmp(prop->name, "name"))
> + has_name = true;
> ret = add_changeset_property(ovcs, target, prop, 0);
> if (ret) {
> pr_debug("Failed to apply prop @%pOF/%s, err=%d\n",
> @@ -455,6 +459,57 @@ static int build_changeset_next_level(struct overlay_changeset *ovcs,
> }
> }
>
> + /*
> + * With FDT version 0x10 we may not have the name property,
> + * recreate it here from the unit name if absent
> + */
> +
> + if (!has_name) {
> + const char *p = target->np->full_name, *ps = p, *pa = NULL;
> + int len;
> +
> + /*
> + * zzz
> + * TODO: stash name_prop on a list in ovcs, to be freed
> + * after overlay removed
> + */
> +
> + while (*p) {
> + if ((*p) == '@')
> + pa = p;
> + else if ((*p) == '/')
> + ps = p + 1;
> + p++;
> + }
> +
> + if (pa < ps)
> + pa = p;
> + len = (pa - ps) + 1;
> +
> + name_prop = kmalloc(sizeof(*name_prop), GFP_KERNEL);
> + if (!name_prop)
> + return -ENOMEM;
> +
> + name_prop->name = kstrdup("name", GFP_KERNEL);
> + name_prop->value = kmalloc(len, GFP_KERNEL);
> + if (!name_prop->name || !name_prop->value) {
> + ret = -ENOMEM;
> + goto err_free_name_prop;
> + }
> +
> + memcpy(name_prop->value, ps, len - 1);
> + ((char *)name_prop->value)[len - 1] = 0;
> +
> + name_prop->length = strlen(name_prop->value) + 1;
> +
> + ret = add_changeset_property(ovcs, target, name_prop, 0);
> + if (ret) {
> + pr_debug("Failed to apply name_prop @%pOF/%s, err=%d\n",
> + target->np, name_prop->name, ret);
> + goto err_free_name_prop;
> + }
> + }
> +
> for_each_child_of_node(overlay_node, child) {
> ret = add_changeset_node(ovcs, target, child);
> if (ret) {
> @@ -466,6 +521,13 @@ static int build_changeset_next_level(struct overlay_changeset *ovcs,
> }
>
> return 0;
> +
> +err_free_name_prop:
> + kfree(name_prop->name);
> + kfree(name_prop->value);
> + kfree(name_prop);
> + return ret;
> +
> }
>
> /*
>
^ permalink raw reply
* Re: [PATCH v2] powerpc/perf: Quiet IMC PMU registration message
From: Stewart Smith @ 2018-10-10 6:43 UTC (permalink / raw)
To: Joel Stanley, Madhavan Srinivasan; +Cc: linuxppc-dev
In-Reply-To: <20181009062038.29695-1-joel@jms.id.au>
Joel Stanley <joel@jms.id.au> writes:
> On a Power9 box we get a few screens full of these on boot. Drop
> them to pr_debug.
>
> [ 5.993645] nest_centaur6_imc performance monitor hardware support registered
> [ 5.993728] nest_centaur7_imc performance monitor hardware support registered
> [ 5.996510] core_imc performance monitor hardware support registered
> [ 5.996569] nest_mba0_imc performance monitor hardware support registered
> [ 5.996631] nest_mba1_imc performance monitor hardware support registered
> [ 5.996685] nest_mba2_imc performance monitor hardware support registered
>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
Oh goodness yes.
Reviewed-by: Stewart Smith <stewart@linux.ibm.com>
--
Stewart Smith
OPAL Architect, IBM.
^ permalink raw reply
* [PATCH 2/2] powerpc/pseries: Add driver for PAPR SCM regions
From: Oliver O'Halloran @ 2018-10-10 6:08 UTC (permalink / raw)
To: linuxppc-dev; +Cc: nfont, Oliver O'Halloran, linux-nvdimm
In-Reply-To: <20181010060812.20068-1-oohall@gmail.com>
Adds a driver that implements support for enabling and accessing PAPR
SCM regions. Unfortunately due to how the PAPR interface works we can't
use the existing of_pmem driver (yet) because:
a) The guest is required to use the H_SCM_BIND_MEM h-call to add
add the SCM region to it's physical address space, and
b) There is currently no mechanism for relating a bare of_pmem region
to the backing DIMM (or not-a-DIMM for our case).
Both of these are easily handled by rolling the functionality into a
seperate driver so here we are...
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
The alternative implementation here is that we have the pseries code
do the h-calls and craft a pmem-region@<addr> node based on that.
However, that doesn't solve b) and mpe has expressed his dislike of
adding new stuff to the DT at runtime so i'd say that's a non-starter.
---
arch/powerpc/platforms/pseries/Kconfig | 7 +
arch/powerpc/platforms/pseries/Makefile | 1 +
arch/powerpc/platforms/pseries/papr_scm.c | 340 ++++++++++++++++++++++++++++++
3 files changed, 348 insertions(+)
create mode 100644 arch/powerpc/platforms/pseries/papr_scm.c
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 0c698fd6d491..4b0fcb80efe5 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -140,3 +140,10 @@ config IBMEBUS
bool "Support for GX bus based adapters"
help
Bus device driver for GX bus based adapters.
+
+config PAPR_SCM
+ depends on PPC_PSERIES && MEMORY_HOTPLUG
+ select LIBNVDIMM
+ tristate "Support for the PAPR Storage Class Memory interface"
+ help
+ Enable access to hypervisor provided storage class memory.
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 892b27ced973..a43ec843c8e2 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_IO_EVENT_IRQ) += io_event_irq.o
obj-$(CONFIG_LPARCFG) += lparcfg.o
obj-$(CONFIG_IBMVIO) += vio.o
obj-$(CONFIG_IBMEBUS) += ibmebus.o
+obj-$(CONFIG_PAPR_SCM) += papr_scm.o
ifdef CONFIG_PPC_PSERIES
obj-$(CONFIG_SUSPEND) += suspend.o
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
new file mode 100644
index 000000000000..87d4dbc18845
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/papr_scm.c
@@ -0,0 +1,340 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#define pr_fmt(fmt) "papr-scm: " fmt
+
+#include <linux/of.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/ndctl.h>
+#include <linux/libnvdimm.h>
+#include <linux/platform_device.h>
+
+#include <asm/plpar_wrappers.h>
+
+#define BIND_ANY_ADDR (~0ul)
+
+#define PAPR_SCM_DIMM_CMD_MASK \
+ ((1ul << ND_CMD_GET_CONFIG_SIZE) | \
+ (1ul << ND_CMD_GET_CONFIG_DATA) | \
+ (1ul << ND_CMD_SET_CONFIG_DATA))
+
+struct papr_scm_priv {
+ struct platform_device *pdev;
+ struct device_node *dn;
+ uint32_t drc_index;
+ uint64_t blocks;
+ uint64_t block_size;
+ int metadata_size;
+
+ uint64_t bound_addr;
+
+ struct nvdimm_bus_descriptor bus_desc;
+ struct nvdimm_bus *bus;
+ struct nvdimm *nvdimm;
+ struct resource res;
+ struct nd_region *region;
+ struct nd_interleave_set nd_set;
+};
+
+static int drc_pmem_bind(struct papr_scm_priv *p)
+{
+ unsigned long ret[PLPAR_HCALL_BUFSIZE];
+ uint64_t rc, token;
+
+ /*
+ * When the hypervisor cannot map all the requested memory in a single
+ * hcall it returns H_BUSY and we call again with the token until
+ * we get H_SUCCESS. Aborting the retry loop before getting H_SUCCESS
+ * leave the system in an undefined state, so we wait.
+ */
+ token = 0;
+
+ do {
+ rc = plpar_hcall(H_SCM_BIND_MEM, ret, p->drc_index, 0,
+ p->blocks, BIND_ANY_ADDR, token);
+ token = be64_to_cpu(ret[0]);
+ } while (rc == H_BUSY);
+
+ if (rc) {
+ dev_err(&p->pdev->dev, "bind err: %lld\n", rc);
+ return -ENXIO;
+ }
+
+ p->bound_addr = be64_to_cpu(ret[1]);
+
+ dev_dbg(&p->pdev->dev, "bound drc %x to %pR\n", p->drc_index, &p->res);
+
+ return 0;
+}
+
+static int drc_pmem_unbind(struct papr_scm_priv *p)
+{
+ unsigned long ret[PLPAR_HCALL_BUFSIZE];
+ uint64_t rc, token;
+
+ token = 0;
+
+ /* NB: unbind has the same retry requirements mentioned above */
+ do {
+ rc = plpar_hcall(H_SCM_UNBIND_MEM, ret, p->drc_index,
+ p->bound_addr, p->blocks, token);
+ token = be64_to_cpu(ret);
+ } while (rc == H_BUSY);
+
+ if (rc)
+ dev_err(&p->pdev->dev, "unbind error: %lld\n", rc);
+
+ return !!rc;
+}
+
+static int papr_scm_meta_get(struct papr_scm_priv *p,
+ struct nd_cmd_get_config_data_hdr *hdr)
+{
+ unsigned long data[PLPAR_HCALL_BUFSIZE];
+ int64_t ret;
+
+ if (hdr->in_offset >= p->metadata_size || hdr->in_length != 1)
+ return -EINVAL;
+
+ ret = plpar_hcall(H_SCM_READ_METADATA, data, p->drc_index,
+ hdr->in_offset, 1);
+
+ if (ret == H_PARAMETER) /* bad DRC index */
+ return -ENODEV;
+ if (ret)
+ return -EINVAL; /* other invalid parameter */
+
+ hdr->out_buf[0] = data[0] & 0xff;
+
+ return 0;
+}
+
+static int papr_scm_meta_set(struct papr_scm_priv *p,
+ struct nd_cmd_set_config_hdr *hdr)
+{
+ int64_t ret;
+
+ if (hdr->in_offset >= p->metadata_size || hdr->in_length != 1)
+ return -EINVAL;
+
+ ret = plpar_hcall_norets(H_SCM_WRITE_METADATA,
+ p->drc_index, hdr->in_offset, hdr->in_buf[0], 1);
+
+ if (ret == H_PARAMETER) /* bad DRC index */
+ return -ENODEV;
+ if (ret)
+ return -EINVAL; /* other invalid parameter */
+
+ return 0;
+}
+
+int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
+ unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc)
+{
+ struct nd_cmd_get_config_size *get_size_hdr;
+ struct papr_scm_priv *p;
+
+ /* Only dimm-specific calls are supported atm */
+ if (!nvdimm)
+ return -EINVAL;
+
+ p = nvdimm_provider_data(nvdimm);
+
+ switch (cmd) {
+ case ND_CMD_GET_CONFIG_SIZE:
+ get_size_hdr = buf;
+
+ get_size_hdr->status = 0;
+ get_size_hdr->max_xfer = 1;
+ get_size_hdr->config_size = p->metadata_size;
+ *cmd_rc = 0;
+ break;
+
+ case ND_CMD_GET_CONFIG_DATA:
+ *cmd_rc = papr_scm_meta_get(p, buf);
+ break;
+
+ case ND_CMD_SET_CONFIG_DATA:
+ *cmd_rc = papr_scm_meta_set(p, buf);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ dev_dbg(&p->pdev->dev, "returned with cmd_rc = %d\n", *cmd_rc);
+
+ return 0;
+}
+
+static const struct attribute_group *region_attr_groups[] = {
+ &nd_region_attribute_group,
+ &nd_device_attribute_group,
+ &nd_mapping_attribute_group,
+ &nd_numa_attribute_group,
+ NULL,
+};
+
+static const struct attribute_group *bus_attr_groups[] = {
+ &nvdimm_bus_attribute_group,
+ NULL,
+};
+
+static const struct attribute_group *papr_scm_dimm_groups[] = {
+ &nvdimm_attribute_group,
+ &nd_device_attribute_group,
+ NULL,
+};
+
+static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
+{
+ struct device *dev = &p->pdev->dev;
+ struct nd_mapping_desc mapping;
+ struct nd_region_desc ndr_desc;
+ unsigned long dimm_flags;
+
+ p->bus_desc.ndctl = papr_scm_ndctl;
+ p->bus_desc.module = THIS_MODULE;
+ p->bus_desc.of_node = p->pdev->dev.of_node;
+ p->bus_desc.attr_groups = bus_attr_groups;
+ p->bus_desc.provider_name = kstrdup(p->pdev->name, GFP_KERNEL);
+
+ if (!p->bus_desc.provider_name)
+ return -ENOMEM;
+
+ p->bus = nvdimm_bus_register(NULL, &p->bus_desc);
+ if (!p->bus) {
+ dev_err(dev, "Error creating nvdimm bus %pOF\n", p->dn);
+ return -ENXIO;
+ }
+
+ dimm_flags = 0;
+ set_bit(NDD_ALIASING, &dimm_flags);
+
+ p->nvdimm = nvdimm_create(p->bus, p, papr_scm_dimm_groups,
+ dimm_flags, PAPR_SCM_DIMM_CMD_MASK, 0, NULL);
+ if (!p->nvdimm) {
+ dev_err(dev, "Error creating DIMM object for %pOF\n", p->dn);
+ goto err;
+ }
+
+ /* now add the region */
+
+ memset(&mapping, 0, sizeof(mapping));
+ mapping.nvdimm = p->nvdimm;
+ mapping.start = p->res.start;
+ mapping.size = p->blocks * p->block_size; // XXX: potential overflow?
+
+ memset(&ndr_desc, 0, sizeof(ndr_desc));
+ ndr_desc.attr_groups = region_attr_groups;
+ ndr_desc.numa_node = dev_to_node(&p->pdev->dev);
+ ndr_desc.res = &p->res;
+ ndr_desc.of_node = p->dn;
+ ndr_desc.provider_data = p;
+ ndr_desc.mapping = &mapping;
+ ndr_desc.num_mappings = 1;
+ ndr_desc.nd_set = &p->nd_set;
+ set_bit(ND_REGION_PAGEMAP, &ndr_desc.flags);
+
+ p->region = nvdimm_pmem_region_create(p->bus, &ndr_desc);
+ if (!p->region) {
+ dev_err(dev, "Error registering region %pR from %pOF\n",
+ ndr_desc.res, p->dn);
+ goto err;
+ }
+
+ return 0;
+
+err: nvdimm_bus_unregister(p->bus);
+ kfree(p->bus_desc.provider_name);
+ return -ENXIO;
+}
+
+static int papr_scm_probe(struct platform_device *pdev)
+{
+ uint32_t drc_index, metadata_size, unit_cap[2];
+ struct device_node *dn = pdev->dev.of_node;
+ struct papr_scm_priv *p;
+ int rc;
+
+ /* check we have all the required DT properties */
+ if (of_property_read_u32(dn, "ibm,my-drc-index", &drc_index)) {
+ dev_err(&pdev->dev, "%pOF: missing drc-index!\n", dn);
+ return -ENODEV;
+ }
+
+ if (of_property_read_u32_array(dn, "ibm,unit-capacity", unit_cap, 2)) {
+ dev_err(&pdev->dev, "%pOF: missing unit-capacity!\n", dn);
+ return -ENODEV;
+ }
+
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+
+ /* optional DT properties */
+ of_property_read_u32(dn, "ibm,metadata-size", &metadata_size);
+
+ p->dn = dn;
+ p->drc_index = drc_index;
+ p->block_size = unit_cap[0];
+ p->blocks = unit_cap[1];
+
+ /* might be zero */
+ p->metadata_size = metadata_size;
+ p->pdev = pdev;
+
+ /* request the hypervisor to bind this region to somewhere in memory */
+ rc = drc_pmem_bind(p);
+ if (rc)
+ goto err;
+
+ /* setup the resource for the newly bound range */
+ p->res.start = p->bound_addr;
+ p->res.end = p->bound_addr + p->blocks * p->block_size;
+ p->res.name = pdev->name;
+ p->res.flags = IORESOURCE_MEM;
+
+ rc = papr_scm_nvdimm_init(p);
+ if (rc)
+ goto err2;
+
+ return 0;
+
+err2: drc_pmem_unbind(p);
+err: kfree(p);
+ return rc;
+}
+
+static int papr_scm_remove(struct platform_device *pdev)
+{
+ struct papr_scm_priv *p = platform_get_drvdata(pdev);
+
+ nvdimm_bus_unregister(p->bus);
+ drc_pmem_unbind(p);
+ kfree(p);
+
+ return 0;
+}
+
+static const struct of_device_id papr_scm_match[] = {
+ { .compatible = "ibm,pmemory" },
+ { },
+};
+
+static struct platform_driver papr_scm_driver = {
+ .probe = papr_scm_probe,
+ .remove = papr_scm_remove,
+ .driver = {
+ .name = "papr_scm",
+ .owner = THIS_MODULE,
+ .of_match_table = papr_scm_match,
+ },
+};
+
+module_platform_driver(papr_scm_driver);
+MODULE_DEVICE_TABLE(of, papr_scm_match);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("IBM Corporation");
--
2.9.5
^ permalink raw reply related
* [PATCH 1/2] powerpc/pseries: PAPR persistent memory support
From: Oliver O'Halloran @ 2018-10-10 6:08 UTC (permalink / raw)
To: linuxppc-dev; +Cc: nfont, Oliver O'Halloran, linux-nvdimm
In-Reply-To: <20181010060812.20068-1-oohall@gmail.com>
This patch implements support for discovering storage class memory
devices at boot and for handling hotplug of new regions via RTAS
hotplug events.
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
arch/powerpc/include/asm/firmware.h | 3 ++-
arch/powerpc/include/asm/hvcall.h | 10 +++++++++-
arch/powerpc/include/asm/rtas.h | 2 ++
arch/powerpc/kernel/rtasd.c | 2 ++
arch/powerpc/platforms/pseries/Makefile | 2 +-
arch/powerpc/platforms/pseries/dlpar.c | 4 ++++
arch/powerpc/platforms/pseries/firmware.c | 1 +
arch/powerpc/platforms/pseries/pseries.h | 5 +++++
arch/powerpc/platforms/pseries/ras.c | 3 ++-
9 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h
index 7a051bd21f87..113c64d5d394 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -52,6 +52,7 @@
#define FW_FEATURE_PRRN ASM_CONST(0x0000000200000000)
#define FW_FEATURE_DRMEM_V2 ASM_CONST(0x0000000400000000)
#define FW_FEATURE_DRC_INFO ASM_CONST(0x0000000800000000)
+#define FW_FEATURE_PAPR_SCM ASM_CONST(0x0000001000000000)
#ifndef __ASSEMBLY__
@@ -69,7 +70,7 @@ enum {
FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY |
FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN |
FW_FEATURE_HPT_RESIZE | FW_FEATURE_DRMEM_V2 |
- FW_FEATURE_DRC_INFO,
+ FW_FEATURE_DRC_INFO | FW_FEATURE_PAPR_SCM,
FW_FEATURE_PSERIES_ALWAYS = 0,
FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL,
FW_FEATURE_POWERNV_ALWAYS = 0,
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index a0b17f9f1ea4..0e81ef83b35a 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -295,7 +295,15 @@
#define H_INT_ESB 0x3C8
#define H_INT_SYNC 0x3CC
#define H_INT_RESET 0x3D0
-#define MAX_HCALL_OPCODE H_INT_RESET
+#define H_SCM_READ_METADATA 0x3E4
+#define H_SCM_WRITE_METADATA 0x3E8
+#define H_SCM_BIND_MEM 0x3EC
+#define H_SCM_UNBIND_MEM 0x3F0
+#define H_SCM_QUERY_BLOCK_MEM_BINDING 0x3F4
+#define H_SCM_QUERY_LOGICAL_MEM_BINDING 0x3F8
+#define H_SCM_MEM_QUERY 0x3FC
+#define H_SCM_BLOCK_CLEAR 0x400
+#define MAX_HCALL_OPCODE H_SCM_BLOCK_CLEAR
/* H_VIOCTL functions */
#define H_GET_VIOA_DUMP_SIZE 0x01
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 71e393c46a49..1e81f3d55457 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -125,6 +125,7 @@ struct rtas_suspend_me_data {
#define RTAS_TYPE_INFO 0xE2
#define RTAS_TYPE_DEALLOC 0xE3
#define RTAS_TYPE_DUMP 0xE4
+#define RTAS_TYPE_HOTPLUG 0xE5
/* I don't add PowerMGM events right now, this is a different topic */
#define RTAS_TYPE_PMGM_POWER_SW_ON 0x60
#define RTAS_TYPE_PMGM_POWER_SW_OFF 0x61
@@ -316,6 +317,7 @@ struct pseries_hp_errorlog {
#define PSERIES_HP_ELOG_RESOURCE_MEM 2
#define PSERIES_HP_ELOG_RESOURCE_SLOT 3
#define PSERIES_HP_ELOG_RESOURCE_PHB 4
+#define PSERIES_HP_ELOG_RESOURCE_PMEM 6
#define PSERIES_HP_ELOG_ACTION_ADD 1
#define PSERIES_HP_ELOG_ACTION_REMOVE 2
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 6fafc82c04b0..fad0baddfcba 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -91,6 +91,8 @@ static char *rtas_event_type(int type)
return "Dump Notification Event";
case RTAS_TYPE_PRRN:
return "Platform Resource Reassignment Event";
+ case RTAS_TYPE_HOTPLUG:
+ return "Hotplug Event";
}
return rtas_type[0];
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 7e89d5c47068..892b27ced973 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_KEXEC_CORE) += kexec.o
obj-$(CONFIG_PSERIES_ENERGY) += pseries_energy.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o
-obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o
+obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o pmem.o
obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
obj-$(CONFIG_HVCS) += hvcserver.o
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index a0b20c03f078..795996fefdb9 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -357,6 +357,10 @@ static int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog)
case PSERIES_HP_ELOG_RESOURCE_CPU:
rc = dlpar_cpu(hp_elog);
break;
+ case PSERIES_HP_ELOG_RESOURCE_PMEM:
+ rc = dlpar_hp_pmem(hp_elog);
+ break;
+
default:
pr_warn_ratelimited("Invalid resource (%d) specified\n",
hp_elog->resource);
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index a3bbeb43689e..4927de57d8ee 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -65,6 +65,7 @@ hypertas_fw_features_table[] = {
{FW_FEATURE_SET_MODE, "hcall-set-mode"},
{FW_FEATURE_BEST_ENERGY, "hcall-best-energy-1*"},
{FW_FEATURE_HPT_RESIZE, "hcall-hpt-resize"},
+ {FW_FEATURE_PAPR_SCM, "hcall-scm"},
};
/* Build up the firmware features bitmask using the contents of
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 60db2ee511fb..d0829677c896 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -63,11 +63,16 @@ void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog,
struct completion *hotplug_done, int *rc);
#ifdef CONFIG_MEMORY_HOTPLUG
int dlpar_memory(struct pseries_hp_errorlog *hp_elog);
+int dlpar_hp_pmem(struct pseries_hp_errorlog *hp_elog);
#else
static inline int dlpar_memory(struct pseries_hp_errorlog *hp_elog)
{
return -EOPNOTSUPP;
}
+int dlpar_hp_pmem(struct pseries_hp_errorlog *hp_elog)
+{
+ return -EOPNOTSUPP;
+};
#endif
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 851ce326874a..ae22fc007276 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -237,7 +237,8 @@ static irqreturn_t ras_hotplug_interrupt(int irq, void *dev_id)
* hotplug events on the ras_log_buf to be handled by rtas_errd.
*/
if (hp_elog->resource == PSERIES_HP_ELOG_RESOURCE_MEM ||
- hp_elog->resource == PSERIES_HP_ELOG_RESOURCE_CPU)
+ hp_elog->resource == PSERIES_HP_ELOG_RESOURCE_CPU ||
+ hp_elog->resource == PSERIES_HP_ELOG_RESOURCE_PMEM)
queue_hotplug_event(hp_elog, NULL, NULL);
else
log_error(ras_log_buf, ERR_TYPE_RTAS_LOG, 0);
--
2.9.5
^ permalink raw reply related
* PAPR SCM support
From: Oliver O'Halloran @ 2018-10-10 6:08 UTC (permalink / raw)
To: linuxppc-dev; +Cc: nfont, linux-nvdimm
This series adds support for the para-virtualised storage class memory
interface defined by the Power Architecture Platform Reference.
Patch 1 implements the pseries device discovery (via DT) and hotplug
support (via RTAS hotplug interrupt).
Patch 2 implements a driver that binds to the platform devices, does the
necessary H-calls to activate the region and configures the libnvdimm
interface. It also adds an NDCTL implementation to allow the "metadata"
space associated with an SCM region to be used as label space.
This should go in via the ppc tree, but an ack from Dan for patch two
would be appreciated.
^ permalink raw reply
* [PATCH 05.1/16] of:overlay: missing name, phandle, linux, phandle in new nodes
From: frowand.list @ 2018-10-10 6:04 UTC (permalink / raw)
To: Rob Herring, Pantelis Antoniou, Michael Ellerman,
Benjamin Herrenschmidt, Paul Mackerras, Alan Tull, Moritz Fischer
Cc: devicetree, linux-fpga, linuxppc-dev, linux-kernel
In-Reply-To: <CANk1AXQScT_b1_UOiVuWNcB=LiA3gvvZrw53H1XVSCNqsGPqtA@mail.gmail.com>
From: Frank Rowand <frank.rowand@sony.com>
"of: overlay: use prop add changeset entry for property in new nodes"
fixed a problem where an 'update property' changeset entry was
created for properties contained in nodes added by a changeset.
The fix was to use an 'add property' changeset entry.
This exposed more bugs in the apply overlay code. The properties
'name', 'phandle', and 'linux,phandle' were filtered out by
add_changeset_property() as special properties. Change the filter
to be only for existing nodes, not newly added nodes.
The second bug is that the 'name' property does not exist in the
newest FDT version, and has to be constructed from the node's
full_name. Construct an 'add property' changeset entry for
newly added nodes.
Signed-off-by: Frank Rowand <frank.rowand@sony.com>
---
Hi Alan,
Thanks for reporting the problem with missing node names.
I was able to replicate the problem, and have created this preliminary
version of a patch to fix the problem.
I have not extensively reviewed the patch yet, but would appreciate
if you can confirm this fixes your problem.
I created this patch as patch 17 of the series, but have also
applied it as patch 05.1, immediately after patch 05/16, and
built the kernel, booted, and verified name and phandle for
one of the nodes in a unittest overlay for both cases. So
minimal testing so far on my part.
I have not verified whether the series builds and boots after
each of patches 06..16 if this patch is applied as patch 05.1.
There is definitely more work needed for me to complete this
patch because it allocates some more memory, but does not yet
free it when the overlay is released.
-Frank
drivers/of/overlay.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 67 insertions(+), 5 deletions(-)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 0b0904f44bc7..9746cea2aa91 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -301,10 +301,11 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
struct property *new_prop = NULL, *prop;
int ret = 0;
- if (!of_prop_cmp(overlay_prop->name, "name") ||
- !of_prop_cmp(overlay_prop->name, "phandle") ||
- !of_prop_cmp(overlay_prop->name, "linux,phandle"))
- return 0;
+ if (target->in_livetree)
+ if (!of_prop_cmp(overlay_prop->name, "name") ||
+ !of_prop_cmp(overlay_prop->name, "phandle") ||
+ !of_prop_cmp(overlay_prop->name, "linux,phandle"))
+ return 0;
if (target->in_livetree)
prop = of_find_property(target->np, overlay_prop->name, NULL);
@@ -443,10 +444,13 @@ static int build_changeset_next_level(struct overlay_changeset *ovcs,
struct target *target, const struct device_node *overlay_node)
{
struct device_node *child;
- struct property *prop;
+ struct property *prop, *name_prop;
+ bool has_name = false;
int ret;
for_each_property_of_node(overlay_node, prop) {
+ if (!strcmp(prop->name, "name"))
+ has_name = true;
ret = add_changeset_property(ovcs, target, prop, 0);
if (ret) {
pr_debug("Failed to apply prop @%pOF/%s, err=%d\n",
@@ -455,6 +459,57 @@ static int build_changeset_next_level(struct overlay_changeset *ovcs,
}
}
+ /*
+ * With FDT version 0x10 we may not have the name property,
+ * recreate it here from the unit name if absent
+ */
+
+ if (!has_name) {
+ const char *p = target->np->full_name, *ps = p, *pa = NULL;
+ int len;
+
+ /*
+ * zzz
+ * TODO: stash name_prop on a list in ovcs, to be freed
+ * after overlay removed
+ */
+
+ while (*p) {
+ if ((*p) == '@')
+ pa = p;
+ else if ((*p) == '/')
+ ps = p + 1;
+ p++;
+ }
+
+ if (pa < ps)
+ pa = p;
+ len = (pa - ps) + 1;
+
+ name_prop = kmalloc(sizeof(*name_prop), GFP_KERNEL);
+ if (!name_prop)
+ return -ENOMEM;
+
+ name_prop->name = kstrdup("name", GFP_KERNEL);
+ name_prop->value = kmalloc(len, GFP_KERNEL);
+ if (!name_prop->name || !name_prop->value) {
+ ret = -ENOMEM;
+ goto err_free_name_prop;
+ }
+
+ memcpy(name_prop->value, ps, len - 1);
+ ((char *)name_prop->value)[len - 1] = 0;
+
+ name_prop->length = strlen(name_prop->value) + 1;
+
+ ret = add_changeset_property(ovcs, target, name_prop, 0);
+ if (ret) {
+ pr_debug("Failed to apply name_prop @%pOF/%s, err=%d\n",
+ target->np, name_prop->name, ret);
+ goto err_free_name_prop;
+ }
+ }
+
for_each_child_of_node(overlay_node, child) {
ret = add_changeset_node(ovcs, target, child);
if (ret) {
@@ -466,6 +521,13 @@ static int build_changeset_next_level(struct overlay_changeset *ovcs,
}
return 0;
+
+err_free_name_prop:
+ kfree(name_prop->name);
+ kfree(name_prop->value);
+ kfree(name_prop);
+ return ret;
+
}
/*
--
Frank Rowand <frank.rowand@sony.com>
^ permalink raw reply related
* Re: [PATCH] powerpc/rtasd: Improve unknown error logging
From: Vasant Hegde @ 2018-10-10 5:49 UTC (permalink / raw)
To: Oliver O'Halloran, linuxppc-dev
In-Reply-To: <20181010052302.18094-1-oohall@gmail.com>
On 10/10/2018 10:53 AM, Oliver O'Halloran wrote:
> Currently when we get an unknown RTAS event it prints the type as
> "Unknown" and no other useful information. Add the raw type code to the
> log message so that we have something to work off.
Yeah. Useful one.
Reviewed-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
-Vasant
>
> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
> ---
> arch/powerpc/kernel/rtasd.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
> index 44d66c33d59d..6fafc82c04b0 100644
> --- a/arch/powerpc/kernel/rtasd.c
> +++ b/arch/powerpc/kernel/rtasd.c
> @@ -150,8 +150,10 @@ static void printk_log_rtas(char *buf, int len)
> } else {
> struct rtas_error_log *errlog = (struct rtas_error_log *)buf;
>
> - printk(RTAS_DEBUG "event: %d, Type: %s, Severity: %d\n",
> - error_log_cnt, rtas_event_type(rtas_error_type(errlog)),
> + printk(RTAS_DEBUG "event: %d, Type: %s (%d), Severity: %d\n",
> + error_log_cnt,
> + rtas_event_type(rtas_error_type(errlog)),
> + rtas_error_type(errlog),
> rtas_error_severity(errlog));
> }
> }
>
^ permalink raw reply
* Re: [PATCH] powerpc/topology: Update numa mask when cpu node mapping changes
From: Srikar Dronamraju @ 2018-10-10 5:37 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Michael Bringmann
In-Reply-To: <1539145486-10250-1-git-send-email-srikar@linux.vnet.ibm.com>
* Srikar Dronamraju <srikar@linux.vnet.ibm.com> [2018-10-10 09:54:46]:
> Commit 2ea626306810 ("powerpc/topology: Get topology for shared
> processors at boot") will update the cpu node topology for shared lpars
> on PowerVM.
>
> However shared lpars on PowerVM also support VPHN and PRRN events.
> On receiving a VPHN, PRRN events, cpu to node mapping might change.
>
> Scheduler maintains sched_domains_numa_masks[], which is currently not
> updated on cpu to node mapping changes. This can lead to machine
> regressions and performance regressions.
s/regressions and performance regressions./hangs or performance hit./
>
> Fix numa_update_cpu_topology() to update sched_domains_numa_masks[].
>
--
Thanks and Regards
Srikar Dronamraju
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox