Received: by 2002:a25:868d:0:0:0:0:0 with SMTP id z13csp1715510ybk; Mon, 11 May 2020 02:28:58 -0700 (PDT) X-Google-Smtp-Source: APiQypILXVKWqxpn0DAM2UfiC9JFJ/hKu5Qm7haSGBfczAwP54lHm7teZLsCvov4oEKQ5FFZnk+U X-Received: by 2002:a17:906:8051:: with SMTP id x17mr6958000ejw.251.1589189337884; Mon, 11 May 2020 02:28:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1589189337; cv=none; d=google.com; s=arc-20160816; b=mX1Tflc3SoETxZRWmb4fi3QjrEb+MsKcaOJhU9IT+UfqH9eKFCnSnCFIvV/+nSOaTp FZsFtzrIf3ktA9ub1O2ltm6w9chsg/euz6j/zwTM0JtDUsFbHpibsSbfgTgsh38bRODi s4FeqzubZUjpNyDBUkcNkp66YftnIIvuuieOAEVwe3Z5oUCUxo3FvpV5rEOnEhcpTY0D z7Vf1YTz2M7vxp5XZfYC8xprgB/MUg9T0N++5EPWIdswG2C5B0IHzOcyW9Afzmg7w3Gc NCNoZ9dFsxxzK7bEK4Eky5vYbFUCyE0lOj/ynBwf90MThSvlFagoe7rWdXaSzGPVfpou sq5A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-language :content-transfer-encoding:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature; bh=13BAfE/1sRi/J98yTfEpMD1AFwnvSYNGHAmPHqQf/Xs=; b=W7hchyATzksw+szDgzgLUpcmuvibYgEq0dSCiDPGw7p89oq+nEH4b82BHVTexPxTMf V4MWlJL88skVOAvoJ4hOJxGCEsnyYhH5XA2+qb4v+5DH7aoS5PlRRmlWR7k7qVKyOeen 79apQ2FmOvCzA77sI0Z7FYg5iJbJXcgytkuJvnJ0kOnowUVyR1kC5ej1GyYpxfXSwc6S 6dq+rjrUJe09VeLwm1Bj+gx0xud5qesyJNy8BqIr8dfTWZFAMoOyJMQBQMQWN/EDDVsa azuWID06dPE6yWEFX64E9VXvIRLGE3/5KT5i1GG1yFISJVvPwpvep67EL2ex+TDhFEXw o5fw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=bAq1Ws61; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id m18si5674282eja.298.2020.05.11.02.28.33; Mon, 11 May 2020 02:28:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=bAq1Ws61; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 S1725993AbgEKJ1F (ORCPT + 99 others); Mon, 11 May 2020 05:27:05 -0400 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:46664 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726071AbgEKJ1F (ORCPT ); Mon, 11 May 2020 05:27:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1589189222; 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=13BAfE/1sRi/J98yTfEpMD1AFwnvSYNGHAmPHqQf/Xs=; b=bAq1Ws61NhzVkyb0RcrYAxrhfqPtdsI7iAKXrbkB1lnfx73drcBWNI5VjchcAlZRpXCXE4 M6hZrxTpgHmHIWYyzbJ06b9QzVBkjSranz3OKOUmcJconl13L50yPM3zINe2HlS8uL40aW bNG1fQZRsL1JUheJDc2bIu1hREZjD6Q= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-422-054MV0GAOBWYzkGne0pEFA-1; Mon, 11 May 2020 05:27:01 -0400 X-MC-Unique: 054MV0GAOBWYzkGne0pEFA-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C06AA18CA274; Mon, 11 May 2020 09:26:59 +0000 (UTC) Received: from [10.72.12.137] (ovpn-12-137.pek2.redhat.com [10.72.12.137]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2670C165F6; Mon, 11 May 2020 09:26:50 +0000 (UTC) Subject: Re: [PATCH] ifcvf: move IRQ request/free to status change handlers To: Zhu Lingshan , mst@redhat.com, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org Cc: lulu@redhat.com, dan.daly@intel.com, cunming.liang@intel.com References: <1589181563-38400-1-git-send-email-lingshan.zhu@intel.com> From: Jason Wang Message-ID: <22d9dcdb-e790-0a68-ba41-b9530b2bf9fd@redhat.com> Date: Mon, 11 May 2020 17:26:49 +0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <1589181563-38400-1-git-send-email-lingshan.zhu@intel.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2020/5/11 下午3:19, Zhu Lingshan wrote: > This commit move IRQ request and free operations from probe() > to VIRTIO status change handler to comply with VIRTIO spec. > > VIRTIO spec 1.1, section 2.1.2 Device Requirements: Device Status Field > The device MUST NOT consume buffers or send any used buffer > notifications to the driver before DRIVER_OK. My previous explanation might be wrong here. It depends on how you implement your hardware, if you hardware guarantee that no interrupt will be triggered before DRIVER_OK, then it's fine. And the main goal for this patch is to allocate the interrupt on demand. > > Signed-off-by: Zhu Lingshan > --- > drivers/vdpa/ifcvf/ifcvf_main.c | 119 ++++++++++++++++++++++++---------------- > 1 file changed, 73 insertions(+), 46 deletions(-) > > diff --git a/drivers/vdpa/ifcvf/ifcvf_main.c b/drivers/vdpa/ifcvf/ifcvf_main.c > index abf6a061..4d58bf2 100644 > --- a/drivers/vdpa/ifcvf/ifcvf_main.c > +++ b/drivers/vdpa/ifcvf/ifcvf_main.c > @@ -28,6 +28,60 @@ static irqreturn_t ifcvf_intr_handler(int irq, void *arg) > return IRQ_HANDLED; > } > > +static void ifcvf_free_irq_vectors(void *data) > +{ > + pci_free_irq_vectors(data); > +} > + > +static void ifcvf_free_irq(struct ifcvf_adapter *adapter, int queues) > +{ > + struct pci_dev *pdev = adapter->pdev; > + struct ifcvf_hw *vf = &adapter->vf; > + int i; > + > + > + for (i = 0; i < queues; i++) > + devm_free_irq(&pdev->dev, vf->vring[i].irq, &vf->vring[i]); > + > + ifcvf_free_irq_vectors(pdev); > +} > + > +static int ifcvf_request_irq(struct ifcvf_adapter *adapter) > +{ > + struct pci_dev *pdev = adapter->pdev; > + struct ifcvf_hw *vf = &adapter->vf; > + int vector, i, ret, irq; > + > + ret = pci_alloc_irq_vectors(pdev, IFCVF_MAX_INTR, > + IFCVF_MAX_INTR, PCI_IRQ_MSIX); > + if (ret < 0) { > + IFCVF_ERR(pdev, "Failed to alloc IRQ vectors\n"); > + return ret; > + } > + > + for (i = 0; i < IFCVF_MAX_QUEUE_PAIRS * 2; i++) { > + snprintf(vf->vring[i].msix_name, 256, "ifcvf[%s]-%d\n", > + pci_name(pdev), i); > + vector = i + IFCVF_MSI_QUEUE_OFF; > + irq = pci_irq_vector(pdev, vector); > + ret = devm_request_irq(&pdev->dev, irq, > + ifcvf_intr_handler, 0, > + vf->vring[i].msix_name, > + &vf->vring[i]); > + if (ret) { > + IFCVF_ERR(pdev, > + "Failed to request irq for vq %d\n", i); > + ifcvf_free_irq(adapter, i); I'm not sure this unwind is correct. It looks like we should loop and call devm_free_irq() for virtqueue [0, i); > + > + return ret; > + } > + > + vf->vring[i].irq = irq; > + } > + > + return 0; > +} > + > static int ifcvf_start_datapath(void *private) > { > struct ifcvf_hw *vf = ifcvf_private_to_vf(private); > @@ -118,9 +172,12 @@ static void ifcvf_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status) > { > struct ifcvf_adapter *adapter; > struct ifcvf_hw *vf; > + u8 status_old; > + int ret; > > vf = vdpa_to_vf(vdpa_dev); > adapter = dev_get_drvdata(vdpa_dev->dev.parent); > + status_old = ifcvf_get_status(vf); > > if (status == 0) { > ifcvf_stop_datapath(adapter); > @@ -128,7 +185,22 @@ static void ifcvf_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status) > return; > } > > - if (status & VIRTIO_CONFIG_S_DRIVER_OK) { > + if ((status_old & VIRTIO_CONFIG_S_DRIVER_OK) && > + !(status & VIRTIO_CONFIG_S_DRIVER_OK)) { > + ifcvf_stop_datapath(adapter); > + ifcvf_free_irq(adapter, IFCVF_MAX_QUEUE_PAIRS * 2); > + } > + > + if ((status & VIRTIO_CONFIG_S_DRIVER_OK) && > + !(status_old & VIRTIO_CONFIG_S_DRIVER_OK)) { > + ret = ifcvf_request_irq(adapter); > + if (ret) { > + status = ifcvf_get_status(vf); > + status |= VIRTIO_CONFIG_S_FAILED; > + ifcvf_set_status(vf, status); > + return; > + } > + Have a hard though on the logic here. This depends on the status setting from guest or userspace. Which means it can not deal with e.g when qemu or userspace is crashed? Do we need to care this or it's a over engineering? Thanks > if (ifcvf_start_datapath(adapter) < 0) > IFCVF_ERR(adapter->pdev, > "Failed to set ifcvf vdpa status %u\n", > @@ -284,38 +356,6 @@ static void ifcvf_vdpa_set_config_cb(struct vdpa_device *vdpa_dev, > .set_config_cb = ifcvf_vdpa_set_config_cb, > }; > > -static int ifcvf_request_irq(struct ifcvf_adapter *adapter) > -{ > - struct pci_dev *pdev = adapter->pdev; > - struct ifcvf_hw *vf = &adapter->vf; > - int vector, i, ret, irq; > - > - > - for (i = 0; i < IFCVF_MAX_QUEUE_PAIRS * 2; i++) { > - snprintf(vf->vring[i].msix_name, 256, "ifcvf[%s]-%d\n", > - pci_name(pdev), i); > - vector = i + IFCVF_MSI_QUEUE_OFF; > - irq = pci_irq_vector(pdev, vector); > - ret = devm_request_irq(&pdev->dev, irq, > - ifcvf_intr_handler, 0, > - vf->vring[i].msix_name, > - &vf->vring[i]); > - if (ret) { > - IFCVF_ERR(pdev, > - "Failed to request irq for vq %d\n", i); > - return ret; > - } > - vf->vring[i].irq = irq; > - } > - > - return 0; > -} > - > -static void ifcvf_free_irq_vectors(void *data) > -{ > - pci_free_irq_vectors(data); > -} > - > static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id) > { > struct device *dev = &pdev->dev; > @@ -349,13 +389,6 @@ static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id) > return ret; > } > > - ret = pci_alloc_irq_vectors(pdev, IFCVF_MAX_INTR, > - IFCVF_MAX_INTR, PCI_IRQ_MSIX); > - if (ret < 0) { > - IFCVF_ERR(pdev, "Failed to alloc irq vectors\n"); > - return ret; > - } > - > ret = devm_add_action_or_reset(dev, ifcvf_free_irq_vectors, pdev); > if (ret) { > IFCVF_ERR(pdev, > @@ -379,12 +412,6 @@ static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id) > adapter->pdev = pdev; > adapter->vdpa.dma_dev = &pdev->dev; > > - ret = ifcvf_request_irq(adapter); > - if (ret) { > - IFCVF_ERR(pdev, "Failed to request MSI-X irq\n"); > - goto err; > - } > - > ret = ifcvf_init_hw(vf, pdev); > if (ret) { > IFCVF_ERR(pdev, "Failed to init IFCVF hw\n");