* [PATCH 0/2] powerpc/pseries: Perform PRRN topology updates in kernel @ 2016-12-12 21:01 John Allen 2016-12-12 21:05 ` [PATCH 1/2] powerpc/pseries: Introduce memory hotplug READD operation John Allen 2016-12-12 21:07 ` [PATCH 2/2] powerpc/pseries: Update affinity for memory and cpus specified in a PRRN event John Allen 0 siblings, 2 replies; 4+ messages in thread From: John Allen @ 2016-12-12 21:01 UTC (permalink / raw) To: linuxppc-dev, Nathan Fontenot Formerly, when we received a PRRN rtas event, device tree updating was performed in the kernel and the actual topology updating was performed in userspace. This was necessary as in order to update the topology for memory, we must perform a hot remove and a subsequent hot add and until recently, memory hotplug was not included in the kernel. Since memory hotplug is now available, this patchset moves the PRRN topology updating into the kernel. John Allen (2): powerpc/pseries: Introduce memory hotplug READD operation powerpc/pseries: Update affinity for memory and cpus specified in a PRRN event arch/powerpc/include/asm/rtas.h | 1 arch/powerpc/kernel/rtasd.c | 7 +++ arch/powerpc/platforms/pseries/hotplug-memory.c | 5 ++ arch/powerpc/platforms/pseries/mobility.c | 48 +++++++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] powerpc/pseries: Introduce memory hotplug READD operation 2016-12-12 21:01 [PATCH 0/2] powerpc/pseries: Perform PRRN topology updates in kernel John Allen @ 2016-12-12 21:05 ` John Allen 2016-12-12 21:07 ` [PATCH 2/2] powerpc/pseries: Update affinity for memory and cpus specified in a PRRN event John Allen 1 sibling, 0 replies; 4+ messages in thread From: John Allen @ 2016-12-12 21:05 UTC (permalink / raw) To: linuxppc-dev, Nathan Fontenot Currently, memory must be hot removed and subsequently re-added in order to dynamically update the affinity of LMBs specified by a PRRN event. Earlier implementations of the PRRN event handler ran into issues in which the hot remove would occur successfully, but a hotplug event would be initiated from another source and grab the hotplug lock preventing the hot add from occurring. To prevent this situation, this patch introduces the notion of a hot "readd" action for memory which atomizes a hot remove and a hot add into a single, serialized operation on the hotplug queue. Signed-off-by: John Allen <jallen@linux.vnet.ibm.com> --- diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index 9c23baa..076b892 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h @@ -318,6 +318,7 @@ struct pseries_hp_errorlog { #define PSERIES_HP_ELOG_ACTION_ADD 1 #define PSERIES_HP_ELOG_ACTION_REMOVE 2 +#define PSERIES_HP_ELOG_ACTION_READD 3 #define PSERIES_HP_ELOG_ID_DRC_NAME 1 #define PSERIES_HP_ELOG_ID_DRC_INDEX 2 diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 76ec104..291d49b 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -766,6 +766,11 @@ int dlpar_memory(struct pseries_hp_errorlog *hp_elog) else rc = -EINVAL; break; + case PSERIES_HP_ELOG_ACTION_READD: + rc = dlpar_memory_remove_by_index(drc_index, prop); + if (!rc) + dlpar_memory_add_by_index(drc_index, prop); + break; default: pr_err("Invalid action (%d) specified\n", hp_elog->action); rc = -EINVAL; ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] powerpc/pseries: Update affinity for memory and cpus specified in a PRRN event 2016-12-12 21:01 [PATCH 0/2] powerpc/pseries: Perform PRRN topology updates in kernel John Allen 2016-12-12 21:05 ` [PATCH 1/2] powerpc/pseries: Introduce memory hotplug READD operation John Allen @ 2016-12-12 21:07 ` John Allen 2016-12-13 16:58 ` Nathan Fontenot 1 sibling, 1 reply; 4+ messages in thread From: John Allen @ 2016-12-12 21:07 UTC (permalink / raw) To: linuxppc-dev, Nathan Fontenot Extend the existing PRRN infrastructure to perform the actual affinity updating for cpus and memory in addition to the device tree updating. For cpus, dynamic affinity updating already appears to exist in the kernel in the form of arch_update_cpu_topology. For memory, we must place a READD operation on the hotplug queue for any phandle included in the PRRN event that is determined to be an LMB. Signed-off-by: John Allen <jallen@linux.vnet.ibm.com> --- diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index a26a020..8836130 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c @@ -21,6 +21,7 @@ #include <linux/cpu.h> #include <linux/workqueue.h> #include <linux/slab.h> +#include <linux/topology.h> #include <asm/uaccess.h> #include <asm/io.h> @@ -282,6 +283,7 @@ static void prrn_work_fn(struct work_struct *work) * the RTAS event. */ pseries_devicetree_update(-prrn_update_scope); + arch_update_cpu_topology(); } static DECLARE_WORK(prrn_work, prrn_work_fn); @@ -434,7 +436,10 @@ static void do_event_scan(void) } if (error == 0) { - pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0); + if (rtas_error_type((struct rtas_error_log *)logdata) != + RTAS_TYPE_PRRN) + pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, + 0); handle_rtas_event((struct rtas_error_log *)logdata); } diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index a560a98..e2ed2d6 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -39,6 +39,7 @@ struct update_props_workarea { #define ADD_DT_NODE 0x03000000 #define MIGRATION_SCOPE (1) +#define PRRN_SCOPE -2 static int mobility_rtas_call(int token, char *buf, s32 scope) { @@ -236,6 +237,49 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index) return rc; } +void pseries_prrn_update_node(__be32 phandle) +{ + struct pseries_hp_errorlog *hp_elog; + struct completion hotplug_done; + struct device_node *dn; + char *type; + int rc = 0; + + hp_elog = kzalloc(sizeof(*hp_elog), GFP_KERNEL); + if (!hp_elog) + return; + + dn = of_find_node_by_phandle(be32_to_cpu(phandle)); + + /* + * If the phandle was not found, assume phandle is the drc index of + * an LMB. + */ + if (!dn) { + type = "memory"; + hp_elog->resource = PSERIES_HP_ELOG_RESOURCE_MEM; + hp_elog->action = PSERIES_HP_ELOG_ACTION_READD; + hp_elog->id_type = PSERIES_HP_ELOG_ID_DRC_INDEX; + hp_elog->_drc_u.drc_index = cpu_to_be32(phandle); + + pr_info("Attempting to update %s at drc index %x\n", type, + hp_elog->_drc_u.drc_index); + + init_completion(&hotplug_done); + queue_hotplug_event(hp_elog, &hotplug_done, &rc); + wait_for_completion(&hotplug_done); + + if (rc) + pr_info("Failed to update %s at drc index %x\n", type, + hp_elog->_drc_u.drc_index); + else + pr_info("Updated %s at drc index %x\n", type, + hp_elog->_drc_u.drc_index); + } + + kfree(hp_elog); +} + int pseries_devicetree_update(s32 scope) { char *rtas_buf; @@ -274,6 +318,10 @@ int pseries_devicetree_update(s32 scope) break; case UPDATE_DT_NODE: update_dt_node(phandle, scope); + + if (scope == PRRN_SCOPE) + pseries_prrn_update_node(phandle); + break; case ADD_DT_NODE: drc_index = *data++; ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2] powerpc/pseries: Update affinity for memory and cpus specified in a PRRN event 2016-12-12 21:07 ` [PATCH 2/2] powerpc/pseries: Update affinity for memory and cpus specified in a PRRN event John Allen @ 2016-12-13 16:58 ` Nathan Fontenot 0 siblings, 0 replies; 4+ messages in thread From: Nathan Fontenot @ 2016-12-13 16:58 UTC (permalink / raw) To: John Allen, linuxppc-dev On 12/12/2016 03:07 PM, John Allen wrote: > Extend the existing PRRN infrastructure to perform the actual affinity > updating for cpus and memory in addition to the device tree updating. For > cpus, dynamic affinity updating already appears to exist in the kernel in > the form of arch_update_cpu_topology. For memory, we must place a READD > operation on the hotplug queue for any phandle included in the PRRN event > that is determined to be an LMB. > > Signed-off-by: John Allen <jallen@linux.vnet.ibm.com> > --- > diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c > index a26a020..8836130 100644 > --- a/arch/powerpc/kernel/rtasd.c > +++ b/arch/powerpc/kernel/rtasd.c > @@ -21,6 +21,7 @@ > #include <linux/cpu.h> > #include <linux/workqueue.h> > #include <linux/slab.h> > +#include <linux/topology.h> > > #include <asm/uaccess.h> > #include <asm/io.h> > @@ -282,6 +283,7 @@ static void prrn_work_fn(struct work_struct *work) > * the RTAS event. > */ > pseries_devicetree_update(-prrn_update_scope); > + arch_update_cpu_topology(); > } > > static DECLARE_WORK(prrn_work, prrn_work_fn); > @@ -434,7 +436,10 @@ static void do_event_scan(void) > } > > if (error == 0) { > - pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0); > + if (rtas_error_type((struct rtas_error_log *)logdata) != > + RTAS_TYPE_PRRN) > + pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, > + 0); > handle_rtas_event((struct rtas_error_log *)logdata); > } > > diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c > index a560a98..e2ed2d6 100644 > --- a/arch/powerpc/platforms/pseries/mobility.c > +++ b/arch/powerpc/platforms/pseries/mobility.c > @@ -39,6 +39,7 @@ struct update_props_workarea { > #define ADD_DT_NODE 0x03000000 > > #define MIGRATION_SCOPE (1) > +#define PRRN_SCOPE -2 > > static int mobility_rtas_call(int token, char *buf, s32 scope) > { > @@ -236,6 +237,49 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index) > return rc; > } > > +void pseries_prrn_update_node(__be32 phandle) > +{ > + struct pseries_hp_errorlog *hp_elog; > + struct completion hotplug_done; > + struct device_node *dn; > + char *type; > + int rc = 0; > + > + hp_elog = kzalloc(sizeof(*hp_elog), GFP_KERNEL); Doing memory hotplug by index results in the struct pseries_hp_elog only being about 64 bits. Since we are adding each action to the queue and waiting for its completion do we need to allocate the struct. Seems like we could just have a local pseries_hp_elog. > + if (!hp_elog) > + return; > + > + dn = of_find_node_by_phandle(be32_to_cpu(phandle)); > + > + /* > + * If the phandle was not found, assume phandle is the drc index of > + * an LMB. > + */ > + if (!dn) { > + type = "memory"; > + hp_elog->resource = PSERIES_HP_ELOG_RESOURCE_MEM; > + hp_elog->action = PSERIES_HP_ELOG_ACTION_READD; > + hp_elog->id_type = PSERIES_HP_ELOG_ID_DRC_INDEX; > + hp_elog->_drc_u.drc_index = cpu_to_be32(phandle); Isn't the phandle already in BE format? -Nathan > + > + pr_info("Attempting to update %s at drc index %x\n", type, > + hp_elog->_drc_u.drc_index); > + > + init_completion(&hotplug_done); > + queue_hotplug_event(hp_elog, &hotplug_done, &rc); > + wait_for_completion(&hotplug_done); > + > + if (rc) > + pr_info("Failed to update %s at drc index %x\n", type, > + hp_elog->_drc_u.drc_index); > + else > + pr_info("Updated %s at drc index %x\n", type, > + hp_elog->_drc_u.drc_index); > + } > + > + kfree(hp_elog); > +} > + > int pseries_devicetree_update(s32 scope) > { > char *rtas_buf; > @@ -274,6 +318,10 @@ int pseries_devicetree_update(s32 scope) > break; > case UPDATE_DT_NODE: > update_dt_node(phandle, scope); > + > + if (scope == PRRN_SCOPE) > + pseries_prrn_update_node(phandle); > + > break; > case ADD_DT_NODE: > drc_index = *data++; > ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-12-13 16:58 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-12-12 21:01 [PATCH 0/2] powerpc/pseries: Perform PRRN topology updates in kernel John Allen 2016-12-12 21:05 ` [PATCH 1/2] powerpc/pseries: Introduce memory hotplug READD operation John Allen 2016-12-12 21:07 ` [PATCH 2/2] powerpc/pseries: Update affinity for memory and cpus specified in a PRRN event John Allen 2016-12-13 16:58 ` Nathan Fontenot
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).