From patchwork Thu Jan 10 14:12:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Thierry X-Patchwork-Id: 10755883 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 71F3913B4 for ; Thu, 10 Jan 2019 14:13:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 61CC82994B for ; Thu, 10 Jan 2019 14:13:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5FFC529959; Thu, 10 Jan 2019 14:13:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E9E8B29961 for ; Thu, 10 Jan 2019 14:13:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728019AbfAJONL (ORCPT ); Thu, 10 Jan 2019 09:13:11 -0500 Received: from foss.arm.com ([217.140.101.70]:36466 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727983AbfAJONJ (ORCPT ); Thu, 10 Jan 2019 09:13:09 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 51BDA15BE; Thu, 10 Jan 2019 06:13:09 -0800 (PST) Received: from e112298-lin.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 1F80C3F5AF; Thu, 10 Jan 2019 06:13:07 -0800 (PST) From: Julien Thierry To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: jean-philippe.brucker@arm.com, will.deacon@arm.com, kraxel@redhat.com, Julien Thierry Subject: [PATCH kvmtool v2 09/13] virtio/net: Implement device and virtqueue reset Date: Thu, 10 Jan 2019 14:12:46 +0000 Message-Id: <1547129570-14351-10-git-send-email-julien.thierry@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1547129570-14351-1-git-send-email-julien.thierry@arm.com> References: <1547129570-14351-1-git-send-email-julien.thierry@arm.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Jean-Philippe Brucker On exit_vq(), clean all resources allocated for the queue. When the device is reset, clean the backend. Signed-off-by: Jean-Philippe Brucker Signed-off-by: Julien Thierry --- virtio/net.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/virtio/net.c b/virtio/net.c index ef8e226..a05f4cd 100644 --- a/virtio/net.c +++ b/virtio/net.c @@ -43,6 +43,8 @@ struct net_dev_queue { pthread_t thread; struct mutex lock; pthread_cond_t cond; + int gsi; + int irqfd; }; struct net_dev { @@ -361,6 +363,23 @@ fail: return 0; } +static void virtio_net__tap_exit(struct net_dev *ndev) +{ + int sock; + struct ifreq ifr; + + if (ndev->params->tapif) + return; + + sock = socket(AF_INET, SOCK_STREAM, 0); + strncpy(ifr.ifr_name, ndev->tap_name, sizeof(ndev->tap_name)); + ioctl(sock, SIOCGIFFLAGS, &ifr); + ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING); + if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) + pr_warning("Count not bring tap device down"); + close(sock); +} + static bool virtio_net__tap_create(struct net_dev *ndev) { int offload; @@ -533,10 +552,21 @@ static void virtio_net_start(struct net_dev *ndev) } } +static void virtio_net_stop(struct net_dev *ndev) +{ + /* Undo whatever start() did */ + if (ndev->mode == NET_MODE_TAP) + virtio_net__tap_exit(ndev); + else + uip_exit(&ndev->info); +} + static void notify_status(struct kvm *kvm, void *dev, u32 status) { if (status & VIRTIO__STATUS_START) virtio_net_start(dev); + else if (status & VIRTIO__STATUS_STOP) + virtio_net_stop(dev); } static bool is_ctrl_vq(struct net_dev *ndev, u32 vq) @@ -611,6 +641,35 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align, return 0; } +static void exit_vq(struct kvm *kvm, void *dev, u32 vq) +{ + struct net_dev *ndev = dev; + struct net_dev_queue *queue = &ndev->queues[vq]; + + if (!is_ctrl_vq(ndev, vq) && queue->gsi) { + irq__del_irqfd(kvm, queue->gsi, queue->irqfd); + close(queue->irqfd); + queue->gsi = queue->irqfd = 0; + } + + /* + * TODO: vhost reset owner. It's the only way to cleanly stop vhost, but + * we can't restart it at the moment. + */ + if (ndev->vhost_fd && !is_ctrl_vq(ndev, vq)) { + pr_warning("Cannot reset VHOST queue"); + ioctl(ndev->vhost_fd, VHOST_RESET_OWNER); + return; + } + + /* + * Threads are waiting on cancellation points (readv or + * pthread_cond_wait) and should stop gracefully. + */ + pthread_cancel(queue->thread); + pthread_join(queue->thread, NULL); +} + static void notify_vq_gsi(struct kvm *kvm, void *dev, u32 vq, u32 gsi) { struct net_dev *ndev = dev; @@ -630,6 +689,9 @@ static void notify_vq_gsi(struct kvm *kvm, void *dev, u32 vq, u32 gsi) if (r < 0) die_perror("KVM_IRQFD failed"); + queue->irqfd = file.fd; + queue->gsi = gsi; + r = ioctl(ndev->vhost_fd, VHOST_SET_VRING_CALL, &file); if (r < 0) die_perror("VHOST_SET_VRING_CALL failed"); @@ -698,6 +760,7 @@ static struct virtio_ops net_dev_virtio_ops = { .set_guest_features = set_guest_features, .get_vq_count = get_vq_count, .init_vq = init_vq, + .exit_vq = exit_vq, .get_vq = get_vq, .get_size_vq = get_size_vq, .set_size_vq = set_size_vq,