On 07/07/2016 10:00 AM, John Allen wrote: > In support of PAPR changes to add a new hotplug interrupt, introduce a > hotplug workqueue to avoid processing hotplug events in interrupt context. > We will also take advantage of the queue on PowerVM to ensure hotplug > events initiated from different sources (HMC and PRRN events) are handled > and serialized properly. > > Signed-off-by: John Allen <jal...@linux.vnet.ibm.com> > --- > arch/powerpc/platforms/pseries/dlpar.c | 52 > ++++++++++++++++++++++++++++++++ > 1 file changed, 52 insertions(+) > > diff --git a/arch/powerpc/platforms/pseries/dlpar.c > b/arch/powerpc/platforms/pseries/dlpar.c > index 2b93ae8..66a77d7 100644 > --- a/arch/powerpc/platforms/pseries/dlpar.c > +++ b/arch/powerpc/platforms/pseries/dlpar.c > @@ -27,6 +27,15 @@ > #include <asm/uaccess.h> > #include <asm/rtas.h> > > +struct workqueue_struct *pseries_hp_wq; > + > +struct pseries_hp_work { > + struct work_struct work; > + struct pseries_hp_errorlog *errlog; > + struct completion *hp_completion; > + int *rc; > +}; > + > struct cc_workarea { > __be32 drc_index; > __be32 zero; > @@ -368,10 +377,51 @@ static int handle_dlpar_errorlog(struct > pseries_hp_errorlog *hp_elog) > return rc; > } > > +void pseries_hp_work_fn(struct work_struct *work) > +{ > + struct pseries_hp_work *hp_work = > + container_of(work, struct pseries_hp_work, work); > + > + if (hp_work->rc) > + *(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((void *)work); > +} > + > +void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog, > + struct completion *hotplug_done, int *rc) > +{ > + struct pseries_hp_work *work; > + struct pseries_hp_errorlog *hp_errlog_copy; > + > + hp_errlog_copy = kmalloc(sizeof(struct pseries_hp_errorlog), > + GFP_KERNEL); > + memcpy(hp_errlog_copy, hp_errlog, sizeof(struct pseries_hp_errorlog)); > + > + work = kmalloc(sizeof(struct pseries_hp_work), GFP_KERNEL); > + if (work) { > + INIT_WORK((struct work_struct *)work, pseries_hp_work_fn); > + work->errlog = hp_errlog_copy; > + work->hp_completion = hotplug_done; > + work->rc = rc; > + queue_work(pseries_hp_wq, (struct work_struct *)work); > + } else { > + *rc = -ENOMEM; > + complete(hotplug_done); > + } > +} > + > static ssize_t dlpar_store(struct class *class, struct class_attribute *attr, > const char *buf, size_t count) > { > struct pseries_hp_errorlog *hp_elog; > + struct completion hotplug_done;
It may not matter but this looks it may fit better in patch 3/3. Otherwise looks good. Reviewed-by: Nathan Fontenot <nf...@linux.vnet.ibm.com> > const char *arg; > int rc; > > @@ -450,6 +500,8 @@ static CLASS_ATTR(dlpar, S_IWUSR, NULL, dlpar_store); > > static int __init pseries_dlpar_init(void) > { > + pseries_hp_wq = alloc_workqueue("pseries hotplug workqueue", > + WQ_UNBOUND, 1); > return sysfs_create_file(kernel_kobj, &class_attr_dlpar.attr); > } > machine_device_initcall(pseries, pseries_dlpar_init); > > _______________________________________________ > Linuxppc-dev mailing list > Linuxppc-dev@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/linuxppc-dev > _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev