Received: by 2002:ad5:4acb:0:0:0:0:0 with SMTP id n11csp2679610imw; Wed, 6 Jul 2022 09:55:51 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tvAyYZclW9WLDZyH9VewjwrlzSI4jXhFBC8XXTmIsCZhcSIsX2TXxczr/H14YBr17hTUyT X-Received: by 2002:a17:90b:380c:b0:1ed:2071:e6b with SMTP id mq12-20020a17090b380c00b001ed20710e6bmr49954246pjb.82.1657126550763; Wed, 06 Jul 2022 09:55:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657126550; cv=none; d=google.com; s=arc-20160816; b=Y4qY+/PfK//pAVszFqu+bkwfcC4XoiqREPNOnp4VBjLZV0t2te9BbKUnN8qvzmjQxx 3yFnyhWsieviORogU1qK5ot9GIhNdNP+s2GziGmUvMj3ZBQuFHP5beIotAi7T+zpnqnB UBRewxAN5hkeJ+sVxrggBgNGYL2BT+tnsFX8HrbpGKQsIZF1NaeVdvhBh90UBaImlLI1 7/Bs520xBvY7yJX1XUJnntPjsziUUOZi4iccLL7AHu/0HKQpbw2UwYwtq8acD4OoMMD6 EyWU/SJmdV0Y5i21Xy2HK4HVUzxVkhbCAvBmnG+m3vYkVeWJzGsFommS5IjZ7sNqVjER J6pA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :organization:references:in-reply-to:message-id:subject:cc:to:from :date:dkim-signature; bh=j2ouW0IJ50/LD/W4uln9u2YiN3e6DrWUMY1mn0yrjIw=; b=FxLeZ0MWXyo6E66SkMtd4hm4Sy8u7GD1ediVDjFziRTF3QsaE5ZB7WlmTLgg+kj5oN NRaDlUwcCRUiiPf8F3e3MC+tD2nalLnNCqk0VUZ6UMZT5IBEqpAJXyqFTB4g8TnDYKJv D5Rsg72vWM/Nfrm/vKa40SnKrTOaPZbISraOtPXc2s2MDvJxbhcJ8Wwc0976TJRl89h/ 2b2/ILz39z6zlTNp+LSnfiSMggz95nSR2dJ3UhZJ2ZY71sBHWExLpKPOYzcQ79ePP3FN tY7q23f/iOYjeSIKy96jXAR+mbczHm4yutkQAGsvBWnLe8Dw4LU9Q3er7nkckDrWgkyh BT3A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="Lhv/xcly"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id f7-20020a654007000000b004128a3f4d3asi700419pgp.593.2022.07.06.09.55.38; Wed, 06 Jul 2022 09:55:50 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="Lhv/xcly"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234678AbiGFPs0 (ORCPT + 99 others); Wed, 6 Jul 2022 11:48:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41268 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233995AbiGFPsD (ORCPT ); Wed, 6 Jul 2022 11:48:03 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id EBF942A257 for ; Wed, 6 Jul 2022 08:40:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1657122054; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=j2ouW0IJ50/LD/W4uln9u2YiN3e6DrWUMY1mn0yrjIw=; b=Lhv/xclyPHjig8uePAaGwwSpkJnhNmMqNcdHWdYT5TqKDFtOyGsanZDDDEFVTVsGCf2cI2 gIt/2weWpkal6foaA1t9hQ7P3c8DvxciCHON/HAeLBO+ezcJKWjw16fdilfKyrXExAJk12 v/6JUDS4xiKa0GreWMj+J6v0IVg3Dl0= Received: from mail-il1-f200.google.com (mail-il1-f200.google.com [209.85.166.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-624-oiubjBZLN5Wsmv5017X6GA-1; Wed, 06 Jul 2022 11:40:53 -0400 X-MC-Unique: oiubjBZLN5Wsmv5017X6GA-1 Received: by mail-il1-f200.google.com with SMTP id x5-20020a923005000000b002d1a91c4d13so7833225ile.4 for ; Wed, 06 Jul 2022 08:40:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:in-reply-to :references:organization:mime-version:content-transfer-encoding; bh=j2ouW0IJ50/LD/W4uln9u2YiN3e6DrWUMY1mn0yrjIw=; b=jtMmiHjTGAq5qlpYkveI/R+F4tLuouB4sGb64eGMdBYAESvTrPhckJVUsEmNSl6aRo lEckYA7FzIZtlljKq/wFkNv282MTkpp5w4xQxQWORiJ634pe0v1E3ZK7P89Ep1iz55VX SXguz2ELBsOm71B4AyQS0FwhJjK2hXQvy1zwrJ/aQxLcC7JTgQ7K8Y2hKrmv4fcu+0Kg s72p8cYrCdI+cJDdBu0EGGvqJAx0Lw0HfaipuepXeC70U/LO4G0p9EmoKJ9laBY3mzEd AwoCowFA91kkFLUYQ9z1f9xOqRkgMWlthZgzppLpvDPTHDXHxBwZPxub1E2phKxSsMu1 KekA== X-Gm-Message-State: AJIora9pPOWJ2tjOxNBYe8Appyl5qmqjFj+W5YSwsYAhTv9afmPvtqJ6 E3EEZhtqdWdyxXpqf2No6xSlVS9bXw07q5DY6dKUWGdpXEN5ohAfO3fJAjKdJ8UAU8GOnE3GFMD j69eBj0rmcjlZLma795K6ZqLp X-Received: by 2002:a05:6e02:12ea:b0:2da:bb5b:bcc5 with SMTP id l10-20020a056e0212ea00b002dabb5bbcc5mr23192256iln.173.1657122052914; Wed, 06 Jul 2022 08:40:52 -0700 (PDT) X-Received: by 2002:a05:6e02:12ea:b0:2da:bb5b:bcc5 with SMTP id l10-20020a056e0212ea00b002dabb5bbcc5mr23192237iln.173.1657122052658; Wed, 06 Jul 2022 08:40:52 -0700 (PDT) Received: from redhat.com ([38.15.36.239]) by smtp.gmail.com with ESMTPSA id d12-20020a0566022bec00b0066958ec56d9sm17003884ioy.40.2022.07.06.08.40.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Jul 2022 08:40:51 -0700 (PDT) Date: Wed, 6 Jul 2022 09:40:07 -0600 From: Alex Williamson To: Abhishek Sahu Cc: Cornelia Huck , Yishai Hadas , Jason Gunthorpe , Shameer Kolothum , Kevin Tian , "Rafael J . Wysocki" , Max Gurtovoy , Bjorn Helgaas , , , , Subject: Re: [PATCH v4 3/6] vfio: Increment the runtime PM usage count during IOCTL call Message-ID: <20220706094007.12c33d63.alex.williamson@redhat.com> In-Reply-To: <20220701110814.7310-4-abhsahu@nvidia.com> References: <20220701110814.7310-1-abhsahu@nvidia.com> <20220701110814.7310-4-abhsahu@nvidia.com> Organization: Red Hat MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, 1 Jul 2022 16:38:11 +0530 Abhishek Sahu wrote: > The vfio-pci based driver will have runtime power management > support where the user can put the device into the low power state > and then PCI devices can go into the D3cold state. If the device is > in the low power state and the user issues any IOCTL, then the > device should be moved out of the low power state first. Once > the IOCTL is serviced, then it can go into the 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. Variant drivers can easily opt-out of runtime pm support by performing a gratuitous pm-get in their device-open function. > Taking this usage count incremented while servicing IOCTL will make > sure that the user won't put the device into low power state when any > other IOCTL is being serviced in parallel. Let's consider the > following scenario: > > 1. Some other IOCTL is called. > 2. The user has opened another device instance and called the power > management IOCTL for the low power entry. > 3. The power management IOCTL moves the device into the low power state. > 4. The other IOCTL finishes. > > If we don't keep the usage count incremented then the device > access will happen between step 3 and 4 while the device has already > gone into the low power state. > > The runtime PM API's should not be invoked for > VFIO_DEVICE_FEATURE_POWER_MANAGEMENT since this IOCTL itself performs > the runtime power management entry and exit for the VFIO device. I think the one-shot interface I proposed in the previous patch avoids the need for special handling for these feature ioctls. Thanks, Alex > The pm_runtime_resume_and_get() will be the first call so its error > should not be propagated to user space directly. For example, if > pm_runtime_resume_and_get() can return -EINVAL for the cases where the > user has passed the correct argument. So the > pm_runtime_resume_and_get() errors have been masked behind -EIO. > > Signed-off-by: Abhishek Sahu > --- > drivers/vfio/vfio.c | 82 ++++++++++++++++++++++++++++++++++++++++----- > 1 file changed, 74 insertions(+), 8 deletions(-) > > diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c > index 61e71c1154be..61a8d9f7629a 100644 > --- a/drivers/vfio/vfio.c > +++ b/drivers/vfio/vfio.c > @@ -32,6 +32,7 @@ > #include > #include > #include > +#include > #include "vfio.h" > > #define DRIVER_VERSION "0.3" > @@ -1333,6 +1334,39 @@ static const struct file_operations vfio_group_fops = { > .release = vfio_group_fops_release, > }; > > +/* > + * Wrapper around pm_runtime_resume_and_get(). > + * Return error code on failure or 0 on success. > + */ > +static inline int vfio_device_pm_runtime_get(struct vfio_device *device) > +{ > + struct device *dev = device->dev; > + > + if (dev->driver && dev->driver->pm) { > + int ret; > + > + ret = pm_runtime_resume_and_get(dev); > + if (ret < 0) { > + dev_info_ratelimited(dev, > + "vfio: runtime resume failed %d\n", ret); > + return -EIO; > + } > + } > + > + return 0; > +} > + > +/* > + * Wrapper around pm_runtime_put(). > + */ > +static inline void vfio_device_pm_runtime_put(struct vfio_device *device) > +{ > + struct device *dev = device->dev; > + > + if (dev->driver && dev->driver->pm) > + pm_runtime_put(dev); > +} > + > /* > * VFIO Device fd > */ > @@ -1607,6 +1641,8 @@ static int vfio_ioctl_device_feature(struct vfio_device *device, > { > size_t minsz = offsetofend(struct vfio_device_feature, flags); > struct vfio_device_feature feature; > + int ret = 0; > + u16 feature_cmd; > > if (copy_from_user(&feature, arg, minsz)) > return -EFAULT; > @@ -1626,28 +1662,51 @@ static int vfio_ioctl_device_feature(struct vfio_device *device, > (feature.flags & VFIO_DEVICE_FEATURE_GET)) > return -EINVAL; > > - switch (feature.flags & VFIO_DEVICE_FEATURE_MASK) { > + feature_cmd = feature.flags & VFIO_DEVICE_FEATURE_MASK; > + > + /* > + * The VFIO_DEVICE_FEATURE_POWER_MANAGEMENT itself performs the runtime > + * power management entry and exit for the VFIO device, so the runtime > + * PM API's should not be called for this feature. > + */ > + if (feature_cmd != VFIO_DEVICE_FEATURE_POWER_MANAGEMENT) { > + ret = vfio_device_pm_runtime_get(device); > + if (ret) > + return ret; > + } > + > + switch (feature_cmd) { > case VFIO_DEVICE_FEATURE_MIGRATION: > - return vfio_ioctl_device_feature_migration( > + ret = vfio_ioctl_device_feature_migration( > device, feature.flags, arg->data, > feature.argsz - minsz); > + break; > case VFIO_DEVICE_FEATURE_MIG_DEVICE_STATE: > - return vfio_ioctl_device_feature_mig_device_state( > + ret = vfio_ioctl_device_feature_mig_device_state( > device, feature.flags, arg->data, > feature.argsz - minsz); > + break; > default: > if (unlikely(!device->ops->device_feature)) > - return -EINVAL; > - return device->ops->device_feature(device, feature.flags, > - arg->data, > - feature.argsz - minsz); > + ret = -EINVAL; > + else > + ret = device->ops->device_feature( > + device, feature.flags, arg->data, > + feature.argsz - minsz); > + break; > } > + > + if (feature_cmd != VFIO_DEVICE_FEATURE_POWER_MANAGEMENT) > + vfio_device_pm_runtime_put(device); > + > + return ret; > } > > static long vfio_device_fops_unl_ioctl(struct file *filep, > unsigned int cmd, unsigned long arg) > { > struct vfio_device *device = filep->private_data; > + int ret; > > switch (cmd) { > case VFIO_DEVICE_FEATURE: > @@ -1655,7 +1714,14 @@ static long vfio_device_fops_unl_ioctl(struct file *filep, > default: > if (unlikely(!device->ops->ioctl)) > return -EINVAL; > - return device->ops->ioctl(device, cmd, arg); > + > + ret = vfio_device_pm_runtime_get(device); > + if (ret) > + return ret; > + > + ret = device->ops->ioctl(device, cmd, arg); > + vfio_device_pm_runtime_put(device); > + return ret; > } > } >