[RFC v9 2/4] hotplug/cpu: Add operation queuing function
From: Michael Bringmann <hidden>
Date: 2018-06-03 20:04:37
Subsystem:
linux for powerpc (32-bit and 64-bit), the rest · Maintainers:
Madhavan Srinivasan, Linus Torvalds
[Testing delayed due to internal SAN problems.]
migration/dlpar: This patch adds function dlpar_queue_action()
which will add information about a CPU/Memory 'readd' operation
according to resource type, action code, and DRC index. Initial
usage is for the 'readd' CPU and Memory blocks identified as
having changed their associativity during a migration event.
Signed-off-by: Michael Bringmann <redacted>
---
Changes in RFC:
-- Correct drc_index for dlpar_queue_action worker invocation
-- Correct text of notice
-- Revise queuing model to save up all of the DLPAR actions for
later execution.
---
arch/powerpc/platforms/pseries/dlpar.c | 51 ++++++++++++++++++++++++++++++
arch/powerpc/platforms/pseries/pseries.h | 2 +
2 files changed, 53 insertions(+)
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index a0b20c0..a1300d2 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c@@ -407,6 +407,57 @@ void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog, } } +struct DlparWork { + struct list_head list; + int resource; + int action; + u32 drc_index; +} DlparWorkQ; + +int dlpar_delayed_queue_action(int resource, int action, u32 drc_index) +{ + struct DlparWork *dwq; + + dwq = kmalloc(sizeof(struct DlparWork), GFP_KERNEL); + if (!dwq) + return -ENOMEM; + + dwq->resource = resource; + dwq->action = action; + dwq->drc_index = drc_index; + + list_add_tail(&dwq->list, &DlparWorkQ.list); + + return 0; +} + +int dlpar_schedule_delayed_queue(void) +{ + struct DlparWork *iter; + struct list_head *pos, *q; + + list_for_each_entry(iter, &DlparWorkQ.list, list) { + struct pseries_hp_errorlog hp_elog; + + hp_elog.resource = iter->resource; + hp_elog.action = iter->action; + hp_elog.id_type = PSERIES_HP_ELOG_ID_DRC_INDEX; + hp_elog._drc_u.drc_index = cpu_to_be32(iter->drc_index); + + handle_dlpar_errorlog(&hp_elog); + } + + list_for_each_safe(pos, q, &DlparWorkQ.list) { + struct DlparWork *tmp; + + tmp = list_entry(pos, struct DlparWork, list); + list_del(pos); + kfree(tmp); + } + + return 0; +} + static int dlpar_parse_resource(char **cmd, struct pseries_hp_errorlog *hp_elog) { char *arg;
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 60db2ee..de73fda 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h@@ -61,6 +61,8 @@ extern struct device_node *dlpar_configure_connector(__be32, void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog, struct completion *hotplug_done, int *rc); +int dlpar_delayed_queue_action(int resource, int action, u32 drc_index); +int dlpar_schedule_delayed_queue(void); #ifdef CONFIG_MEMORY_HOTPLUG int dlpar_memory(struct pseries_hp_errorlog *hp_elog); #else