lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CANLsYkxLWaEe3YEpXOc=2Bmn5q8beZSYo45T+OnRuD8+7DiGKA@mail.gmail.com>
Date:	Thu, 30 Jun 2016 09:19:07 -0600
From:	Mathieu Poirier <mathieu.poirier@...aro.org>
To:	Alexander Shishkin <alexander.shishkin@...ux.intel.com>
Cc:	Greg KH <greg@...ah.com>, Chunyan Zhang <zhang.chunyan@...aro.org>,
	laurent.fert@...el.com, yann.fouassier@...el.com,
	"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: Re: [QUEUED v20160630 1/4] stm class: Add runtime power management handling

On 30 June 2016 at 06:56, Alexander Shishkin
<alexander.shishkin@...ux.intel.com> wrote:
> Currently, there's no runtime pm in stm class devices, which makes it
> harder for the underlying hardware drivers to handle their power
> management.
>
> This patch applies the following runtime pm policy to stm class devices,
> which their parents can rely on for their power management tracking:
>
>   * device is in use during character device writes,
>   * delayed autosuspend is used to keep it active between adjacent
>   writes,
>   * device is in use while mmio regions are mapped,
>   * device is is use while any stm_source devices are linked to it.
>
> Signed-off-by: Alexander Shishkin <alexander.shishkin@...ux.intel.com>
> Cc: Mathieu Poirier <mathieu.poirier@...aro.org>
> Cc: Chunyan Zhang <zhang.chunyan@...aro.org>

Coresight power management on my Juno board (the only device with an
STM I have access to) is broken and as such, can't test if this code
does what is intended.  But theoretically it looks good.

Throughout the driver, wouldn't it be better to use
pm_runtime_put_sync() rather than autosuspending with a hard coded
value?

Thanks,
Mathieu

> ---
>  drivers/hwtracing/stm/core.c | 47 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
>
> diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c
> index ff31108b06..ff3a868c2a 100644
> --- a/drivers/hwtracing/stm/core.c
> +++ b/drivers/hwtracing/stm/core.c
> @@ -15,6 +15,7 @@
>   * as defined in MIPI STPv2 specification.
>   */
>
> +#include <linux/pm_runtime.h>
>  #include <linux/uaccess.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> @@ -482,14 +483,40 @@ static ssize_t stm_char_write(struct file *file, const char __user *buf,
>                 return -EFAULT;
>         }
>
> +       pm_runtime_get_sync(&stm->dev);
> +
>         count = stm_write(stm->data, stmf->output.master, stmf->output.channel,
>                           kbuf, count);
>
> +       pm_runtime_mark_last_busy(&stm->dev);
> +       pm_runtime_put_autosuspend(&stm->dev);
>         kfree(kbuf);
>
>         return count;
>  }
>
> +static void stm_mmap_open(struct vm_area_struct *vma)
> +{
> +       struct stm_file *stmf = vma->vm_file->private_data;
> +       struct stm_device *stm = stmf->stm;
> +
> +       pm_runtime_get(&stm->dev);
> +}
> +
> +static void stm_mmap_close(struct vm_area_struct *vma)
> +{
> +       struct stm_file *stmf = vma->vm_file->private_data;
> +       struct stm_device *stm = stmf->stm;
> +
> +       pm_runtime_mark_last_busy(&stm->dev);
> +       pm_runtime_put_autosuspend(&stm->dev);
> +}
> +
> +static const struct vm_operations_struct stm_mmap_vmops = {
> +       .open   = stm_mmap_open,
> +       .close  = stm_mmap_close,
> +};
> +
>  static int stm_char_mmap(struct file *file, struct vm_area_struct *vma)
>  {
>         struct stm_file *stmf = file->private_data;
> @@ -514,8 +541,11 @@ static int stm_char_mmap(struct file *file, struct vm_area_struct *vma)
>         if (!phys)
>                 return -EINVAL;
>
> +       pm_runtime_get_sync(&stm->dev);
> +
>         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
>         vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
> +       vma->vm_ops = &stm_mmap_vmops;
>         vm_iomap_memory(vma, phys, size);
>
>         return 0;
> @@ -701,6 +731,12 @@ int stm_register_device(struct device *parent, struct stm_data *stm_data,
>         if (err)
>                 goto err_device;
>
> +       pm_runtime_no_callbacks(&stm->dev);
> +       pm_runtime_use_autosuspend(&stm->dev);
> +       pm_runtime_set_autosuspend_delay(&stm->dev, 2000);
> +       pm_runtime_set_suspended(&stm->dev);
> +       pm_runtime_enable(&stm->dev);
> +
>         return 0;
>
>  err_device:
> @@ -724,6 +760,9 @@ void stm_unregister_device(struct stm_data *stm_data)
>         struct stm_source_device *src, *iter;
>         int i, ret;
>
> +       pm_runtime_dont_use_autosuspend(&stm->dev);
> +       pm_runtime_disable(&stm->dev);
> +
>         mutex_lock(&stm->link_mutex);
>         list_for_each_entry_safe(src, iter, &stm->link_list, link_entry) {
>                 ret = __stm_source_link_drop(src, stm);
> @@ -878,6 +917,8 @@ static int __stm_source_link_drop(struct stm_source_device *src,
>
>         stm_output_free(link, &src->output);
>         list_del_init(&src->link_entry);
> +       pm_runtime_mark_last_busy(&link->dev);
> +       pm_runtime_put_autosuspend(&link->dev);
>         /* matches stm_find_device() from stm_source_link_store() */
>         stm_put_device(link);
>         rcu_assign_pointer(src->link, NULL);
> @@ -971,8 +1012,11 @@ static ssize_t stm_source_link_store(struct device *dev,
>         if (!link)
>                 return -EINVAL;
>
> +       pm_runtime_get(&link->dev);
> +
>         err = stm_source_link_add(src, link);
>         if (err) {
> +               pm_runtime_put_autosuspend(&link->dev);
>                 /* matches the stm_find_device() above */
>                 stm_put_device(link);
>         }
> @@ -1033,6 +1077,9 @@ int stm_source_register_device(struct device *parent,
>         if (err)
>                 goto err;
>
> +       pm_runtime_no_callbacks(&src->dev);
> +       pm_runtime_forbid(&src->dev);
> +
>         err = device_add(&src->dev);
>         if (err)
>                 goto err;
> --
> 2.8.1
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ