lkml.org 
[lkml]   [2022]   [Apr]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 6/8] vfio: Invoke runtime PM API for IOCTL request
    Date
    The vfio/pci driver will have runtime power management support where the
    user can put the device low power state and then PCI devices can go into
    the D3cold state. If the device is in low power state and user issues any
    IOCTL, then the device should be moved out of low power state first. Once
    the IOCTL is serviced, then it can go into low power state again. The
    runtime PM framework manages this with help of usage count. One option
    was to add the runtime PM related API's inside vfio/pci driver but some
    IOCTL (like VFIO_DEVICE_FEATURE) can follow a different path and more
    IOCTL can be added in the future. Also, the runtime PM will be
    added for vfio/pci based drivers variant currently but the other vfio
    based drivers can use the same in the future. So, this patch adds the
    runtime calls runtime related API in the top level IOCTL function itself.

    For the vfio drivers which do not have runtime power management support
    currently, the runtime PM API's won't be invoked. Only for vfio/pci
    based drivers currently, the runtime PM API's will be invoked to increment
    and decrement the usage count. Taking this usage count incremented while
    servicing IOCTL will make sure that user won't put the device into low
    power state when any other IOCTL is being serviced in parallel.

    Signed-off-by: Abhishek Sahu <abhsahu@nvidia.com>
    ---
    drivers/vfio/vfio.c | 44 +++++++++++++++++++++++++++++++++++++++++---
    1 file changed, 41 insertions(+), 3 deletions(-)

    diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
    index a4555014bd1e..4e65a127744e 100644
    --- a/drivers/vfio/vfio.c
    +++ b/drivers/vfio/vfio.c
    @@ -32,6 +32,7 @@
    #include <linux/vfio.h>
    #include <linux/wait.h>
    #include <linux/sched/signal.h>
    +#include <linux/pm_runtime.h>
    #include "vfio.h"

    #define DRIVER_VERSION "0.3"
    @@ -1536,6 +1537,30 @@ static const struct file_operations vfio_group_fops = {
    .release = vfio_group_fops_release,
    };

    +/*
    + * Wrapper around pm_runtime_resume_and_get().
    + * Return 0, if driver power management callbacks are not present i.e. the driver is not
    + * using runtime power management.
    + * Return 1 upon success, otherwise -errno
    + */
    +static inline int vfio_device_pm_runtime_get(struct device *dev)
    +{
    +#ifdef CONFIG_PM
    + int ret;
    +
    + if (!dev->driver || !dev->driver->pm)
    + return 0;
    +
    + ret = pm_runtime_resume_and_get(dev);
    + if (ret < 0)
    + return ret;
    +
    + return 1;
    +#else
    + return 0;
    +#endif
    +}
    +
    /*
    * VFIO Device fd
    */
    @@ -1845,15 +1870,28 @@ static long vfio_device_fops_unl_ioctl(struct file *filep,
    unsigned int cmd, unsigned long arg)
    {
    struct vfio_device *device = filep->private_data;
    + int pm_ret, ret = 0;
    +
    + pm_ret = vfio_device_pm_runtime_get(device->dev);
    + if (pm_ret < 0)
    + return pm_ret;

    switch (cmd) {
    case VFIO_DEVICE_FEATURE:
    - return vfio_ioctl_device_feature(device, (void __user *)arg);
    + ret = vfio_ioctl_device_feature(device, (void __user *)arg);
    + break;
    default:
    if (unlikely(!device->ops->ioctl))
    - return -EINVAL;
    - return device->ops->ioctl(device, cmd, arg);
    + ret = -EINVAL;
    + else
    + ret = device->ops->ioctl(device, cmd, arg);
    + break;
    }
    +
    + if (pm_ret)
    + pm_runtime_put(device->dev);
    +
    + return ret;
    }

    static ssize_t vfio_device_fops_read(struct file *filep, char __user *buf,
    --
    2.17.1
    \
     
     \ /
      Last update: 2022-04-25 11:29    [W:2.610 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site