Commit fd12527a authored by Nathan Fontenot's avatar Nathan Fontenot Committed by Michael Ellerman

powerpc/pseries: Remove unneeded uses of dlpar work queue

There are three instances in which dlpar hotplug events are invoked;
handling a hotplug interrupt (in a kvm guest), handling a dlpar
request through sysfs, and updating LMB affinity when handling a
PRRN event. Only in the case of handling a hotplug interrupt do we
have to put the work on a workqueue, the other cases can handle the
dlpar request directly.

This patch exports the handle_dlpar_errorlog() function so that
dlpar hotplug events can be handled directly and updates the two
instances mentioned above to use the direct invocation.
Signed-off-by: default avatarNathan Fontenot <nfont@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent cd24e457
...@@ -32,8 +32,6 @@ static struct workqueue_struct *pseries_hp_wq; ...@@ -32,8 +32,6 @@ static struct workqueue_struct *pseries_hp_wq;
struct pseries_hp_work { struct pseries_hp_work {
struct work_struct work; struct work_struct work;
struct pseries_hp_errorlog *errlog; struct pseries_hp_errorlog *errlog;
struct completion *hp_completion;
int *rc;
}; };
struct cc_workarea { struct cc_workarea {
...@@ -329,7 +327,7 @@ int dlpar_release_drc(u32 drc_index) ...@@ -329,7 +327,7 @@ int dlpar_release_drc(u32 drc_index)
return 0; return 0;
} }
static int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog) int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog)
{ {
int rc; int rc;
...@@ -371,20 +369,13 @@ static void pseries_hp_work_fn(struct work_struct *work) ...@@ -371,20 +369,13 @@ static void pseries_hp_work_fn(struct work_struct *work)
struct pseries_hp_work *hp_work = struct pseries_hp_work *hp_work =
container_of(work, struct pseries_hp_work, work); container_of(work, struct pseries_hp_work, work);
if (hp_work->rc) handle_dlpar_errorlog(hp_work->errlog);
*(hp_work->rc) = handle_dlpar_errorlog(hp_work->errlog);
else
handle_dlpar_errorlog(hp_work->errlog);
if (hp_work->hp_completion)
complete(hp_work->hp_completion);
kfree(hp_work->errlog); kfree(hp_work->errlog);
kfree((void *)work); kfree((void *)work);
} }
void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog, void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog)
struct completion *hotplug_done, int *rc)
{ {
struct pseries_hp_work *work; struct pseries_hp_work *work;
struct pseries_hp_errorlog *hp_errlog_copy; struct pseries_hp_errorlog *hp_errlog_copy;
...@@ -397,13 +388,9 @@ void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog, ...@@ -397,13 +388,9 @@ void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog,
if (work) { if (work) {
INIT_WORK((struct work_struct *)work, pseries_hp_work_fn); INIT_WORK((struct work_struct *)work, pseries_hp_work_fn);
work->errlog = hp_errlog_copy; work->errlog = hp_errlog_copy;
work->hp_completion = hotplug_done;
work->rc = rc;
queue_work(pseries_hp_wq, (struct work_struct *)work); queue_work(pseries_hp_wq, (struct work_struct *)work);
} else { } else {
*rc = -ENOMEM;
kfree(hp_errlog_copy); kfree(hp_errlog_copy);
complete(hotplug_done);
} }
} }
...@@ -521,18 +508,15 @@ static int dlpar_parse_id_type(char **cmd, struct pseries_hp_errorlog *hp_elog) ...@@ -521,18 +508,15 @@ static int dlpar_parse_id_type(char **cmd, struct pseries_hp_errorlog *hp_elog)
static ssize_t dlpar_store(struct class *class, struct class_attribute *attr, static ssize_t dlpar_store(struct class *class, struct class_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct pseries_hp_errorlog *hp_elog; struct pseries_hp_errorlog hp_elog;
struct completion hotplug_done;
char *argbuf; char *argbuf;
char *args; char *args;
int rc; int rc;
args = argbuf = kstrdup(buf, GFP_KERNEL); args = argbuf = kstrdup(buf, GFP_KERNEL);
hp_elog = kzalloc(sizeof(*hp_elog), GFP_KERNEL); if (!argbuf) {
if (!hp_elog || !argbuf) {
pr_info("Could not allocate resources for DLPAR operation\n"); pr_info("Could not allocate resources for DLPAR operation\n");
kfree(argbuf); kfree(argbuf);
kfree(hp_elog);
return -ENOMEM; return -ENOMEM;
} }
...@@ -540,25 +524,22 @@ static ssize_t dlpar_store(struct class *class, struct class_attribute *attr, ...@@ -540,25 +524,22 @@ static ssize_t dlpar_store(struct class *class, struct class_attribute *attr,
* Parse out the request from the user, this will be in the form: * Parse out the request from the user, this will be in the form:
* <resource> <action> <id_type> <id> * <resource> <action> <id_type> <id>
*/ */
rc = dlpar_parse_resource(&args, hp_elog); rc = dlpar_parse_resource(&args, &hp_elog);
if (rc) if (rc)
goto dlpar_store_out; goto dlpar_store_out;
rc = dlpar_parse_action(&args, hp_elog); rc = dlpar_parse_action(&args, &hp_elog);
if (rc) if (rc)
goto dlpar_store_out; goto dlpar_store_out;
rc = dlpar_parse_id_type(&args, hp_elog); rc = dlpar_parse_id_type(&args, &hp_elog);
if (rc) if (rc)
goto dlpar_store_out; goto dlpar_store_out;
init_completion(&hotplug_done); rc = handle_dlpar_errorlog(&hp_elog);
queue_hotplug_event(hp_elog, &hotplug_done, &rc);
wait_for_completion(&hotplug_done);
dlpar_store_out: dlpar_store_out:
kfree(argbuf); kfree(argbuf);
kfree(hp_elog);
if (rc) if (rc)
pr_err("Could not handle DLPAR request \"%s\"\n", buf); pr_err("Could not handle DLPAR request \"%s\"\n", buf);
......
...@@ -242,7 +242,7 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index) ...@@ -242,7 +242,7 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index)
static void prrn_update_node(__be32 phandle) static void prrn_update_node(__be32 phandle)
{ {
struct pseries_hp_errorlog *hp_elog; struct pseries_hp_errorlog hp_elog;
struct device_node *dn; struct device_node *dn;
/* /*
...@@ -255,18 +255,12 @@ static void prrn_update_node(__be32 phandle) ...@@ -255,18 +255,12 @@ static void prrn_update_node(__be32 phandle)
return; return;
} }
hp_elog = kzalloc(sizeof(*hp_elog), GFP_KERNEL); hp_elog.resource = PSERIES_HP_ELOG_RESOURCE_MEM;
if(!hp_elog) hp_elog.action = PSERIES_HP_ELOG_ACTION_READD;
return; hp_elog.id_type = PSERIES_HP_ELOG_ID_DRC_INDEX;
hp_elog._drc_u.drc_index = phandle;
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 = phandle;
queue_hotplug_event(hp_elog, NULL, NULL);
kfree(hp_elog); handle_dlpar_errorlog(&hp_elog);
} }
int pseries_devicetree_update(s32 scope) int pseries_devicetree_update(s32 scope)
......
...@@ -60,8 +60,9 @@ extern int dlpar_detach_node(struct device_node *); ...@@ -60,8 +60,9 @@ extern int dlpar_detach_node(struct device_node *);
extern int dlpar_acquire_drc(u32 drc_index); extern int dlpar_acquire_drc(u32 drc_index);
extern int dlpar_release_drc(u32 drc_index); extern int dlpar_release_drc(u32 drc_index);
void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog, void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog);
struct completion *hotplug_done, int *rc); int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_errlog);
#ifdef CONFIG_MEMORY_HOTPLUG #ifdef CONFIG_MEMORY_HOTPLUG
int dlpar_memory(struct pseries_hp_errorlog *hp_elog); int dlpar_memory(struct pseries_hp_errorlog *hp_elog);
#else #else
......
...@@ -334,7 +334,7 @@ static irqreturn_t ras_hotplug_interrupt(int irq, void *dev_id) ...@@ -334,7 +334,7 @@ static irqreturn_t ras_hotplug_interrupt(int irq, void *dev_id)
*/ */
if (hp_elog->resource == PSERIES_HP_ELOG_RESOURCE_MEM || 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)
queue_hotplug_event(hp_elog, NULL, NULL); queue_hotplug_event(hp_elog);
else else
log_error(ras_log_buf, ERR_TYPE_RTAS_LOG, 0); log_error(ras_log_buf, ERR_TYPE_RTAS_LOG, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment