Message ID | 20221110185758.879472-2-ira.weiny@intel.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp323078wru; Thu, 10 Nov 2022 11:07:04 -0800 (PST) X-Google-Smtp-Source: AMsMyM7P+XcUboqmhZXg1QTNYyl0edcdxsjgwLoTontf09oQ1gls1ANCsQ0ck7N8GEt9KDQbrbmz X-Received: by 2002:a17:906:3bc1:b0:78d:8cf3:6ae with SMTP id v1-20020a1709063bc100b0078d8cf306aemr3617838ejf.173.1668107224637; Thu, 10 Nov 2022 11:07:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668107224; cv=none; d=google.com; s=arc-20160816; b=IJcLEdrs8nuOqRfpydfbwo5TUhyJ2GpKOhmJtYIMSsJaOjZxW/lgrd63rAkbFOQc7v wI7/zjjZbI7tNQqvp3TDzhv2dBPmCEJCTclQFLL9REs/ZRCq/ToaWzNc2l7iWOGejxae QH936Ibw7r0h0KSnpOWhDCpLjO2PEQ6ewAV3JzrghexzIl8k7ArIMgDSe3X691xip5hX XJU6WeCsNlVt8DRfBZCGXhvGmF4C2WWnxuT2/IZx9fF3Z6Z6TBANRDRZ++sObUW+cJGO dPwwXwvdQH47XmPBkHCK69UYsBA4afTBchPvq+AbvvEv8fZxe8J21KPIKpgmquiXmE3L WCag== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=iCjZMtrcO2ULR2luiewYLCn32Qnk3XJGAlCJiWDX3ic=; b=nQw9LHMm3ZveSzB4cZpZF0EurP7su6iJuByDqd+HFgMWiPRSKMkxAIWhcb042uJJVf inCjI4x29CZoikfBcNRb/GQ2+/iLt8jDHKloPsbxfaq3KCGEDXc74BlsQ8clWh7MGp+i 7/w2zC8DdjCkzip51QqHMilgdz0TQtLe4AQ/K+B/UeyeQcOXB4llp+iySmFxvR4jakn2 taN2TdB97lGnOuNbAwBSYzQI3w4Hp8OxG5lL1ZWVCXuivsZoI33T2ZNim8ZDCdMjWK6z hL1iF9GFdRM9zy5spRJRdMkqDlBT/+sfMGQa7ZKY6oIzX+7M/7djReP9TI7EKwiYv9KM 0GbQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=btjv4kiS; 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=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ke15-20020a17090798ef00b007a6384d506csi33476ejc.643.2022.11.10.11.06.40; Thu, 10 Nov 2022 11:07:04 -0800 (PST) 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=@intel.com header.s=Intel header.b=btjv4kiS; 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=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231394AbiKJTFy (ORCPT <rfc822;winker.wchi@gmail.com> + 99 others); Thu, 10 Nov 2022 14:05:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48634 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231493AbiKJTF3 (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 10 Nov 2022 14:05:29 -0500 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ACC2157B4A; Thu, 10 Nov 2022 11:05:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1668107110; x=1699643110; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Sx3L3dmcice/SW1UlG+9QaZyvdP4rfIP1/QGaOO2PdA=; b=btjv4kiS0E5tf0e71YU5b0rQF41/2SSZNucwzdPSiEAIzBp7MtlzDJ/Q gSbuBmdRgpGDCjaNcUh7O5aLBeefTL8VXH+2dya3owQKXyQKdFJKCX3Iw V2Z9hCEEZ0j9p3OAnHEcQvJPiMuQzGaJRC83qV4moUM2ZVur/UGRdEspf nc0gUE8qxodfyW3sTyHpD7En6Ge3QgBaeCD43QM695/RjmIZoHQoDa9HU mGqhvpDkD6pPYEoIQzuEiVk2QC9IumZ4LciqpAran+vAFGdvJqeB3iF3O adLGuU60LbrTFwwHtDJYozP0hc03apoi9pjOXxT/3GB0/rAYW448WX/2q g==; X-IronPort-AV: E=McAfee;i="6500,9779,10527"; a="375662050" X-IronPort-AV: E=Sophos;i="5.96,154,1665471600"; d="scan'208";a="375662050" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Nov 2022 10:58:05 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10527"; a="882473397" X-IronPort-AV: E=Sophos;i="5.96,154,1665471600"; d="scan'208";a="882473397" Received: from iweiny-mobl.amr.corp.intel.com (HELO localhost) ([10.212.6.223]) by fmsmga006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Nov 2022 10:58:05 -0800 From: ira.weiny@intel.com To: Dan Williams <dan.j.williams@intel.com> Cc: Davidlohr Bueso <dave@stgolabs.net>, Bjorn Helgaas <helgaas@kernel.org>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Ira Weiny <ira.weiny@intel.com>, Alison Schofield <alison.schofield@intel.com>, Vishal Verma <vishal.l.verma@intel.com>, Ben Widawsky <bwidawsk@kernel.org>, Steven Rostedt <rostedt@goodmis.org>, linux-kernel@vger.kernel.org, linux-cxl@vger.kernel.org Subject: [PATCH 01/11] cxl/pci: Add generic MSI-X/MSI irq support Date: Thu, 10 Nov 2022 10:57:48 -0800 Message-Id: <20221110185758.879472-2-ira.weiny@intel.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221110185758.879472-1-ira.weiny@intel.com> References: <20221110185758.879472-1-ira.weiny@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE autolearn=ham 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: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749137201256279599?= X-GMAIL-MSGID: =?utf-8?q?1749137201256279599?= |
Series |
CXL: Process event logs
|
|
Commit Message
Ira Weiny
Nov. 10, 2022, 6:57 p.m. UTC
From: Davidlohr Bueso <dave@stgolabs.net> Currently the only CXL features targeted for irq support require their message numbers to be within the first 16 entries. The device may however support less than 16 entries depending on the support it provides. Attempt to allocate these 16 irq vectors. If the device supports less then the PCI infrastructure will allocate that number. Store the number of vectors actually allocated in the device state for later use by individual functions. Upon successful allocation, users can plug in their respective isr at any point thereafter, for example, if the irq setup is not done in the PCI driver, such as the case of the CXL-PMU. Cc: Bjorn Helgaas <helgaas@kernel.org> Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com> Co-developed-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> --- Changes from Ira Remove reviews Allocate up to a static 16 vectors. Change cover letter --- drivers/cxl/cxlmem.h | 3 +++ drivers/cxl/cxlpci.h | 6 ++++++ drivers/cxl/pci.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+)
Comments
On 11/10/2022 10:57 AM, ira.weiny@intel.com wrote: > From: Davidlohr Bueso <dave@stgolabs.net> > > Currently the only CXL features targeted for irq support require their > message numbers to be within the first 16 entries. The device may > however support less than 16 entries depending on the support it > provides. > > Attempt to allocate these 16 irq vectors. If the device supports less > then the PCI infrastructure will allocate that number. Store the number > of vectors actually allocated in the device state for later use > by individual functions. > > Upon successful allocation, users can plug in their respective isr at > any point thereafter, for example, if the irq setup is not done in the > PCI driver, such as the case of the CXL-PMU. > > Cc: Bjorn Helgaas <helgaas@kernel.org> > Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com> > Co-developed-by: Ira Weiny <ira.weiny@intel.com> > Signed-off-by: Ira Weiny <ira.weiny@intel.com> > Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> Reviewed-by: Dave Jiang <dave.jiang@intel.com> > > --- > Changes from Ira > Remove reviews > Allocate up to a static 16 vectors. > Change cover letter > --- > drivers/cxl/cxlmem.h | 3 +++ > drivers/cxl/cxlpci.h | 6 ++++++ > drivers/cxl/pci.c | 32 ++++++++++++++++++++++++++++++++ > 3 files changed, 41 insertions(+) > > diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h > index 88e3a8e54b6a..b7b955ded3ac 100644 > --- a/drivers/cxl/cxlmem.h > +++ b/drivers/cxl/cxlmem.h > @@ -211,6 +211,7 @@ struct cxl_endpoint_dvsec_info { > * @info: Cached DVSEC information about the device. > * @serial: PCIe Device Serial Number > * @doe_mbs: PCI DOE mailbox array > + * @nr_irq_vecs: Number of MSI-X/MSI vectors available > * @mbox_send: @dev specific transport for transmitting mailbox commands > * > * See section 8.2.9.5.2 Capacity Configuration and Label Storage for > @@ -247,6 +248,8 @@ struct cxl_dev_state { > > struct xarray doe_mbs; > > + int nr_irq_vecs; > + > int (*mbox_send)(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd); > }; > > diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h > index eec597dbe763..b7f4e2f417d3 100644 > --- a/drivers/cxl/cxlpci.h > +++ b/drivers/cxl/cxlpci.h > @@ -53,6 +53,12 @@ > #define CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK GENMASK(15, 8) > #define CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK GENMASK(31, 16) > > +/* > + * NOTE: Currently all the functions which are enabled for CXL require their > + * vectors to be in the first 16. Use this as the max. > + */ > +#define CXL_PCI_REQUIRED_VECTORS 16 > + > /* Register Block Identifier (RBI) */ > enum cxl_regloc_type { > CXL_REGLOC_RBI_EMPTY = 0, > diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c > index faeb5d9d7a7a..62e560063e50 100644 > --- a/drivers/cxl/pci.c > +++ b/drivers/cxl/pci.c > @@ -428,6 +428,36 @@ static void devm_cxl_pci_create_doe(struct cxl_dev_state *cxlds) > } > } > > +static void cxl_pci_free_irq_vectors(void *data) > +{ > + pci_free_irq_vectors(data); > +} > + > +static void cxl_pci_alloc_irq_vectors(struct cxl_dev_state *cxlds) > +{ > + struct device *dev = cxlds->dev; > + struct pci_dev *pdev = to_pci_dev(dev); > + int nvecs; > + int rc; > + > + nvecs = pci_alloc_irq_vectors(pdev, 1, CXL_PCI_REQUIRED_VECTORS, > + PCI_IRQ_MSIX | PCI_IRQ_MSI); > + if (nvecs < 0) { > + dev_dbg(dev, "Not enough interrupts; use polling instead.\n"); > + return; > + } > + > + rc = devm_add_action_or_reset(dev, cxl_pci_free_irq_vectors, pdev); > + if (rc) { > + dev_dbg(dev, "Device managed call failed; interrupts disabled.\n"); > + /* some got allocated, clean them up */ > + cxl_pci_free_irq_vectors(pdev); > + return; > + } > + > + cxlds->nr_irq_vecs = nvecs; > +} > + > static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) > { > struct cxl_register_map map; > @@ -494,6 +524,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) > if (rc) > return rc; > > + cxl_pci_alloc_irq_vectors(cxlds); > + > cxlmd = devm_cxl_add_memdev(cxlds); > if (IS_ERR(cxlmd)) > return PTR_ERR(cxlmd);
On Thu, 10 Nov 2022 10:57:48 -0800 ira.weiny@intel.com wrote: > From: Davidlohr Bueso <dave@stgolabs.net> > > Currently the only CXL features targeted for irq support require their > message numbers to be within the first 16 entries. The device may > however support less than 16 entries depending on the support it > provides. > > Attempt to allocate these 16 irq vectors. If the device supports less > then the PCI infrastructure will allocate that number. Store the number > of vectors actually allocated in the device state for later use > by individual functions. See later patch review, but I don't think we need to store the number allocated because any vector is guaranteed to be below that point (QEMU code is wrong on this at the momemt, but there are very few vectors so it hasn't mattered yet). Otherwise, pcim fun deals with some of the cleanup you are doing again here for us so can simplify this somewhat. See inline. Jonathan > > Upon successful allocation, users can plug in their respective isr at > any point thereafter, for example, if the irq setup is not done in the > PCI driver, such as the case of the CXL-PMU. > > Cc: Bjorn Helgaas <helgaas@kernel.org> > Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com> > Co-developed-by: Ira Weiny <ira.weiny@intel.com> > Signed-off-by: Ira Weiny <ira.weiny@intel.com> > Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> > > --- > Changes from Ira > Remove reviews > Allocate up to a static 16 vectors. > Change cover letter > --- > drivers/cxl/cxlmem.h | 3 +++ > drivers/cxl/cxlpci.h | 6 ++++++ > drivers/cxl/pci.c | 32 ++++++++++++++++++++++++++++++++ > 3 files changed, 41 insertions(+) > > diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h > index 88e3a8e54b6a..b7b955ded3ac 100644 > --- a/drivers/cxl/cxlmem.h > +++ b/drivers/cxl/cxlmem.h > @@ -211,6 +211,7 @@ struct cxl_endpoint_dvsec_info { > * @info: Cached DVSEC information about the device. > * @serial: PCIe Device Serial Number > * @doe_mbs: PCI DOE mailbox array > + * @nr_irq_vecs: Number of MSI-X/MSI vectors available > * @mbox_send: @dev specific transport for transmitting mailbox commands > * > * See section 8.2.9.5.2 Capacity Configuration and Label Storage for > @@ -247,6 +248,8 @@ struct cxl_dev_state { > > struct xarray doe_mbs; > > + int nr_irq_vecs; > + > int (*mbox_send)(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd); > }; > > diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h > index eec597dbe763..b7f4e2f417d3 100644 > --- a/drivers/cxl/cxlpci.h > +++ b/drivers/cxl/cxlpci.h > @@ -53,6 +53,12 @@ > #define CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK GENMASK(15, 8) > #define CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK GENMASK(31, 16) > > +/* > + * NOTE: Currently all the functions which are enabled for CXL require their > + * vectors to be in the first 16. Use this as the max. > + */ > +#define CXL_PCI_REQUIRED_VECTORS 16 > + > /* Register Block Identifier (RBI) */ > enum cxl_regloc_type { > CXL_REGLOC_RBI_EMPTY = 0, > diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c > index faeb5d9d7a7a..62e560063e50 100644 > --- a/drivers/cxl/pci.c > +++ b/drivers/cxl/pci.c > @@ -428,6 +428,36 @@ static void devm_cxl_pci_create_doe(struct cxl_dev_state *cxlds) > } > } > > +static void cxl_pci_free_irq_vectors(void *data) > +{ > + pci_free_irq_vectors(data); > +} > + > +static void cxl_pci_alloc_irq_vectors(struct cxl_dev_state *cxlds) > +{ > + struct device *dev = cxlds->dev; > + struct pci_dev *pdev = to_pci_dev(dev); > + int nvecs; > + int rc; > + > + nvecs = pci_alloc_irq_vectors(pdev, 1, CXL_PCI_REQUIRED_VECTORS, > + PCI_IRQ_MSIX | PCI_IRQ_MSI); > + if (nvecs < 0) { > + dev_dbg(dev, "Not enough interrupts; use polling instead.\n"); > + return; > + } > + > + rc = devm_add_action_or_reset(dev, cxl_pci_free_irq_vectors, pdev); The pci managed code always gives me a headache because there is a lot of magic under the hood if you ever called pcim_enable_device() which we did. Chasing through pci_alloc_irq_vectors_affinity()-> either __pci_enable_msix_range() or __pci_enable_msi_range() they are similar pci_setup_msi_context() pci_setup_msi_release() adds pcmi_msi_release devm action. and that frees the vectors for us. So we don't need to do it here. > + if (rc) { > + dev_dbg(dev, "Device managed call failed; interrupts disabled.\n"); > + /* some got allocated, clean them up */ > + cxl_pci_free_irq_vectors(pdev); We could just leave them lying around for devm cleanup to sweep up eventually or free them as you have done here. > + return; > + } > + > + cxlds->nr_irq_vecs = nvecs; > +} > + > static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) > { > struct cxl_register_map map; > @@ -494,6 +524,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) > if (rc) > return rc; > > + cxl_pci_alloc_irq_vectors(cxlds); > + > cxlmd = devm_cxl_add_memdev(cxlds); > if (IS_ERR(cxlmd)) > return PTR_ERR(cxlmd);
On Wed, Nov 16, 2022 at 02:53:41PM +0000, Jonathan Cameron wrote: > On Thu, 10 Nov 2022 10:57:48 -0800 > ira.weiny@intel.com wrote: > > > From: Davidlohr Bueso <dave@stgolabs.net> > > > > Currently the only CXL features targeted for irq support require their > > message numbers to be within the first 16 entries. The device may > > however support less than 16 entries depending on the support it > > provides. > > > > Attempt to allocate these 16 irq vectors. If the device supports less > > then the PCI infrastructure will allocate that number. Store the number > > of vectors actually allocated in the device state for later use > > by individual functions. > See later patch review, but I don't think we need to store the number > allocated because any vector is guaranteed to be below that point Only as long as we stick to those functions which are guaranteed to be under 16. If a device supports more than 16 and code is added to try and enable that irq this base support will not cover that. > (QEMU code is wrong on this at the momemt, but there are very few vectors > so it hasn't mattered yet). How so? Does the spec state that a device must report at least 16 vectors? > > Otherwise, pcim fun deals with some of the cleanup you are doing again > here for us so can simplify this somewhat. See inline. Yea it is broken. > > Jonathan > > > > > > > Upon successful allocation, users can plug in their respective isr at > > any point thereafter, for example, if the irq setup is not done in the > > PCI driver, such as the case of the CXL-PMU. > > > > Cc: Bjorn Helgaas <helgaas@kernel.org> > > Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > Co-developed-by: Ira Weiny <ira.weiny@intel.com> > > Signed-off-by: Ira Weiny <ira.weiny@intel.com> > > Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> > > > > --- > > Changes from Ira > > Remove reviews > > Allocate up to a static 16 vectors. > > Change cover letter > > --- > > drivers/cxl/cxlmem.h | 3 +++ > > drivers/cxl/cxlpci.h | 6 ++++++ > > drivers/cxl/pci.c | 32 ++++++++++++++++++++++++++++++++ > > 3 files changed, 41 insertions(+) > > > > diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h > > index 88e3a8e54b6a..b7b955ded3ac 100644 > > --- a/drivers/cxl/cxlmem.h > > +++ b/drivers/cxl/cxlmem.h > > @@ -211,6 +211,7 @@ struct cxl_endpoint_dvsec_info { > > * @info: Cached DVSEC information about the device. > > * @serial: PCIe Device Serial Number > > * @doe_mbs: PCI DOE mailbox array > > + * @nr_irq_vecs: Number of MSI-X/MSI vectors available > > * @mbox_send: @dev specific transport for transmitting mailbox commands > > * > > * See section 8.2.9.5.2 Capacity Configuration and Label Storage for > > @@ -247,6 +248,8 @@ struct cxl_dev_state { > > > > struct xarray doe_mbs; > > > > + int nr_irq_vecs; > > + > > int (*mbox_send)(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd); > > }; > > > > diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h > > index eec597dbe763..b7f4e2f417d3 100644 > > --- a/drivers/cxl/cxlpci.h > > +++ b/drivers/cxl/cxlpci.h > > @@ -53,6 +53,12 @@ > > #define CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK GENMASK(15, 8) > > #define CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK GENMASK(31, 16) > > > > +/* > > + * NOTE: Currently all the functions which are enabled for CXL require their > > + * vectors to be in the first 16. Use this as the max. > > + */ > > +#define CXL_PCI_REQUIRED_VECTORS 16 > > + > > /* Register Block Identifier (RBI) */ > > enum cxl_regloc_type { > > CXL_REGLOC_RBI_EMPTY = 0, > > diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c > > index faeb5d9d7a7a..62e560063e50 100644 > > --- a/drivers/cxl/pci.c > > +++ b/drivers/cxl/pci.c > > @@ -428,6 +428,36 @@ static void devm_cxl_pci_create_doe(struct cxl_dev_state *cxlds) > > } > > } > > > > +static void cxl_pci_free_irq_vectors(void *data) > > +{ > > + pci_free_irq_vectors(data); > > +} > > + > > +static void cxl_pci_alloc_irq_vectors(struct cxl_dev_state *cxlds) > > +{ > > + struct device *dev = cxlds->dev; > > + struct pci_dev *pdev = to_pci_dev(dev); > > + int nvecs; > > + int rc; > > + > > + nvecs = pci_alloc_irq_vectors(pdev, 1, CXL_PCI_REQUIRED_VECTORS, > > + PCI_IRQ_MSIX | PCI_IRQ_MSI); > > + if (nvecs < 0) { > > + dev_dbg(dev, "Not enough interrupts; use polling instead.\n"); > > + return; > > + } > > + > > + rc = devm_add_action_or_reset(dev, cxl_pci_free_irq_vectors, pdev); > The pci managed code always gives me a headache because there is a lot of magic > under the hood if you ever called pcim_enable_device() which we did. > > Chasing through > > pci_alloc_irq_vectors_affinity()-> > either > __pci_enable_msix_range() > or > __pci_enable_msi_range() > > they are similar > pci_setup_msi_context() > pci_setup_msi_release() > adds pcmi_msi_release devm action. > and that frees the vectors for us. > So we don't need to do it here. :-/ So what is the point of pci_free_irq_vectors()? This is very confusing to have a function not called pcim_* [pci_alloc_irq_vectors()] do 'pcim stuff'. Ok I'll drop this extra because I see it now. > > > > + if (rc) { > > + dev_dbg(dev, "Device managed call failed; interrupts disabled.\n"); > > + /* some got allocated, clean them up */ > > + cxl_pci_free_irq_vectors(pdev); > We could just leave them lying around for devm cleanup to sweep up eventually > or free them as you have done here. And besides this extra call is flat out broken. cxl_pci_free_irq_vectors() is already called at this point if devm_add_action_or_reset() failed... But I see this is not required. I do plan to add a big ol' comment as to why we don't need to mirror the call with the corresponding 'free'. I'll respin, Ira > > > + return; > > + } > > + > > + cxlds->nr_irq_vecs = nvecs; > > +} > > + > > static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) > > { > > struct cxl_register_map map; > > @@ -494,6 +524,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) > > if (rc) > > return rc; > > > > + cxl_pci_alloc_irq_vectors(cxlds); > > + > > cxlmd = devm_cxl_add_memdev(cxlds); > > if (IS_ERR(cxlmd)) > > return PTR_ERR(cxlmd); >
On Wed, 16 Nov 2022 15:48:48 -0800 Ira Weiny <ira.weiny@intel.com> wrote: > On Wed, Nov 16, 2022 at 02:53:41PM +0000, Jonathan Cameron wrote: > > On Thu, 10 Nov 2022 10:57:48 -0800 > > ira.weiny@intel.com wrote: > > > > > From: Davidlohr Bueso <dave@stgolabs.net> > > > > > > Currently the only CXL features targeted for irq support require their > > > message numbers to be within the first 16 entries. The device may > > > however support less than 16 entries depending on the support it > > > provides. > > > > > > Attempt to allocate these 16 irq vectors. If the device supports less > > > then the PCI infrastructure will allocate that number. Store the number > > > of vectors actually allocated in the device state for later use > > > by individual functions. > > See later patch review, but I don't think we need to store the number > > allocated because any vector is guaranteed to be below that point > > Only as long as we stick to those functions which are guaranteed to be under > 16. If a device supports more than 16 and code is added to try and enable that > irq this base support will not cover that. It matters only if this enable is changed. If this remains at 16, the vectors are guaranteed to be under 16.. > > > (QEMU code is wrong on this at the momemt, but there are very few vectors > > so it hasn't mattered yet). > > How so? Does the spec state that a device must report at least 16 vectors? Technically QEMU upstream today uses 1 vector I think, so failure to get that is the same as no irqs. As we expand to more possible vectors, QEMU should adjust the reported msgnums to fit in whatever vectors are enabled (if using msi, logic is handled elsewhere for msix as there is an indirection in the way and I think it is down to the OS to program that indirection correctly). See spec language referred to in review of the patch using the irqs. We may never implement that magic. but it is done correctly for other devices. https://elixir.bootlin.com/qemu/latest/source/hw/pci-bridge/ioh3420.c#L47 is an example where aer is on vector 1 unless there is only one vector in which case it falls back to vector 0. Jonathan > > > > > Otherwise, pcim fun deals with some of the cleanup you are doing again > > here for us so can simplify this somewhat. See inline. > > Yea it is broken. > > > > > Jonathan > > > > > > > > > > > > Upon successful allocation, users can plug in their respective isr at > > > any point thereafter, for example, if the irq setup is not done in the > > > PCI driver, such as the case of the CXL-PMU. > > > > > > Cc: Bjorn Helgaas <helgaas@kernel.org> > > > Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > > Co-developed-by: Ira Weiny <ira.weiny@intel.com> > > > Signed-off-by: Ira Weiny <ira.weiny@intel.com> > > > Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> > > > > > > --- > > > Changes from Ira > > > Remove reviews > > > Allocate up to a static 16 vectors. > > > Change cover letter > > > --- > > > drivers/cxl/cxlmem.h | 3 +++ > > > drivers/cxl/cxlpci.h | 6 ++++++ > > > drivers/cxl/pci.c | 32 ++++++++++++++++++++++++++++++++ > > > 3 files changed, 41 insertions(+) > > > > > > diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h > > > index 88e3a8e54b6a..b7b955ded3ac 100644 > > > --- a/drivers/cxl/cxlmem.h > > > +++ b/drivers/cxl/cxlmem.h > > > @@ -211,6 +211,7 @@ struct cxl_endpoint_dvsec_info { > > > * @info: Cached DVSEC information about the device. > > > * @serial: PCIe Device Serial Number > > > * @doe_mbs: PCI DOE mailbox array > > > + * @nr_irq_vecs: Number of MSI-X/MSI vectors available > > > * @mbox_send: @dev specific transport for transmitting mailbox commands > > > * > > > * See section 8.2.9.5.2 Capacity Configuration and Label Storage for > > > @@ -247,6 +248,8 @@ struct cxl_dev_state { > > > > > > struct xarray doe_mbs; > > > > > > + int nr_irq_vecs; > > > + > > > int (*mbox_send)(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd); > > > }; > > > > > > diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h > > > index eec597dbe763..b7f4e2f417d3 100644 > > > --- a/drivers/cxl/cxlpci.h > > > +++ b/drivers/cxl/cxlpci.h > > > @@ -53,6 +53,12 @@ > > > #define CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK GENMASK(15, 8) > > > #define CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK GENMASK(31, 16) > > > > > > +/* > > > + * NOTE: Currently all the functions which are enabled for CXL require their > > > + * vectors to be in the first 16. Use this as the max. > > > + */ > > > +#define CXL_PCI_REQUIRED_VECTORS 16 > > > + > > > /* Register Block Identifier (RBI) */ > > > enum cxl_regloc_type { > > > CXL_REGLOC_RBI_EMPTY = 0, > > > diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c > > > index faeb5d9d7a7a..62e560063e50 100644 > > > --- a/drivers/cxl/pci.c > > > +++ b/drivers/cxl/pci.c > > > @@ -428,6 +428,36 @@ static void devm_cxl_pci_create_doe(struct cxl_dev_state *cxlds) > > > } > > > } > > > > > > +static void cxl_pci_free_irq_vectors(void *data) > > > +{ > > > + pci_free_irq_vectors(data); > > > +} > > > + > > > +static void cxl_pci_alloc_irq_vectors(struct cxl_dev_state *cxlds) > > > +{ > > > + struct device *dev = cxlds->dev; > > > + struct pci_dev *pdev = to_pci_dev(dev); > > > + int nvecs; > > > + int rc; > > > + > > > + nvecs = pci_alloc_irq_vectors(pdev, 1, CXL_PCI_REQUIRED_VECTORS, > > > + PCI_IRQ_MSIX | PCI_IRQ_MSI); > > > + if (nvecs < 0) { > > > + dev_dbg(dev, "Not enough interrupts; use polling instead.\n"); > > > + return; > > > + } > > > + > > > + rc = devm_add_action_or_reset(dev, cxl_pci_free_irq_vectors, pdev); > > The pci managed code always gives me a headache because there is a lot of magic > > under the hood if you ever called pcim_enable_device() which we did. > > > > Chasing through > > > > pci_alloc_irq_vectors_affinity()-> > > either > > __pci_enable_msix_range() > > or > > __pci_enable_msi_range() > > > > they are similar > > pci_setup_msi_context() > > pci_setup_msi_release() > > adds pcmi_msi_release devm action. > > and that frees the vectors for us. > > So we don't need to do it here. > > :-/ > > So what is the point of pci_free_irq_vectors()? This is very confusing to have > a function not called pcim_* [pci_alloc_irq_vectors()] do 'pcim stuff'. > > Ok I'll drop this extra because I see it now. > > > > > > > > + if (rc) { > > > + dev_dbg(dev, "Device managed call failed; interrupts disabled.\n"); > > > + /* some got allocated, clean them up */ > > > + cxl_pci_free_irq_vectors(pdev); > > We could just leave them lying around for devm cleanup to sweep up eventually > > or free them as you have done here. > > And besides this extra call is flat out broken. cxl_pci_free_irq_vectors() is > already called at this point if devm_add_action_or_reset() failed... But I see > this is not required. > > I do plan to add a big ol' comment as to why we don't need to mirror the call > with the corresponding 'free'. > > I'll respin, > Ira > > > > > > + return; > > > + } > > > + > > > + cxlds->nr_irq_vecs = nvecs; > > > +} > > > + > > > static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) > > > { > > > struct cxl_register_map map; > > > @@ -494,6 +524,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) > > > if (rc) > > > return rc; > > > > > > + cxl_pci_alloc_irq_vectors(cxlds); > > > + > > > cxlmd = devm_cxl_add_memdev(cxlds); > > > if (IS_ERR(cxlmd)) > > > return PTR_ERR(cxlmd); > >
diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 88e3a8e54b6a..b7b955ded3ac 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -211,6 +211,7 @@ struct cxl_endpoint_dvsec_info { * @info: Cached DVSEC information about the device. * @serial: PCIe Device Serial Number * @doe_mbs: PCI DOE mailbox array + * @nr_irq_vecs: Number of MSI-X/MSI vectors available * @mbox_send: @dev specific transport for transmitting mailbox commands * * See section 8.2.9.5.2 Capacity Configuration and Label Storage for @@ -247,6 +248,8 @@ struct cxl_dev_state { struct xarray doe_mbs; + int nr_irq_vecs; + int (*mbox_send)(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd); }; diff --git a/drivers/cxl/cxlpci.h b/drivers/cxl/cxlpci.h index eec597dbe763..b7f4e2f417d3 100644 --- a/drivers/cxl/cxlpci.h +++ b/drivers/cxl/cxlpci.h @@ -53,6 +53,12 @@ #define CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK GENMASK(15, 8) #define CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK GENMASK(31, 16) +/* + * NOTE: Currently all the functions which are enabled for CXL require their + * vectors to be in the first 16. Use this as the max. + */ +#define CXL_PCI_REQUIRED_VECTORS 16 + /* Register Block Identifier (RBI) */ enum cxl_regloc_type { CXL_REGLOC_RBI_EMPTY = 0, diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index faeb5d9d7a7a..62e560063e50 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -428,6 +428,36 @@ static void devm_cxl_pci_create_doe(struct cxl_dev_state *cxlds) } } +static void cxl_pci_free_irq_vectors(void *data) +{ + pci_free_irq_vectors(data); +} + +static void cxl_pci_alloc_irq_vectors(struct cxl_dev_state *cxlds) +{ + struct device *dev = cxlds->dev; + struct pci_dev *pdev = to_pci_dev(dev); + int nvecs; + int rc; + + nvecs = pci_alloc_irq_vectors(pdev, 1, CXL_PCI_REQUIRED_VECTORS, + PCI_IRQ_MSIX | PCI_IRQ_MSI); + if (nvecs < 0) { + dev_dbg(dev, "Not enough interrupts; use polling instead.\n"); + return; + } + + rc = devm_add_action_or_reset(dev, cxl_pci_free_irq_vectors, pdev); + if (rc) { + dev_dbg(dev, "Device managed call failed; interrupts disabled.\n"); + /* some got allocated, clean them up */ + cxl_pci_free_irq_vectors(pdev); + return; + } + + cxlds->nr_irq_vecs = nvecs; +} + static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct cxl_register_map map; @@ -494,6 +524,8 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (rc) return rc; + cxl_pci_alloc_irq_vectors(cxlds); + cxlmd = devm_cxl_add_memdev(cxlds); if (IS_ERR(cxlmd)) return PTR_ERR(cxlmd);