From patchwork Mon Mar 1 15:07:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 1445644 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=J5b+HU75; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Dq3Xb4kMhz9sR4 for ; Tue, 2 Mar 2021 02:07:43 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=c7YTnRVwRwSguIwYKuuA6w5JA7K4srHjo0m9GBih52U=; b=J5b+HU75jk5UPpiBL58n/Msza kqZl24lYCXUwIBfCLkpMtmaLx8q0jmtZHN8tvSAW+TiIL5Rc5bOnvgRWaCH5kLdWuOCKW8Cl1MBzo jzAnEIOIX1y6/gZEMqA3t2l7u99LSB7629UWmazUsHeda6rngqmwQTkcDS/VnTne9oyxaB16NPrEp 5Bc9p2HZGYj0RXjwsOkrRezqOGztmW5FdVMDQRfYeGcq5l9U2OVIXY6SRzCp5snWKOjsPB1omLYeq 439MTyJe5za950+Ui3EIUAqZe1NNyMU7RPMFtExZox7CSDIdVfCmI0FNPKd1xSNdKLT6pxTKzo2Wx /OvH6xMcw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1lGk8w-0008G3-5t; Mon, 01 Mar 2021 15:07:30 +0000 Received: from s3.sipsolutions.net ([2a01:4f8:191:4433::2] helo=sipsolutions.net) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1lGk8p-0008Af-HO for linux-um@lists.infradead.org; Mon, 01 Mar 2021 15:07:25 +0000 Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.94) (envelope-from ) id 1lGk8l-00AJOK-HL; Mon, 01 Mar 2021 16:07:19 +0100 From: Johannes Berg To: linux-um@lists.infradead.org Subject: [PATCH v2 8/8] um: virtio/pci: enable suspend/resume Date: Mon, 1 Mar 2021 16:07:08 +0100 Message-Id: <20210301160501.19e6e5378a97.I2e9caf8b2083e2a8d0c76799179db35d08032aa1@changeid> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210301150708.244970-1-johannes@sipsolutions.net> References: <20210301150708.244970-1-johannes@sipsolutions.net> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210301_100723_645242_6F60109B X-CRM114-Status: GOOD ( 20.00 ) X-Spam-Score: 0.3 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_NONE SPF: sender does not publish an SPF Record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.3 KHOP_HELO_FCRDNS Relay HELO differs from its IP's reverse DNS X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Arnd Bergmann , linux-kernel@vger.kernel.org, Johannes Berg Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Johannes Berg The UM virtual PCI devices currently cannot be suspended properly since the virtio driver already disables VQs well before the PCI bus's suspend_noirq wants to complete the transition by writing to PCI config space. After trying around for a long time with moving the devices on the DPM list, trying to create dependencies between them, etc. I gave up and instead added UML specific cross-driver API that lets the virt-pci code enable not suspending/resuming VQs for its devices. This then allows the PCI bus suspend_noirq to still talk to the device, and suspend/resume works properly. Signed-off-by: Johannes Berg --- arch/um/drivers/virt-pci.c | 10 ++++++++ arch/um/drivers/virtio_uml.c | 40 ++++++++++++++++++++++-------- arch/um/include/linux/virtio-uml.h | 13 ++++++++++ 3 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 arch/um/include/linux/virtio-uml.h diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c index dd85f36197aa..0b802834f40a 100644 --- a/arch/um/drivers/virt-pci.c +++ b/arch/um/drivers/virt-pci.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -134,6 +135,9 @@ static int um_pci_send_cmd(struct um_pci_device *dev, if (completed == HANDLE_NO_FREE(cmd)) break; + if (completed && !HANDLE_IS_NO_FREE(completed)) + kfree(completed); + if (WARN_ONCE(virtqueue_is_broken(dev->cmd_vq) || ++delay_count > UM_VIRT_PCI_MAXDELAY, "um virt-pci delay: %d", delay_count)) { @@ -550,6 +554,12 @@ static int um_pci_virtio_probe(struct virtio_device *vdev) device_set_wakeup_enable(&vdev->dev, true); + /* + * In order to do suspend-resume properly, don't allow VQs + * to be suspended. + */ + virtio_uml_set_no_vq_suspend(vdev, true); + um_pci_rescan(); return 0; error: diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index 91ddf74ca888..4412d6febade 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -56,6 +56,7 @@ struct virtio_uml_device { u8 status; u8 registered:1; u8 suspended:1; + u8 no_vq_suspend:1; u8 config_changed_irq:1; uint64_t vq_irq_vq_map; @@ -1098,6 +1099,19 @@ static void virtio_uml_release_dev(struct device *d) kfree(vu_dev); } +void virtio_uml_set_no_vq_suspend(struct virtio_device *vdev, + bool no_vq_suspend) +{ + struct virtio_uml_device *vu_dev = to_virtio_uml_device(vdev); + + if (WARN_ON(vdev->config != &virtio_uml_config_ops)) + return; + + vu_dev->no_vq_suspend = no_vq_suspend; + dev_info(&vdev->dev, "%sabled VQ suspend\n", + no_vq_suspend ? "dis" : "en"); +} + /* Platform device */ static int virtio_uml_probe(struct platform_device *pdev) @@ -1302,13 +1316,16 @@ MODULE_DEVICE_TABLE(of, virtio_uml_match); static int virtio_uml_suspend(struct platform_device *pdev, pm_message_t state) { struct virtio_uml_device *vu_dev = platform_get_drvdata(pdev); - struct virtqueue *vq; - virtio_device_for_each_vq((&vu_dev->vdev), vq) { - struct virtio_uml_vq_info *info = vq->priv; + if (!vu_dev->no_vq_suspend) { + struct virtqueue *vq; - info->suspended = true; - vhost_user_set_vring_enable(vu_dev, vq->index, false); + virtio_device_for_each_vq((&vu_dev->vdev), vq) { + struct virtio_uml_vq_info *info = vq->priv; + + info->suspended = true; + vhost_user_set_vring_enable(vu_dev, vq->index, false); + } } if (!device_may_wakeup(&vu_dev->vdev.dev)) { @@ -1322,13 +1339,16 @@ static int virtio_uml_suspend(struct platform_device *pdev, pm_message_t state) static int virtio_uml_resume(struct platform_device *pdev) { struct virtio_uml_device *vu_dev = platform_get_drvdata(pdev); - struct virtqueue *vq; - virtio_device_for_each_vq((&vu_dev->vdev), vq) { - struct virtio_uml_vq_info *info = vq->priv; + if (!vu_dev->no_vq_suspend) { + struct virtqueue *vq; + + virtio_device_for_each_vq((&vu_dev->vdev), vq) { + struct virtio_uml_vq_info *info = vq->priv; - info->suspended = false; - vhost_user_set_vring_enable(vu_dev, vq->index, true); + info->suspended = false; + vhost_user_set_vring_enable(vu_dev, vq->index, true); + } } vu_dev->suspended = false; diff --git a/arch/um/include/linux/virtio-uml.h b/arch/um/include/linux/virtio-uml.h new file mode 100644 index 000000000000..2f652fa90f04 --- /dev/null +++ b/arch/um/include/linux/virtio-uml.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2021 Intel Corporation + * Author: Johannes Berg + */ + +#ifndef __VIRTIO_UML_H__ +#define __VIRTIO_UML_H__ + +void virtio_uml_set_no_vq_suspend(struct virtio_device *vdev, + bool no_vq_suspend); + +#endif /* __VIRTIO_UML_H__ */