Subject: Re: [PATCH 1/3] powerpc/pseries: Add pseries hotplug workqueue

From: Nathan Fontenot <[email-masked]>
Date: Mon, 11 Jul 2016 10:48:57 -0500

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 <[email-masked]>
> ---
>  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 <[email-masked]>

>  	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
> [email-masked]
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>