From nobody Sun Feb 8 03:11:43 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 526106CDA1 for ; Fri, 1 Mar 2024 11:30:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292617; cv=none; b=lM6megavEB9fdEoj2XOs3zYGKE/lzLQz7AwKBe0qx7GKi0v6nxbJTVUfxsX/RxW4sVThNT1Q19cILSwcSJDk2vIyC8bXL7vAkAtYvxMC6iQ4WdA85YCCkYr0aQYm9hzz15USvQfcOQm2UAXRxDPa23kB/7iYgBKlMi/f1Q5hMhI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292617; c=relaxed/simple; bh=6GsNN3xfF0svk8urGgXVKJfW7NcyK/H2Z4DcntRTz50=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jMi0dlM+41iEwfC3rUSbEdNLRJzlR8DThuSo+8fRhfczjen/aBsLAL4CdbnZYAFRjjerIqbqosisOMRQHWRaveymf5QriqwFNV/9kVi94VkE7rdfIEf+h6aUP9onniUb6JcbqeZ8Fvb+Y85zgKiNhb0Mt6/SlXwSIiBMc9j7VP4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=VDzASQKs; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="VDzASQKs" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709292614; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=X2fdTwDVrSeAHIT2se36OcPokxnegZtat+WYI3OiLNc=; b=VDzASQKsOZ2LR16mva4iieS7myXp77Eq2NiGAJJBKYanuEcVPAmB2wwofx4yCAOipchSF3 3vCXtldx6C3SUPz45OuH2P1zPTId77qEH0yYJW8fNybBRF3Uo9nPPxXZqGn8uZCUbSSHab hJbaOzlciGlkajzL+CAcmyVh01lbl3Y= Received: from mail-yb1-f197.google.com (mail-yb1-f197.google.com [209.85.219.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-279-kDbHyJRAOL25fR-hQxC_qg-1; Fri, 01 Mar 2024 06:30:13 -0500 X-MC-Unique: kDbHyJRAOL25fR-hQxC_qg-1 Received: by mail-yb1-f197.google.com with SMTP id 3f1490d57ef6-dcf3e29689eso807881276.1 for ; Fri, 01 Mar 2024 03:30:12 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709292612; x=1709897412; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=X2fdTwDVrSeAHIT2se36OcPokxnegZtat+WYI3OiLNc=; b=voW18y5qKfXsGsD/j/uBLqgjes/l+WU73yZMlOZdCW8Gvnn1+esXWypsW7Pci/SVbr GZTyFlXtMQR/CqQTsoOq0LN/z76xUhKs5JZtNdYqzkEmPLd8T5e6B4JNwXJzYSvVBYzW M5oCnN+iLXgiJhmhjeAz7+4e7I6j3vwjldEqGES4pJWkoOCli1rx/N59cGBwk3TCtDn3 kOMc59X14DTs/Jkwkk73nfrczTOehTJ/ij44ETfacXRliTWV7zsM73434igvSkUHVmka QrR1AB5PlJONdUyF0uUCjCUXq5qxm5vsQ8TK8PeEsQfst8BVOfzQwEWX26jf6fY4mQcJ GMrQ== X-Forwarded-Encrypted: i=1; AJvYcCWTZZ2fFCtlhuPI5vKMzAdM2SSNu5IoE1ZvxecBDKz/bVPReZAwrOGwMc0rl2FNEZ1UVdflcD0XWgTSMWw4JQ9q20ZUZyrPDKVQZ3gj X-Gm-Message-State: AOJu0Yw/dEEUJoTAt4o0Cq4ZW5VSi/J5Sc/4HaRzBt5iAa+OMTtRPGOC hr4SM7bXo226PtI4E7bhgv2RLIq0Mbup5qVQKBSbCKnuXNADUE6qQe4L6UUnKVTnyUxLfI+5qEH sUidoRHClAgaoLQQRIfm7VGFvBNtlYqMIiZ+9FeO7rjJY5TaQ/AnjyNJ3bbY9Kg== X-Received: by 2002:a0d:cc14:0:b0:609:87dd:98e6 with SMTP id o20-20020a0dcc14000000b0060987dd98e6mr500742ywd.5.1709292612054; Fri, 01 Mar 2024 03:30:12 -0800 (PST) X-Google-Smtp-Source: AGHT+IGXM17QGBdZ7jX+qXUHoBWFMOd/PCVx0cetnyQf3kJ3P2ZuAKaXf0XZ7rseLXWUyvh/N0P0Ow== X-Received: by 2002:a0d:cc14:0:b0:609:87dd:98e6 with SMTP id o20-20020a0dcc14000000b0060987dd98e6mr500710ywd.5.1709292611552; Fri, 01 Mar 2024 03:30:11 -0800 (PST) Received: from pstanner-thinkpadt14sgen1.remote.csb (nat-pool-muc-t.redhat.com. [149.14.88.26]) by smtp.gmail.com with ESMTPSA id b1-20020ac86781000000b0042eb46d15bbsm1596239qtp.88.2024.03.01.03.30.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Mar 2024 03:30:11 -0800 (PST) From: Philipp Stanner To: Hans de Goede , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter , Bjorn Helgaas , Sam Ravnborg , dakr@redhat.com Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Philipp Stanner Subject: [PATCH v4 01/10] PCI: Add new set of devres functions Date: Fri, 1 Mar 2024 12:29:49 +0100 Message-ID: <20240301112959.21947-2-pstanner@redhat.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240301112959.21947-1-pstanner@redhat.com> References: <20240301112959.21947-1-pstanner@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The PCI devres API is not extensible to partial BAR mappings and has bug-provoking features. Improve that by providing better alternatives. When the original PCI devres API was implemented, priority was given to the creation of a set of "plural functions" such as pcim_request_regions(). These functions have bit masks as parameters to specify which BARs shall get mapped. Most users, however, only use those to map 1-3 BARs. A complete set of "singular functions" does not exist. As functions mapping / requesting multiple BARs at once have (almost) no mechanism in C to return the resources to the caller of the plural function, the PCI devres API utilizes the iomap-table administrated by the function pcim_iomap_table(). The entire PCI devres API was strongly tied to that table which only allows for mapping whole, complete BARs, as the BAR's index is used as table index. Consequently, it's not possible to, e.g., have a pcim_iomap_range() function with that mechanism. An additional problem is hat the PCI devres API has been ipmlemented in a sort of "hybrid-mode": Some unmanaged functions have managed counterparts (e.g.: pci_iomap() <-> pcim_iomap()), making their managed nature obvious to the programmer. However, the region-request functions in pci.c, prefixed with pci_, behave either managed or unmanaged, depending on whether pci_enable_device() or pcim_enable_device() has been called in advance. This hybrid API is confusing and should be more cleanly separated by providing always-managed functions prefixed with pcim_. Thus, the existing PCI devres API is not desirable because: a) The vast majority of the users of the plural functions only ever sets a single bit in the bit mask, consequently making them singular functions anyways. b) There is no mechanism to request / iomap only part of a BAR. c) The iomap-table mechanism is over-engineered and complicated. Even worse, some users index over the table administration function directly: void __iomem *mapping =3D pcim_iomap_table(pdev)[my_index]; This can not perform bounds checks; an invalid index won't cause return of -EINVAL or even NULL, resulting in undefined behavior. d) region-request functions being sometimes managed and sometimes not is bug-provoking. Implement a set of singular pcim_ functions that use devres directly and bypass the legacy iomap table mechanism. Signed-off-by: Philipp Stanner --- drivers/pci/devres.c | 473 ++++++++++++++++++++++++++++++++++++++++++- include/linux/pci.h | 11 + 2 files changed, 479 insertions(+), 5 deletions(-) diff --git a/drivers/pci/devres.c b/drivers/pci/devres.c index 2c562b9eaf80..6a653e1a1acb 100644 --- a/drivers/pci/devres.c +++ b/drivers/pci/devres.c @@ -8,10 +8,215 @@ */ #define PCIM_IOMAP_MAX PCI_STD_NUM_BARS =20 +/* + * Legacy struct storing addresses to whole mapped BARs. + */ struct pcim_iomap_devres { void __iomem *table[PCIM_IOMAP_MAX]; }; =20 +enum pcim_addr_devres_type { + /* Default initializer. */ + PCIM_ADDR_DEVRES_TYPE_INVALID, + + /* A region spanning an entire BAR. */ + PCIM_ADDR_DEVRES_TYPE_REGION, + + /* A region spanning an entire BAR, and a mapping for that whole BAR. */ + PCIM_ADDR_DEVRES_TYPE_REGION_MAPPING, + + /* + * A mapping within a BAR, either spanning the whole BAR or just a range. + * Without a requested region. + */ + PCIM_ADDR_DEVRES_TYPE_MAPPING, + + /* A ranged region within a BAR, with a mapping spanning that range. */ + PCIM_ADDR_DEVRES_TYPE_REGION_RANGE_MAPPING +}; + +/* + * This struct envelopes IO or MEM addresses, that means mappings and regi= on + * requests, because those are very frequently requested and released toge= ther. + */ +struct pcim_addr_devres { + enum pcim_addr_devres_type type; + void __iomem *baseaddr; + unsigned long offset; + unsigned long len; + short bar; +}; + +static inline void pcim_addr_devres_clear(struct pcim_addr_devres *res) +{ + memset(res, 0, sizeof(*res)); + res->bar =3D -1; +} + +/* + * The following functions, __pcim_*_region*, exist as counterparts to the + * versions from pci.c - which, unfortunately, can be in "hybrid mode", i.= e., + * sometimes managed, sometimes not. + * + * To separate the APIs cleanly, we define our own, simplified versions he= re. + */ + +/** + * __pcim_request_region_range - Request a ranged region + * @pdev: PCI device the region belongs to + * @bar: The BAR the region is within + * @offset: offset from the BAR's start address + * @maxlen: length in bytes, beginning at @offset + * @name: name associated with the request + * @req_flags: flags for the request. For example for kernel-exclusive req= uests. + * + * Returns: 0 on success, a negative error code on failure. + * + * Request a ranged region within a device's PCI BAR. This function perfor= ms + * sanity checks on the input. + */ +static int __pcim_request_region_range(struct pci_dev *pdev, int bar, + unsigned long offset, unsigned long maxlen, + const char *name, int req_flags) +{ + resource_size_t start =3D pci_resource_start(pdev, bar); + resource_size_t len =3D pci_resource_len(pdev, bar); + unsigned long dev_flags =3D pci_resource_flags(pdev, bar); + + if (start =3D=3D 0 || len =3D=3D 0) /* That's an unused BAR. */ + return 0; + if (len <=3D offset) + return -EINVAL; + + start +=3D offset; + len -=3D offset; + + if (len > maxlen && maxlen !=3D 0) + len =3D maxlen; + + if (dev_flags & IORESOURCE_IO) { + if (!request_region(start, len, name)) + return -EBUSY; + } else if (dev_flags & IORESOURCE_MEM) { + if (!__request_mem_region(start, len, name, req_flags)) + return -EBUSY; + } else { + /* That's not a device we can request anything on. */ + return -ENODEV; + } + + return 0; +} + +static void __pcim_release_region_range(struct pci_dev *pdev, int bar, + unsigned long offset, unsigned long maxlen) +{ + resource_size_t start =3D pci_resource_start(pdev, bar); + resource_size_t len =3D pci_resource_len(pdev, bar); + unsigned long flags =3D pci_resource_flags(pdev, bar); + + if (len <=3D offset || start =3D=3D 0) + return; + + if (len =3D=3D 0 || maxlen =3D=3D 0) /* This an unused BAR. Do nothing. */ + return; + + start +=3D offset; + len -=3D offset; + + if (len > maxlen) + len =3D maxlen; + + if (flags & IORESOURCE_IO) + release_region(start, len); + else if (flags & IORESOURCE_MEM) + release_mem_region(start, len); +} + +static int __pcim_request_region(struct pci_dev *pdev, int bar, + const char *name, int flags) +{ + unsigned long offset =3D 0; + unsigned long len =3D pci_resource_len(pdev, bar); + + return __pcim_request_region_range(pdev, bar, offset, len, name, flags); +} + +static void __pcim_release_region(struct pci_dev *pdev, int bar) +{ + unsigned long offset =3D 0; + unsigned long len =3D pci_resource_len(pdev, bar); + + __pcim_release_region_range(pdev, bar, offset, len); +} + +static void pcim_addr_resource_release(struct device *dev, void *resource_= raw) +{ + struct pci_dev *pdev =3D to_pci_dev(dev); + struct pcim_addr_devres *res =3D resource_raw; + + switch (res->type) { + case PCIM_ADDR_DEVRES_TYPE_REGION: + __pcim_release_region(pdev, res->bar); + break; + case PCIM_ADDR_DEVRES_TYPE_REGION_MAPPING: + pci_iounmap(pdev, res->baseaddr); + __pcim_release_region(pdev, res->bar); + break; + case PCIM_ADDR_DEVRES_TYPE_MAPPING: + pci_iounmap(pdev, res->baseaddr); + break; + case PCIM_ADDR_DEVRES_TYPE_REGION_RANGE_MAPPING: + pci_iounmap(pdev, res->baseaddr); + __pcim_release_region_range(pdev, res->bar, res->offset, res->len); + break; + default: + break; + } +} + +static struct pcim_addr_devres *pcim_addr_devres_alloc(struct pci_dev *pde= v) +{ + struct pcim_addr_devres *res; + + res =3D devres_alloc_node(pcim_addr_resource_release, sizeof(*res), + GFP_KERNEL, dev_to_node(&pdev->dev)); + if (res) + pcim_addr_devres_clear(res); + return res; +} + +/* Just for consistency and readability. */ +static inline void pcim_addr_devres_free(struct pcim_addr_devres *res) +{ + devres_free(res); +} + +/* + * Used by devres to identify a pcim_addr_devres. + */ +static int pcim_addr_resources_match(struct device *dev, void *a_raw, void= *b_raw) +{ + struct pcim_addr_devres *a, *b; + + a =3D a_raw; + b =3D b_raw; + + if (a->type !=3D b->type) + return 0; + + switch (a->type) { + case PCIM_ADDR_DEVRES_TYPE_REGION: + case PCIM_ADDR_DEVRES_TYPE_REGION_MAPPING: + return a->bar =3D=3D b->bar; + case PCIM_ADDR_DEVRES_TYPE_MAPPING: + return a->baseaddr =3D=3D b->baseaddr; + case PCIM_ADDR_DEVRES_TYPE_REGION_RANGE_MAPPING: + return a->bar =3D=3D b->bar && a->offset =3D=3D b->offset && a->len =3D= =3D b->len; + default: + return 0; + } +} =20 static void devm_pci_unmap_iospace(struct device *dev, void *ptr) { @@ -92,8 +297,8 @@ EXPORT_SYMBOL(devm_pci_remap_cfgspace); * * All operations are managed and will be undone on driver detach. * - * Returns a pointer to the remapped memory or an ERR_PTR() encoded error = code - * on failure. Usage example:: + * Returns a pointer to the remapped memory or an IOMEM_ERR_PTR() encoded = error + * code on failure. Usage example:: * * res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); * base =3D devm_pci_remap_cfg_resource(&pdev->dev, res); @@ -339,15 +544,80 @@ void pcim_iounmap(struct pci_dev *pdev, void __iomem = *addr) tbl[i] =3D NULL; return; } - WARN_ON(1); } EXPORT_SYMBOL(pcim_iounmap); =20 +/** + * pcim_iomap_region - Request and iomap a PCI BAR + * @pdev: PCI device to map IO resources for + * @bar: Index of a BAR to map + * @name: Name associated with the request + * + * Returns: __iomem pointer on success, an IOMEM_ERR_PTR on failure. + * + * Mapping and region will get automatically released on driver detach. If + * desired, release manually only with pcim_iounmap_region(). + */ +void __iomem *pcim_iomap_region(struct pci_dev *pdev, int bar, const char = *name) +{ + int ret; + struct pcim_addr_devres *res; + + res =3D pcim_addr_devres_alloc(pdev); + if (!res) + return IOMEM_ERR_PTR(-ENOMEM); + + res->type =3D PCIM_ADDR_DEVRES_TYPE_REGION_MAPPING; + res->bar =3D bar; + + ret =3D __pcim_request_region(pdev, bar, name, 0); + if (ret !=3D 0) + goto err_region; + + res->baseaddr =3D pci_iomap(pdev, bar, 0); + if (!res->baseaddr) { + ret =3D -EINVAL; + goto err_iomap; + } + + devres_add(&pdev->dev, res); + return res->baseaddr; + +err_iomap: + __pcim_release_region(pdev, bar); +err_region: + pcim_addr_devres_free(res); + + return IOMEM_ERR_PTR(ret); +} +EXPORT_SYMBOL(pcim_iomap_region); + +/** + * pcim_iounmap_region - Unmap and release a PCI BAR + * @pdev: PCI device to operate on + * @bar: Index of BAR to unmap and release + * + * Unmap a BAR and release its region manually. Only pass BARs that were + * previously mapped by pcim_iomap_region(). + */ +void pcim_iounmap_region(struct pci_dev *pdev, int bar) +{ + struct pcim_addr_devres res_searched; + + pcim_addr_devres_clear(&res_searched); + res_searched.type =3D PCIM_ADDR_DEVRES_TYPE_REGION_MAPPING; + res_searched.bar =3D bar; + + devres_release(&pdev->dev, pcim_addr_resource_release, + pcim_addr_resources_match, &res_searched); +} +EXPORT_SYMBOL(pcim_iounmap_region); + /** * pcim_iomap_regions - Request and iomap PCI BARs * @pdev: PCI device to map IO resources for * @mask: Mask of BARs to request and iomap - * @name: Name used when requesting regions + * @name: Name associated with the requests * * Request and iomap regions specified by @mask. */ @@ -400,7 +670,7 @@ EXPORT_SYMBOL(pcim_iomap_regions); * pcim_iomap_regions_request_all - Request all BARs and iomap specified o= nes * @pdev: PCI device to map IO resources for * @mask: Mask of BARs to iomap - * @name: Name used when requesting regions + * @name: Name associated with the requests * * Request all PCI BARs and iomap regions specified by @mask. */ @@ -446,3 +716,196 @@ void pcim_iounmap_regions(struct pci_dev *pdev, int m= ask) } } EXPORT_SYMBOL(pcim_iounmap_regions); + +static int _pcim_request_region(struct pci_dev *pdev, int bar, const char = *name, + int request_flags) +{ + int ret; + struct pcim_addr_devres *res; + + res =3D pcim_addr_devres_alloc(pdev); + if (!res) + return -ENOMEM; + res->type =3D PCIM_ADDR_DEVRES_TYPE_REGION; + res->bar =3D bar; + + ret =3D __pcim_request_region(pdev, bar, name, request_flags); + if (ret !=3D 0) { + pcim_addr_devres_free(res); + return ret; + } + + devres_add(&pdev->dev, res); + return 0; +} + +/** + * pcim_request_region - Request a PCI BAR + * @pdev: PCI device to requestion region for + * @bar: Index of BAR to request + * @name: Name associated with the request + * + * Returns: 0 on success, a negative error code on failure. + * + * Request region specified by @bar. + * + * The region will automatically be released on driver detach. If desired, + * release manually only with pcim_release_region(). + */ +int pcim_request_region(struct pci_dev *pdev, int bar, const char *name) +{ + return _pcim_request_region(pdev, bar, name, 0); +} +EXPORT_SYMBOL(pcim_request_region); + +/** + * pcim_release_region - Release a PCI BAR + * @pdev: PCI device to operate on + * @bar: Index of BAR to release + * + * Release a region manually that was previously requested by + * pcim_request_region(). + */ +void pcim_release_region(struct pci_dev *pdev, int bar) +{ + struct pcim_addr_devres res_searched; + + pcim_addr_devres_clear(&res_searched); + res_searched.type =3D PCIM_ADDR_DEVRES_TYPE_REGION; + res_searched.bar =3D bar; + + devres_release(&pdev->dev, pcim_addr_resource_release, + pcim_addr_resources_match, &res_searched); +} +EXPORT_SYMBOL(pcim_release_region); + +/** + * pcim_iomap_range - Create a ranged __iomap mapping within a PCI BAR + * @pdev: PCI device to map IO resources for + * @bar: Index of the BAR + * @offset: Offset from the begin of the BAR + * @len: Length in bytes for the mapping + * + * Returns: __iomem pointer on success, an IOMEM_ERR_PTR on failure. + * + * Creates a new IO-Mapping within the specified @bar, ranging from @offse= t to + * @offset + @len. + * + * The mapping will automatically get unmapped on driver detach. If desire= d, + * release manually only with pcim_iounmap(). + */ +void __iomem *pcim_iomap_range(struct pci_dev *pdev, int bar, + unsigned long offset, unsigned long len) +{ + void __iomem *mapping; + struct pcim_addr_devres *res; + + res =3D pcim_addr_devres_alloc(pdev); + if (!res) + return IOMEM_ERR_PTR(-ENOMEM); + + mapping =3D pci_iomap_range(pdev, bar, offset, len); + if (!mapping) { + pcim_addr_devres_free(res); + return IOMEM_ERR_PTR(-EINVAL); + } + + res->type =3D PCIM_ADDR_DEVRES_TYPE_MAPPING; + res->baseaddr =3D mapping; + + /* + * Ranged mappings don't get added to the legacy-table, since the table + * only ever keeps track of whole BARs. + */ + + devres_add(&pdev->dev, res); + return mapping; +} +EXPORT_SYMBOL(pcim_iomap_range); + +/** + * pcim_iomap_region_range - Request and map a range within a PCI BAR + * @pdev: PCI device to map IO resources for + * @bar: Index of BAR to request within + * @offset: Offset from the begin of the BAR + * @len: Length in bytes for the mapping + * @name: Name associated with the request + * + * Returns: __iomem pointer on success, an IOMEM_ERR_PTR on failure. + * + * Request region with a range specified by @offset and @len within @bar a= nd + * iomap it. + * + * The region will automatically be released and the mapping be unmapped on + * driver detach. If desired, release manually only with + * pcim_iounmap_region_range(). + * + * You probably should only use this function if you explicitly do not wan= t to + * request the entire BAR. For most use-cases, combining pcim_request_regi= on() + * and pcim_iomap_range() should be sufficient. + */ +void __iomem *pcim_iomap_region_range(struct pci_dev *pdev, int bar, + unsigned long offset, unsigned long len, const char *name) +{ + int ret; + struct pcim_addr_devres *res; + + res =3D pcim_addr_devres_alloc(pdev); + if (!res) + return IOMEM_ERR_PTR(-ENOMEM); + + res->type =3D PCIM_ADDR_DEVRES_TYPE_REGION_RANGE_MAPPING; + res->bar =3D bar; + res->offset =3D offset; + res->len =3D len; + + ret =3D __pcim_request_region_range(pdev, bar, offset, len, name, 0); + if (ret !=3D 0) + goto err_region; + + res->baseaddr =3D pci_iomap_range(pdev, bar, offset, len); + if (!res->baseaddr) { + ret =3D -EINVAL; + goto err_iomap; + } + + devres_add(&pdev->dev, res); + return res->baseaddr; + +err_iomap: + __pcim_release_region_range(pdev, bar, offset, len); +err_region: + pcim_addr_devres_free(res); + + return IOMEM_ERR_PTR(ret); +} +EXPORT_SYMBOL(pcim_iomap_region_range); + +/** + * pcim_iounmap_region_range - Unmap and release a range within a PCI BAR + * @pdev: PCI device to operate on + * @bar: Index of BAR containing the range + * @offset: Offset from the begin of the BAR + * @len: Length in bytes for the mapping + * + * Unmaps and releases a memory area within the specified PCI BAR. + * + * This function may not be used to free only part of a range. Only use th= is + * function with the exact parameters you previously used successfully in + * pcim_iomap_region_range(). + */ +void pcim_iounmap_region_range(struct pci_dev *pdev, int bar, + unsigned long offset, unsigned long len) +{ + struct pcim_addr_devres res_searched; + pcim_addr_devres_clear(&res_searched); + + res_searched.type =3D PCIM_ADDR_DEVRES_TYPE_REGION_RANGE_MAPPING; + res_searched.bar =3D bar; + res_searched.offset =3D offset; + res_searched.len =3D len; + + devres_release(&pdev->dev, pcim_addr_resource_release, + pcim_addr_resources_match, &res_searched); +} +EXPORT_SYMBOL(pcim_iounmap_region_range); diff --git a/include/linux/pci.h b/include/linux/pci.h index a7cd31906547..764aef7023e8 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -2323,10 +2323,21 @@ static inline void pci_fixup_device(enum pci_fixup_= pass pass, void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxl= en); void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr); void __iomem * const *pcim_iomap_table(struct pci_dev *pdev); +void __iomem *pcim_iomap_region(struct pci_dev *pdev, int bar, const char = *name); +void pcim_iounmap_region(struct pci_dev *pdev, int bar); int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name); int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask, const char *name); void pcim_iounmap_regions(struct pci_dev *pdev, int mask); +int pcim_request_region(struct pci_dev *pdev, int bar, const char *res_nam= e); +void pcim_release_region(struct pci_dev *pdev, int bar); +void __iomem *pcim_iomap_range(struct pci_dev *pdev, int bar, + unsigned long offset, unsigned long len); +void __iomem *pcim_iomap_region_range(struct pci_dev *pdev, int bar, + unsigned long offset, unsigned long len, + const char *res_name); +void pcim_iounmap_region_range(struct pci_dev *pdev, int bar, + unsigned long offset, unsigned long len); =20 extern int pci_pci_problems; #define PCIPCI_FAIL 1 /* No PCI PCI DMA */ --=20 2.43.0 From nobody Sun Feb 8 03:11:43 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DC2AC6CDD8 for ; Fri, 1 Mar 2024 11:30:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292620; cv=none; b=L1jTsqACXhlcgSNdkyAiB6B/rypBaitW6q1lQvAPx+/FI4cKr4vNBqfPFhQqzwbqwakt/WF1q2/8UF+RKz+3UK+wAFZUP+/C6oSTy7lM3pcENeElDz9+PyU41cJCXvjGR15aXRltYni68wsusuL9ZEbdDf6oA82RAgUPX/O/Oyo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292620; c=relaxed/simple; bh=GMy3Qn2d2gF2LMVBACUDqhuteqT3p8D1gDWNKRnREb0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PKfstu7xTIG4aU7Moldj3r1rRu220N1tZJqWvTstR3BkiDs3qm+bOpU/+cZX8QtT05wYz8mzV/3zojJYlxNfr1j/8pEq7dLg8VzgrGVjYi5w0pHPguYPM/LSMuGPmpInXH9MW17PnhMFrOBcRiXDnWkxV5pIpZixQHrM0T0bGko= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=IlahilxM; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="IlahilxM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709292616; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xCFPJagLzKx22WqKKTHp8qRZXi4Io4yhhz4S1+ryYYo=; b=IlahilxM9IjrK5/SXSqMW8j2LRXtJ9K5uPyxD6yJJtzbUF2LUwO5gHoZLxrKAF8jAlAy6e RqJbyCTPixUPgUFxg0g6wnM1goGWjFXvAmUgKLXhYjkTC8DbM/9Qz1zkch3Es/heHpQ+kK lD7q+diJVb7LXgVUlq1gLOAdZ3TeCIM= Received: from mail-ua1-f71.google.com (mail-ua1-f71.google.com [209.85.222.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-298-SFgnWlWtM26_nt_YmW8sLg-1; Fri, 01 Mar 2024 06:30:15 -0500 X-MC-Unique: SFgnWlWtM26_nt_YmW8sLg-1 Received: by mail-ua1-f71.google.com with SMTP id a1e0cc1a2514c-7dae230b1b5so137873241.0 for ; Fri, 01 Mar 2024 03:30:15 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709292614; x=1709897414; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xCFPJagLzKx22WqKKTHp8qRZXi4Io4yhhz4S1+ryYYo=; b=sXuNb/1Ld+SVT+OeEEwe+Oz5iGrMipe/s9LxVnvPu2o1wjcm/I8OuAGDouo4MF+K/8 Lmh/M+8d/aeIcpGNwzwul1+hq6toK0MNFDPO7bvIAyiLdwUku48sWLxozkCSvvFvzD1j 5tpxheUniUwYf4fuz86IdrPqdHVY0axb8m3bDzOIMbG2IUMUUP0AuN18XIWr5G1lwOCD Ccy4fETYPmL3YzdYyiLbZqcHvClfkVrNy5lH46rBU0PlmhLTJ4DwrSnJk4ErF3TXDdx2 NHBq8ruTzGRde2UrBHMtb6Q/wURGAHMYsq97MtKVeUhLP/BCBKbs5ruHktw9s8tkFx6Y O2lg== X-Forwarded-Encrypted: i=1; AJvYcCXXEeEFYzeYV5KrG+Vkr87kwHX9XyZvMmUhx0sYLPfkehYNfvgvdVICGNjCq/pWhcjatUsmOVIbB4DK7RI4iLt2lCYPBox0MTxoVJBl X-Gm-Message-State: AOJu0YysolmrQ9fOaiwzzOYKaVKx133RaYh+IAh26n6mU+wZe+Ml2R+X owiQF9Rfz7n4StZO2aEMT79mzzb+0SenG3JoSlhnAkgl/5FDrwaTknJuu8ibJBeOfeeJpjgCuIG PgGNZC01cKge3Qd0tbhfc6lmyJqojKKtf5QF6x6FE0YeAOaZZhV5QpNAiM9R1dQ== X-Received: by 2002:a05:6102:2a44:b0:472:60f4:b7e4 with SMTP id gt4-20020a0561022a4400b0047260f4b7e4mr691230vsb.2.1709292614344; Fri, 01 Mar 2024 03:30:14 -0800 (PST) X-Google-Smtp-Source: AGHT+IFZ7tKzLQCVB9hTcVQJKnS8XGfAFUDMaRaJoN7pDCO81UnZvPFYgOSVp0LUiPtRvfviivVwUA== X-Received: by 2002:a05:6102:2a44:b0:472:60f4:b7e4 with SMTP id gt4-20020a0561022a4400b0047260f4b7e4mr691204vsb.2.1709292613769; Fri, 01 Mar 2024 03:30:13 -0800 (PST) Received: from pstanner-thinkpadt14sgen1.remote.csb (nat-pool-muc-t.redhat.com. [149.14.88.26]) by smtp.gmail.com with ESMTPSA id b1-20020ac86781000000b0042eb46d15bbsm1596239qtp.88.2024.03.01.03.30.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Mar 2024 03:30:13 -0800 (PST) From: Philipp Stanner To: Hans de Goede , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter , Bjorn Helgaas , Sam Ravnborg , dakr@redhat.com Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Philipp Stanner Subject: [PATCH v4 02/10] PCI: Deprecate iomap-table functions Date: Fri, 1 Mar 2024 12:29:50 +0100 Message-ID: <20240301112959.21947-3-pstanner@redhat.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240301112959.21947-1-pstanner@redhat.com> References: <20240301112959.21947-1-pstanner@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The old plural devres functions tie the PCI devres API to the iomap-table mechanism which unfortunately is not extensible. As the plural functions are almost never used with more than one bit set in their bit-mask, deprecating them and encouraging users to use the new singular functions instead is reasonable. Furthermore, to make the implementation more consistent and extensible, the plural functions should use the singular functions. Add new wrapper to request / release all BARs. Make the plural functions call into the singular functions. Mark the plural functions as deprecated. Remove as much of the iomap-table-mechanism as possible. Add comments describing the path towards a cleaned-up API. Signed-off-by: Philipp Stanner --- drivers/pci/devres.c | 374 +++++++++++++++++++++++++++++++++---------- drivers/pci/pci.c | 20 +++ drivers/pci/pci.h | 5 + include/linux/pci.h | 2 + 4 files changed, 318 insertions(+), 83 deletions(-) diff --git a/drivers/pci/devres.c b/drivers/pci/devres.c index 6a653e1a1acb..bc31e3a8cc04 100644 --- a/drivers/pci/devres.c +++ b/drivers/pci/devres.c @@ -4,15 +4,43 @@ #include "pci.h" =20 /* - * PCI iomap devres + * On the state of PCI's devres implementation: + * + * The older devres API for PCI has two significant problems: + * + * 1. It is very strongly tied to the statically allocated mapping table in + * struct pcim_iomap_devres below. This is mostly solved in the sense o= f the + * pcim_ functions in this file providing things like ranged mapping by + * bypassing this table, wheras the functions that were present in the = old + * API still enter the mapping addresses into the table for users of th= e old + * API. + * 2. The region-request-functions in pci.c do become managed IF the devic= e has + * been enabled with pcim_enable_device() instead of pci_enable_device(= ). + * This resulted in the API becoming inconsistent: Some functions have = an + * obviously managed counter-part (e.g., pci_iomap() <-> pcim_iomap()), + * whereas some don't and are never managed, while others don't and are + * _sometimes_ managed (e.g. pci_request_region()). + * Consequently, in the new API, region requests performed by the pcim_ + * functions are automatically cleaned up through the devres callback + * pcim_addr_resource_release(), while requests performed by + * pcim_enable_device() + pci_*region*() are automatically cleaned up + * through the for-loop in pcim_release(). + * + * TODO 1: + * Remove the legacy table entirely once all calls to pcim_iomap_table() in + * the kernel have been removed. + * + * TODO 2: + * Port everyone calling pcim_enable_device() + pci_*region*() to using the + * pcim_ functions. Then, remove all devres functionality from pci_*region= *() + * functions and remove the associated cleanups described above in point #= 2. */ -#define PCIM_IOMAP_MAX PCI_STD_NUM_BARS =20 /* * Legacy struct storing addresses to whole mapped BARs. */ struct pcim_iomap_devres { - void __iomem *table[PCIM_IOMAP_MAX]; + void __iomem *table[PCI_STD_NUM_BARS]; }; =20 enum pcim_addr_devres_type { @@ -373,6 +401,16 @@ static void pcim_release(struct device *gendev, void *= res) struct pci_devres *this =3D res; int i; =20 + /* + * This is legacy code. + * All regions requested by a pcim_ function do get released through + * pcim_addr_resource_release(). Thanks to the hybrid nature of the pci_ + * region-request functions, this for-loop has to release the regions + * if they have been requested by such a function. + * + * TODO: Remove this once all users of pcim_enable_device() PLUS + * pci-region-request-functions have been ported to pcim_ functions. + */ for (i =3D 0; i < DEVICE_COUNT_RESOURCE; i++) if (this->region_mask & (1 << i)) pci_release_region(dev, i); @@ -459,19 +497,21 @@ EXPORT_SYMBOL(pcim_pin_device); =20 static void pcim_iomap_release(struct device *gendev, void *res) { - struct pci_dev *dev =3D to_pci_dev(gendev); - struct pcim_iomap_devres *this =3D res; - int i; - - for (i =3D 0; i < PCIM_IOMAP_MAX; i++) - if (this->table[i]) - pci_iounmap(dev, this->table[i]); + /* + * Do nothing. This is legacy code. + * + * Cleanup of the mappings is now done directly through the callbacks + * registered when creating them. + */ } =20 /** - * pcim_iomap_table - access iomap allocation table + * pcim_iomap_table - access iomap allocation table (DEPRECATED) * @pdev: PCI device to access iomap table for * + * Returns: + * Const pointer to array of __iomem pointers on success NULL on failure. + * * Access iomap allocation table for @dev. If iomap table doesn't * exist and @pdev is managed, it will be allocated. All iomaps * recorded in the iomap table are automatically unmapped on driver @@ -480,6 +520,11 @@ static void pcim_iomap_release(struct device *gendev, = void *res) * This function might sleep when the table is first allocated but can * be safely called without context and guaranteed to succeed once * allocated. + * + * This function is DEPRECATED. Do not use it in new code. + * Instead, obtain a mapping's address directly from one of the pcim_* map= ping + * functions. For example: + * void __iomem *mappy =3D pcim_iomap(pdev, barnr, length); */ void __iomem * const *pcim_iomap_table(struct pci_dev *pdev) { @@ -498,27 +543,114 @@ void __iomem * const *pcim_iomap_table(struct pci_de= v *pdev) } EXPORT_SYMBOL(pcim_iomap_table); =20 +/* + * Fill the legacy mapping-table, so that drivers using the old API + * can still get a BAR's mapping address through pcim_iomap_table(). + */ +static int pcim_add_mapping_to_legacy_table(struct pci_dev *pdev, + void __iomem *mapping, short bar) +{ + void __iomem **legacy_iomap_table; + + if (bar >=3D PCI_STD_NUM_BARS) + return -EINVAL; + + legacy_iomap_table =3D (void __iomem **)pcim_iomap_table(pdev); + if (!legacy_iomap_table) + return -ENOMEM; + + /* The legacy mechanism doesn't allow for duplicate mappings. */ + WARN_ON(legacy_iomap_table[bar]); + + legacy_iomap_table[bar] =3D mapping; + + return 0; +} + +/* + * Removes a mapping. The table only contains whole-bar-mappings, so this = will + * never interfere with ranged mappings. + */ +static void pcim_remove_mapping_from_legacy_table(struct pci_dev *pdev, + void __iomem *addr) +{ + short bar; + void __iomem **legacy_iomap_table; + + legacy_iomap_table =3D (void __iomem **)pcim_iomap_table(pdev); + if (!legacy_iomap_table) + return; + + for (bar =3D 0; bar < PCI_STD_NUM_BARS; bar++) { + if (legacy_iomap_table[bar] =3D=3D addr) { + legacy_iomap_table[bar] =3D NULL; + return; + } + } +} + +/* + * The same as pcim_remove_mapping_from_legacy_table(), but identifies the + * mapping by its BAR index. + */ +static void pcim_remove_bar_from_legacy_table(struct pci_dev *pdev, short = bar) +{ + void __iomem **legacy_iomap_table; + + if (bar >=3D PCI_STD_NUM_BARS) + return; + + legacy_iomap_table =3D (void __iomem **)pcim_iomap_table(pdev); + if (!legacy_iomap_table) + return; + + legacy_iomap_table[bar] =3D NULL; +} + /** * pcim_iomap - Managed pcim_iomap() * @pdev: PCI device to iomap for * @bar: BAR to iomap * @maxlen: Maximum length of iomap * - * Managed pci_iomap(). Map is automatically unmapped on driver - * detach. + * Returns: __iomem pointer on success, NULL on failure. + * + * Managed pci_iomap(). Map is automatically unmapped on driver detach. If + * desired, unmap manually only with pcim_iounmap(). + * + * This SHOULD only be used once per BAR. + * + * NOTE: + * Contrary to the other pcim_* functions, this function does not return an + * IOMEM_ERR_PTR() on failure, but a simple NULL. This is done for backwar= ds + * compatibility. */ void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxl= en) { - void __iomem **tbl; - - BUG_ON(bar >=3D PCIM_IOMAP_MAX); + void __iomem *mapping; + struct pcim_addr_devres *res; =20 - tbl =3D (void __iomem **)pcim_iomap_table(pdev); - if (!tbl || tbl[bar]) /* duplicate mappings not allowed */ + res =3D pcim_addr_devres_alloc(pdev); + if (!res) return NULL; + res->type =3D PCIM_ADDR_DEVRES_TYPE_MAPPING; + + mapping =3D pci_iomap(pdev, bar, maxlen); + if (!mapping) + goto err_iomap; + res->baseaddr =3D mapping; + + if (pcim_add_mapping_to_legacy_table(pdev, mapping, bar) !=3D 0) + goto err_table; =20 - tbl[bar] =3D pci_iomap(pdev, bar, maxlen); - return tbl[bar]; + devres_add(&pdev->dev, res); + return mapping; + +err_table: + pci_iounmap(pdev, mapping); +err_iomap: + pcim_addr_devres_free(res); + return NULL; } EXPORT_SYMBOL(pcim_iomap); =20 @@ -527,23 +659,24 @@ EXPORT_SYMBOL(pcim_iomap); * @pdev: PCI device to iounmap for * @addr: Address to unmap * - * Managed pci_iounmap(). @addr must have been mapped using pcim_iomap(). + * Managed pci_iounmap(). @addr must have been mapped using pcim_iomap() or + * pcim_iomap_range(). */ void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr) { - void __iomem **tbl; - int i; + struct pcim_addr_devres res_searched; =20 - pci_iounmap(pdev, addr); + pcim_addr_devres_clear(&res_searched); + res_searched.type =3D PCIM_ADDR_DEVRES_TYPE_MAPPING; + res_searched.baseaddr =3D addr; =20 - tbl =3D (void __iomem **)pcim_iomap_table(pdev); - BUG_ON(!tbl); + if (devres_release(&pdev->dev, pcim_addr_resource_release, + pcim_addr_resources_match, &res_searched) !=3D 0) { + /* Doesn't exist. User passed nonsense. */ + return; + } =20 - for (i =3D 0; i < PCIM_IOMAP_MAX; i++) - if (tbl[i] =3D=3D addr) { - tbl[i] =3D NULL; - return; - } + pcim_remove_mapping_from_legacy_table(pdev, addr); } EXPORT_SYMBOL(pcim_iounmap); =20 @@ -613,106 +746,181 @@ void pcim_iounmap_region(struct pci_dev *pdev, int = bar) } EXPORT_SYMBOL(pcim_iounmap_region); =20 +static inline bool mask_contains_bar(int mask, int bar) +{ + return mask & BIT(bar); +} + /** - * pcim_iomap_regions - Request and iomap PCI BARs + * pcim_iomap_regions - Request and iomap PCI BARs (DEPRECATED) * @pdev: PCI device to map IO resources for * @mask: Mask of BARs to request and iomap * @name: Name associated with the requests * + * Returns: 0 on success, negative error code on failure. + * * Request and iomap regions specified by @mask. + * + * This function is DEPRECATED. Don't use it in new code. + * Use pcim_iomap_region() instead. */ int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name) { - void __iomem * const *iomap; - int i, rc; + int ret; + short bar; + void __iomem *mapping; =20 - iomap =3D pcim_iomap_table(pdev); - if (!iomap) - return -ENOMEM; + for (bar =3D 0; bar < DEVICE_COUNT_RESOURCE; bar++) { + if (!mask_contains_bar(mask, bar)) + continue; =20 - for (i =3D 0; i < DEVICE_COUNT_RESOURCE; i++) { - unsigned long len; + mapping =3D pcim_iomap_region(pdev, bar, name); + if (IS_ERR(mapping)) { + ret =3D PTR_ERR(mapping); + goto err; + } + ret =3D pcim_add_mapping_to_legacy_table(pdev, mapping, bar); + if (ret !=3D 0) + goto err; + } =20 - if (!(mask & (1 << i))) - continue; + return 0; =20 - rc =3D -EINVAL; - len =3D pci_resource_len(pdev, i); - if (!len) - goto err_inval; +err: + while (--bar >=3D 0) { + pcim_iounmap_region(pdev, bar); + pcim_remove_bar_from_legacy_table(pdev, bar); + } =20 - rc =3D pci_request_region(pdev, i, name); - if (rc) - goto err_inval; + return ret; +} +EXPORT_SYMBOL(pcim_iomap_regions); =20 - rc =3D -ENOMEM; - if (!pcim_iomap(pdev, i, 0)) - goto err_region; +/** + * pcim_release_all_regions - Release all regions of a PCI-device + * @pdev: the PCI device + * + * Will release all regions previously requested through pcim_request_regi= on() + * or pcim_request_all_regions(). + * + * Can be called from any context, i.e., not necessarily as a counterpart = to + * pcim_request_all_regions(). + */ +void pcim_release_all_regions(struct pci_dev *pdev) +{ + short bar; + + for (bar =3D 0; bar < PCI_STD_NUM_BARS; bar++) + pcim_release_region(pdev, bar); +} +EXPORT_SYMBOL(pcim_release_all_regions); + +/** + * pcim_request_all_regions - Request all regions + * @pdev: PCI device to map IO resources for + * @name: name associated with the request + * + * Returns: 0 on success, negative error code on failure. + * + * Requested regions will automatically be released at driver detach. If d= esired, + * release individual regions with pcim_release_region() or all of them at= once + * with pcim_release_all_regions(). + */ +int pcim_request_all_regions(struct pci_dev *pdev, const char *name) +{ + int ret; + short bar; + + for (bar =3D 0; bar < PCI_STD_NUM_BARS; bar++) { + ret =3D pcim_request_region(pdev, bar, name); + if (ret !=3D 0) + goto err; } =20 return 0; =20 - err_region: - pci_release_region(pdev, i); - err_inval: - while (--i >=3D 0) { - if (!(mask & (1 << i))) - continue; - pcim_iounmap(pdev, iomap[i]); - pci_release_region(pdev, i); - } +err: + pcim_release_all_regions(pdev); =20 - return rc; + return ret; } -EXPORT_SYMBOL(pcim_iomap_regions); +EXPORT_SYMBOL(pcim_request_all_regions); =20 /** - * pcim_iomap_regions_request_all - Request all BARs and iomap specified o= nes + * pcim_iomap_regions_request_all - Request all BARs and iomap specified o= nes (DEPRECATED) * @pdev: PCI device to map IO resources for * @mask: Mask of BARs to iomap * @name: Name associated with the requests * + * Returns: 0 on success, negative error code on failure. + * * Request all PCI BARs and iomap regions specified by @mask. + * + * To release these resources manually, call pcim_release_region() for the + * regions and pcim_iounmap() for the mappings. + * + * This function is DEPRECATED. Don't use it in new code. + * Use pcim_request_all_regions() + pcim_iomap*() instead. */ int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask, const char *name) { - int request_mask =3D ((1 << 6) - 1) & ~mask; - int rc; + short bar; + int ret; + void __iomem **legacy_iomap_table; + + ret =3D pcim_request_all_regions(pdev, name); + if (ret !=3D 0) + return ret; =20 - rc =3D pci_request_selected_regions(pdev, request_mask, name); - if (rc) - return rc; + for (bar =3D 0; bar < PCI_STD_NUM_BARS; bar++) { + if (!mask_contains_bar(mask, bar)) + continue; + if (!pcim_iomap(pdev, bar, 0)) + goto err; + } =20 - rc =3D pcim_iomap_regions(pdev, mask, name); - if (rc) - pci_release_selected_regions(pdev, request_mask); - return rc; + return 0; + +err: + /* + * Here it gets tricky: pcim_iomap() above has most likely + * failed because it got an OOM when trying to create the + * legacy-table. + * We check here if that has happened. If not, pcim_iomap() + * must have failed because of EINVAL. + */ + legacy_iomap_table =3D (void __iomem **)pcim_iomap_table(pdev); + ret =3D legacy_iomap_table ? -EINVAL : -ENOMEM; + + while (--bar >=3D 0) + pcim_iounmap(pdev, legacy_iomap_table[bar]); + + pcim_release_all_regions(pdev); + + return ret; } EXPORT_SYMBOL(pcim_iomap_regions_request_all); =20 /** - * pcim_iounmap_regions - Unmap and release PCI BARs + * pcim_iounmap_regions - Unmap and release PCI BARs (DEPRECATED) * @pdev: PCI device to map IO resources for * @mask: Mask of BARs to unmap and release * * Unmap and release regions specified by @mask. + * + * This function is DEPRECATED. Don't use it in new code. */ void pcim_iounmap_regions(struct pci_dev *pdev, int mask) { - void __iomem * const *iomap; - int i; - - iomap =3D pcim_iomap_table(pdev); - if (!iomap) - return; + short bar; =20 - for (i =3D 0; i < PCIM_IOMAP_MAX; i++) { - if (!(mask & (1 << i))) + for (bar =3D 0; bar < PCI_STD_NUM_BARS; bar++) { + if (!mask_contains_bar(mask, bar)) continue; =20 - pcim_iounmap(pdev, iomap[i]); - pci_release_region(pdev, i); + pcim_iounmap_region(pdev, bar); + pcim_remove_bar_from_legacy_table(pdev, bar); } } EXPORT_SYMBOL(pcim_iounmap_regions); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index cfc5b84dc9c9..e01e316de1c3 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3864,6 +3864,16 @@ void pci_release_region(struct pci_dev *pdev, int ba= r) release_mem_region(pci_resource_start(pdev, bar), pci_resource_len(pdev, bar)); =20 + /* + * This devres utility makes this function sometimes managed + * (when pcim_enable_device() has been called before). + * This is bad because it conflicts with the pcim_ functions being + * exclusively responsible for managed pci. Its "sometimes yes, sometimes + * no" nature can cause bugs. + * + * TODO: Remove this once all users that use pcim_enable_device() PLUS + * a region request function have been ported to using pcim_ functions. + */ dr =3D find_pci_dr(pdev); if (dr) dr->region_mask &=3D ~(1 << bar); @@ -3908,6 +3918,16 @@ static int __pci_request_region(struct pci_dev *pdev= , int bar, goto err_out; } =20 + /* + * This devres utility makes this function sometimes managed + * (when pcim_enable_device() has been called before). + * This is bad because it conflicts with the pcim_ functions being + * exclusively responsible for managed pci. Its "sometimes yes, sometimes + * no" nature can cause bugs. + * + * TODO: Remove this once all users that use pcim_enable_device() PLUS + * a region request function have been ported to using pcim_ functions. + */ dr =3D find_pci_dr(pdev); if (dr) dr->region_mask |=3D 1 << bar; diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index b217e74966eb..9d334bf4cbc4 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -830,6 +830,11 @@ struct pci_devres { unsigned int orig_intx:1; unsigned int restore_intx:1; unsigned int mwi:1; + + /* + * TODO: remove the region_mask once everyone calling + * pcim_enable_device() + pci_*region*() is ported to pcim_ functions. + */ u32 region_mask; }; =20 diff --git a/include/linux/pci.h b/include/linux/pci.h index 764aef7023e8..5d134e833546 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -2331,6 +2331,8 @@ int pcim_iomap_regions_request_all(struct pci_dev *pd= ev, int mask, void pcim_iounmap_regions(struct pci_dev *pdev, int mask); int pcim_request_region(struct pci_dev *pdev, int bar, const char *res_nam= e); void pcim_release_region(struct pci_dev *pdev, int bar); +void pcim_release_all_regions(struct pci_dev *pdev); +int pcim_request_all_regions(struct pci_dev *pdev, const char *name); void __iomem *pcim_iomap_range(struct pci_dev *pdev, int bar, unsigned long offset, unsigned long len); void __iomem *pcim_iomap_region_range(struct pci_dev *pdev, int bar, --=20 2.43.0 From nobody Sun Feb 8 03:11:43 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 245FB6E2B3 for ; Fri, 1 Mar 2024 11:30:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292625; cv=none; b=PhtsGx3kYfijBpMchEz6Ehopr+kWcZ/HTPu/oBVkhJar0NDGOnv03dRgE09WmrNuMkBnLHtyybIUMyy53eTCT+ptGscLnG0dVDdbXpIpPXPuDR0nGrbnJ2ZFlkRp18KEKV8KcbXIfdVR0rj6haRREUW8/EbTuGiTWxSrl2AcXa8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292625; c=relaxed/simple; bh=/AwlCpVAO2oHu0uUrBvoYcwSq48osNascDYif54npNs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WQprADlOBbYNCGPvEjXGz3ixhuFbX0f5SP+5ExVTzQwHE3a1wkwM7OIkW80sKB3vGcpkI0rbHsUFu4/X6SJ4kZ4QbwzX047bczOl9hjQWjKFQDDGSgguKS8C5VmFX7NaGMFVIBDr5qjdKCn1uhXIvbkhGivQDVzJshjfzs4veng= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=d7LeEQPE; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="d7LeEQPE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709292623; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=x1vv8w5iQVUitgG0ysLWn1q06xCEf1/TkXPRyfO6KrE=; b=d7LeEQPENpPsI7mo609neFScX83J074D4aE42WjRJgbQtpTrr71J7WrX+He9VbXJpixJa2 rEUVWi0Fq+Ze6YBIGAAuudWC5e/851Jp+l/8bVQBdBVlG1JDPrKgghaoPFdPieFM8IcjwO vKGO9B6YEqXIGMztC3wNlQ4iCZjOQqg= Received: from mail-ot1-f72.google.com (mail-ot1-f72.google.com [209.85.210.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-414-puWEIfgnMsa8g3qqI_DHvw-1; Fri, 01 Mar 2024 06:30:22 -0500 X-MC-Unique: puWEIfgnMsa8g3qqI_DHvw-1 Received: by mail-ot1-f72.google.com with SMTP id 46e09a7af769-6dde25ac92fso993590a34.0 for ; Fri, 01 Mar 2024 03:30:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709292621; x=1709897421; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=x1vv8w5iQVUitgG0ysLWn1q06xCEf1/TkXPRyfO6KrE=; b=scLvjKbU6a2zverrwH0sTDTqdVD5tBmINaNxLqx/Vxqi1hSup8GyjjjACyeUr9dbSQ K3I9+0oTx2axLHsICKEHJ5fEuFl0ymmGtovZ9Mf3jfjG/OryuZQ1DzzM2YRxmFWt/VU3 VIsJQoxe71AR6RDA8zJnFcDXrSZemKLYXDPgXoKXRoip0yP83RDvi7whdcAWnuQvsuTq Maq5j9b1D6XuLIuolpaXPOfxgWPoTD/H2ZRgd8emUPHvHz1swiSZ/hbXV5GpaWSCNXTk Tj+WcKg3aSvr0bapaLSExfIFcWpC9NsmUZ72xOAsDO8fARsasmi5h9awO0yGeU9OB0Zm dSTg== X-Forwarded-Encrypted: i=1; AJvYcCWDVq3I0+wmOrHkbJ4ls6GOIN37Nxc3HYPDjOzIsuJc3/BodjlU3XYuVLS9otJcpuz+uKamI5TOu40vWgfrdznIWT30yZxaDeg+XLpT X-Gm-Message-State: AOJu0YzDDftJygCNZ6DnLhmyaN5mJBq9oLCYmPMzQMhqFhI0IVrdutg8 CntY2CZEjcBfJSW4IxfnjG+RUhguubi15kjTwyf8OCixxOw43vxc7UwIYb3dkYs6sQWwLSYhVvx ZC46wjk9Wqy88JI5DhpJK9eBKb6t40UwqJUFf+D5jF4fsdLddUt8HSCBQaz0O2w== X-Received: by 2002:a05:6870:1b89:b0:21e:be91:ae48 with SMTP id hm9-20020a0568701b8900b0021ebe91ae48mr1405857oab.1.1709292616340; Fri, 01 Mar 2024 03:30:16 -0800 (PST) X-Google-Smtp-Source: AGHT+IEbFvAujWEWv1z6YVxUiGVIfr1SqZdnci7z1l0hJ/GNeV3/nbcF6AczulXgObryYZMXAxSD7g== X-Received: by 2002:a05:6870:1b89:b0:21e:be91:ae48 with SMTP id hm9-20020a0568701b8900b0021ebe91ae48mr1405843oab.1.1709292616009; Fri, 01 Mar 2024 03:30:16 -0800 (PST) Received: from pstanner-thinkpadt14sgen1.remote.csb (nat-pool-muc-t.redhat.com. [149.14.88.26]) by smtp.gmail.com with ESMTPSA id b1-20020ac86781000000b0042eb46d15bbsm1596239qtp.88.2024.03.01.03.30.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Mar 2024 03:30:15 -0800 (PST) From: Philipp Stanner To: Hans de Goede , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter , Bjorn Helgaas , Sam Ravnborg , dakr@redhat.com Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Philipp Stanner Subject: [PATCH v4 03/10] PCI: Warn users about complicated devres nature Date: Fri, 1 Mar 2024 12:29:51 +0100 Message-ID: <20240301112959.21947-4-pstanner@redhat.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240301112959.21947-1-pstanner@redhat.com> References: <20240301112959.21947-1-pstanner@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The PCI region-request functions become managed functions when pcim_enable_device() has been called previously instead of pci_enable_device(). This has already caused bugs by confusing users, who came to believe that all pci functions, such as pci_iomap_range(), suddenly are managed that way. This is not the case. Add comments to the relevant functions' docstrings that warn users about this behavior. Signed-off-by: Philipp Stanner --- drivers/pci/iomap.c | 18 ++++++++++++++ drivers/pci/pci.c | 60 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/drivers/pci/iomap.c b/drivers/pci/iomap.c index c9725428e387..ea3b9842132a 100644 --- a/drivers/pci/iomap.c +++ b/drivers/pci/iomap.c @@ -23,6 +23,11 @@ * * @maxlen specifies the maximum length to map. If you want to get access = to * the complete BAR from offset to the end, pass %0 here. + * + * NOTE: + * This function is never managed, even if you initialized with + * pcim_enable_device(). + * If you need automatic cleanup, use pcim_iomap_range(). * */ void __iomem *pci_iomap_range(struct pci_dev *dev, int bar, @@ -63,6 +68,10 @@ EXPORT_SYMBOL(pci_iomap_range); * * @maxlen specifies the maximum length to map. If you want to get access = to * the complete BAR from offset to the end, pass %0 here. + * + * NOTE: + * This function is never managed, even if you initialized with + * pcim_enable_device(). * */ void __iomem *pci_iomap_wc_range(struct pci_dev *dev, int bar, @@ -106,6 +115,11 @@ EXPORT_SYMBOL_GPL(pci_iomap_wc_range); * * @maxlen specifies the maximum length to map. If you want to get access = to * the complete BAR without checking for its length first, pass %0 here. + * + * NOTE: + * This function is never managed, even if you initialized with + * pcim_enable_device(). + * If you need automatic cleanup, use pcim_iomap(). * */ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) { @@ -127,6 +141,10 @@ EXPORT_SYMBOL(pci_iomap); * * @maxlen specifies the maximum length to map. If you want to get access = to * the complete BAR without checking for its length first, pass %0 here. + * + * NOTE: + * This function is never managed, even if you initialized with + * pcim_enable_device(). * */ void __iomem *pci_iomap_wc(struct pci_dev *dev, int bar, unsigned long max= len) { diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e01e316de1c3..26179611587b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3887,6 +3887,8 @@ EXPORT_SYMBOL(pci_release_region); * @res_name: Name to be associated with resource. * @exclusive: whether the region access is exclusive or not * + * Returns: 0 on success, negative error code on failure. + * * Mark the PCI region associated with PCI device @pdev BAR @bar as * being reserved by owner @res_name. Do not access any * address inside the PCI regions unless this call returns @@ -3898,6 +3900,13 @@ EXPORT_SYMBOL(pci_release_region); * * Returns 0 on success, or %EBUSY on error. A warning * message is also printed on failure. + * + * NOTE: + * This is a "hybrid" function: Its normally unmanaged, but becomes managed + * when pcim_enable_device() has been called in advance. + * This hybrid feature is DEPRECATED! If you need to implement a new pci + * function that does automatic cleanup, write a new pcim_* function that = uses + * devres directly. */ static int __pci_request_region(struct pci_dev *pdev, int bar, const char *res_name, int exclusive) @@ -3946,6 +3955,8 @@ static int __pci_request_region(struct pci_dev *pdev,= int bar, * @bar: BAR to be reserved * @res_name: Name to be associated with resource * + * Returns: 0 on success, negative error code on failure. + * * Mark the PCI region associated with PCI device @pdev BAR @bar as * being reserved by owner @res_name. Do not access any * address inside the PCI regions unless this call returns @@ -3953,6 +3964,12 @@ static int __pci_request_region(struct pci_dev *pdev= , int bar, * * Returns 0 on success, or %EBUSY on error. A warning * message is also printed on failure. + * + * NOTE: + * This is a "hybrid" function: Its normally unmanaged, but becomes managed + * when pcim_enable_device() has been called in advance. + * This hybrid feature is DEPRECATED! If you want managed cleanup, use the + * pcim_* functions instead. */ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) { @@ -3978,6 +3995,13 @@ void pci_release_selected_regions(struct pci_dev *pd= ev, int bars) } EXPORT_SYMBOL(pci_release_selected_regions); =20 +/* + * NOTE: + * This is a "hybrid" function: Its normally unmanaged, but becomes managed + * when pcim_enable_device() has been called in advance. + * This hybrid feature is DEPRECATED! If you want managed cleanup, use the + * pcim_* functions instead. + */ static int __pci_request_selected_regions(struct pci_dev *pdev, int bars, const char *res_name, int excl) { @@ -4003,6 +4027,14 @@ static int __pci_request_selected_regions(struct pci= _dev *pdev, int bars, * @pdev: PCI device whose resources are to be reserved * @bars: Bitmask of BARs to be requested * @res_name: Name to be associated with resource + * + * Returns: 0 on success, negative error code on failure. + * + * NOTE: + * This is a "hybrid" function: Its normally unmanaged, but becomes managed + * when pcim_enable_device() has been called in advance. + * This hybrid feature is DEPRECATED! If you want managed cleanup, use the + * pcim_* functions instead. */ int pci_request_selected_regions(struct pci_dev *pdev, int bars, const char *res_name) @@ -4011,6 +4043,20 @@ int pci_request_selected_regions(struct pci_dev *pde= v, int bars, } EXPORT_SYMBOL(pci_request_selected_regions); =20 +/** + * pci_request_selected_regions_exclusive - Request regions exclusively + * @pdev: PCI device to request regions from + * @bars: bit mask of bars to request + * @res_name: name to be associated with the requests + * + * Returns: 0 on success, negative error code on failure. + * + * NOTE: + * This is a "hybrid" function: Its normally unmanaged, but becomes managed + * when pcim_enable_device() has been called in advance. + * This hybrid feature is DEPRECATED! If you want managed cleanup, use the + * pcim_* functions instead. + */ int pci_request_selected_regions_exclusive(struct pci_dev *pdev, int bars, const char *res_name) { @@ -4028,7 +4074,6 @@ EXPORT_SYMBOL(pci_request_selected_regions_exclusive); * successful call to pci_request_regions(). Call this function only * after all use of the PCI regions has ceased. */ - void pci_release_regions(struct pci_dev *pdev) { pci_release_selected_regions(pdev, (1 << PCI_STD_NUM_BARS) - 1); @@ -4060,6 +4105,8 @@ EXPORT_SYMBOL(pci_request_regions); * @pdev: PCI device whose resources are to be reserved * @res_name: Name to be associated with resource. * + * Returns: 0 on success, negative error code on failure. + * * Mark all PCI regions associated with PCI device @pdev as being reserved * by owner @res_name. Do not access any address inside the PCI regions * unless this call returns successfully. @@ -4069,6 +4116,12 @@ EXPORT_SYMBOL(pci_request_regions); * * Returns 0 on success, or %EBUSY on error. A warning message is also * printed on failure. + * + * NOTE: + * This is a "hybrid" function: Its normally unmanaged, but becomes managed + * when pcim_enable_device() has been called in advance. + * This hybrid feature is DEPRECATED! If you want managed cleanup, use the + * pcim_* functions instead. */ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_na= me) { @@ -4400,6 +4453,11 @@ void pci_disable_parity(struct pci_dev *dev) * @enable: boolean: whether to enable or disable PCI INTx * * Enables/disables PCI INTx for device @pdev + * + * NOTE: + * This is a "hybrid" function: Its normally unmanaged, but becomes managed + * when pcim_enable_device() has been called in advance. + * This hybrid feature is DEPRECATED! */ void pci_intx(struct pci_dev *pdev, int enable) { --=20 2.43.0 From nobody Sun Feb 8 03:11:43 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 42F066D519 for ; Fri, 1 Mar 2024 11:30:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292623; cv=none; b=hum3eqoDCDM1EgXFbTRzifA5lwbfutXAM6desD+gIO3MGlcFKHapaWzjGq+Wvgfd6vEHuJErCX5r+2B366uhjONxKuLte/9ZZCTwhWS2rbl3fNxSsZ0Vq/cq82hqHAhsG1OFEHY97+0i3wcQakY8mCkHu5m6O2ifjVTeqj7Ij6E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292623; c=relaxed/simple; bh=dBpZAY4G6Rr00NPdO0HEOlJV6ToWk/vij/dkGBAi4nE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nvO7weA1ZwWGWZ15pDM71+xpQCu3wall7VGfdGVlHGr2UwCIl33C4XQGQP312w9JRNHNjWmdros4hIEdrp4NwrwFdXhwlPTrqQ+AYlvbYi4Dn/eKLmKesDbqFFXbZxodXvJXbTy7XjEa3bCKvoHfHZ1LeCCSz2MGqLICvG7wcCA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=FZK6RSg0; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="FZK6RSg0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709292620; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=01p8tyKoJsE6IcXs1ENkYsvv8j7qWZ5JcxE7CS3OF90=; b=FZK6RSg0fNIWuA3046Zvr/R/DTpCEYVhDwZoo2bmN+r6xFZT1FMcJo6XHduThmMoTUW2FE 356m8CUtZcvHncliE6sUtJG2y7s+v9hBLZVly5Ih2gQSijohPf8lYkheqCQSe+XxPI9CeH NScLaluoLJFX7JJOXMITqIOqMdCS+4Y= Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-638-RYNuJgVWM7-yiKZJ9KKO5w-1; Fri, 01 Mar 2024 06:30:19 -0500 X-MC-Unique: RYNuJgVWM7-yiKZJ9KKO5w-1 Received: by mail-qk1-f200.google.com with SMTP id af79cd13be357-7830635331bso65174785a.1 for ; Fri, 01 Mar 2024 03:30:19 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709292618; x=1709897418; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=01p8tyKoJsE6IcXs1ENkYsvv8j7qWZ5JcxE7CS3OF90=; b=H3xUny99BLGvE+EnJgObN3NcssrVorvWcgTU1b/Io0jJBSgEctIPGUaOdIyFoCEx+m wlv7u007KNL+m1nVB1M7PiPEUZpLSfasdPGefQ+CRsIIi0mQ8DtSlBD43E2vsvRihrqZ alJe4S6T8mvn1OAClNaQZUBICEOJhVJXP3d1hmmPWCRZbo8dill4F5afi/GBWbyCwqua onYnUKNfltkmCxWZ6WwcfSYILmasjkQ/I6BttMVl0pWuXmSuVD9rzDG2Zn3VHoD1S5EB gncxDAbQKhEMeblmO7xbJfn4eebVUhJwk2JwsZ42aGW9EuqibxYONInQYwBlpM0zkUrB U+wg== X-Forwarded-Encrypted: i=1; AJvYcCUK0vwh7x3/rv2lz/sp4g/SCtVl9MvmX4mxHiFHWpbYbMKi+E0YPwjzU4VeWR/m5RPXh46zbmjAyJ0SXFsgQt8HoC0A/AtUt4cLoy1u X-Gm-Message-State: AOJu0Yw6D5GBS+pHK+l+eVghAoREIfOnrWwhBN0mUQ9aVXh9Q5LDNYy/ kMkHgl1pnzAQb4dM6zXyzrgH/wxu2dhIvj3bxklvzGshvxeaQIimO9SYY4pkYLW/dpw9H2nY2wI XIy0hjp5j3T3Z0Qf7Bj88D5Rnm02iFjONwo+ZJLIhTCsIWwC9EwetgbHVTKRh2A== X-Received: by 2002:a05:622a:1a03:b0:42e:b8da:9f62 with SMTP id f3-20020a05622a1a0300b0042eb8da9f62mr1316814qtb.4.1709292618494; Fri, 01 Mar 2024 03:30:18 -0800 (PST) X-Google-Smtp-Source: AGHT+IFQw2pD+Wo/GKiG19WPn8v3+gPfSTvvT8b89owjce4fj65GgvIEE3cXUI2Nli8KWBwmgJhdYg== X-Received: by 2002:a05:622a:1a03:b0:42e:b8da:9f62 with SMTP id f3-20020a05622a1a0300b0042eb8da9f62mr1316788qtb.4.1709292618065; Fri, 01 Mar 2024 03:30:18 -0800 (PST) Received: from pstanner-thinkpadt14sgen1.remote.csb (nat-pool-muc-t.redhat.com. [149.14.88.26]) by smtp.gmail.com with ESMTPSA id b1-20020ac86781000000b0042eb46d15bbsm1596239qtp.88.2024.03.01.03.30.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Mar 2024 03:30:17 -0800 (PST) From: Philipp Stanner To: Hans de Goede , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter , Bjorn Helgaas , Sam Ravnborg , dakr@redhat.com Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Philipp Stanner Subject: [PATCH v4 04/10] PCI: Make devres region requests consistent Date: Fri, 1 Mar 2024 12:29:52 +0100 Message-ID: <20240301112959.21947-5-pstanner@redhat.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240301112959.21947-1-pstanner@redhat.com> References: <20240301112959.21947-1-pstanner@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now that pure managed region request functions are available, the implementation of the hybrid-functions which are only sometimes managed can be made more consistent and readable by wrapping those always-managed functions. Implement a new pcim_ function for exclusively requested regions. Have the pci_request / release functions call their pcim_ counterparts. Remove the now surplus region_mask from struct pci_devres. Signed-off-by: Philipp Stanner --- drivers/pci/devres.c | 49 ++++++++++++++++++++++--------------------- drivers/pci/pci.c | 50 +++++++++++++++----------------------------- drivers/pci/pci.h | 6 ------ include/linux/pci.h | 1 + 4 files changed, 43 insertions(+), 63 deletions(-) diff --git a/drivers/pci/devres.c b/drivers/pci/devres.c index bc31e3a8cc04..03662760d629 100644 --- a/drivers/pci/devres.c +++ b/drivers/pci/devres.c @@ -22,18 +22,15 @@ * _sometimes_ managed (e.g. pci_request_region()). * Consequently, in the new API, region requests performed by the pcim_ * functions are automatically cleaned up through the devres callback - * pcim_addr_resource_release(), while requests performed by - * pcim_enable_device() + pci_*region*() are automatically cleaned up - * through the for-loop in pcim_release(). + * pcim_addr_resource_release(). + * Users utilizing pcim_enable_device() + pci_*region*() are redirected= in + * pci.c to the managed functions here in this file. This isn't exactly + * perfect, but the only alternative way would be to port ALL drivers u= sing + * said combination to pcim_ functions. * - * TODO 1: + * TODO: * Remove the legacy table entirely once all calls to pcim_iomap_table() in * the kernel have been removed. - * - * TODO 2: - * Port everyone calling pcim_enable_device() + pci_*region*() to using the - * pcim_ functions. Then, remove all devres functionality from pci_*region= *() - * functions and remove the associated cleanups described above in point #= 2. */ =20 /* @@ -399,21 +396,6 @@ static void pcim_release(struct device *gendev, void *= res) { struct pci_dev *dev =3D to_pci_dev(gendev); struct pci_devres *this =3D res; - int i; - - /* - * This is legacy code. - * All regions requested by a pcim_ function do get released through - * pcim_addr_resource_release(). Thanks to the hybrid nature of the pci_ - * region-request functions, this for-loop has to release the regions - * if they have been requested by such a function. - * - * TODO: Remove this once all users of pcim_enable_device() PLUS - * pci-region-request-functions have been ported to pcim_ functions. - */ - for (i =3D 0; i < DEVICE_COUNT_RESOURCE; i++) - if (this->region_mask & (1 << i)) - pci_release_region(dev, i); =20 if (this->mwi) pci_clear_mwi(dev); @@ -966,6 +948,25 @@ int pcim_request_region(struct pci_dev *pdev, int bar,= const char *name) } EXPORT_SYMBOL(pcim_request_region); =20 +/** + * pcim_request_region_exclusive - Request a PCI BAR exclusively + * @pdev: PCI device to requestion region for + * @bar: Index of BAR to request + * @name: Name associated with the request + * + * Returns: 0 on success, a negative error code on failure. + * + * Request region specified by @bar exclusively. + * + * The region will automatically be released on driver detach. If desired, + * release manually only with pcim_release_region(). + */ +int pcim_request_region_exclusive(struct pci_dev *pdev, int bar, const cha= r *name) +{ + return _pcim_request_region(pdev, bar, name, IORESOURCE_EXCLUSIVE); +} +EXPORT_SYMBOL(pcim_request_region_exclusive); + /** * pcim_release_region - Release a PCI BAR * @pdev: PCI device to operate on diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 26179611587b..9ff52e840d9e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3853,7 +3853,15 @@ EXPORT_SYMBOL(pci_enable_atomic_ops_to_root); */ void pci_release_region(struct pci_dev *pdev, int bar) { - struct pci_devres *dr; + /* + * This is done for backwards compatibility, because the old pci-devres + * API had a mode in which the function became managed if it had been + * enabled with pcim_enable_device() instead of pci_enable_device(). + */ + if (pci_is_managed(pdev)) { + pcim_release_region(pdev, bar); + return; + } =20 if (pci_resource_len(pdev, bar) =3D=3D 0) return; @@ -3863,20 +3871,6 @@ void pci_release_region(struct pci_dev *pdev, int ba= r) else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) release_mem_region(pci_resource_start(pdev, bar), pci_resource_len(pdev, bar)); - - /* - * This devres utility makes this function sometimes managed - * (when pcim_enable_device() has been called before). - * This is bad because it conflicts with the pcim_ functions being - * exclusively responsible for managed pci. Its "sometimes yes, sometimes - * no" nature can cause bugs. - * - * TODO: Remove this once all users that use pcim_enable_device() PLUS - * a region request function have been ported to using pcim_ functions. - */ - dr =3D find_pci_dr(pdev); - if (dr) - dr->region_mask &=3D ~(1 << bar); } EXPORT_SYMBOL(pci_release_region); =20 @@ -3904,14 +3898,18 @@ EXPORT_SYMBOL(pci_release_region); * NOTE: * This is a "hybrid" function: Its normally unmanaged, but becomes managed * when pcim_enable_device() has been called in advance. - * This hybrid feature is DEPRECATED! If you need to implement a new pci - * function that does automatic cleanup, write a new pcim_* function that = uses - * devres directly. + * This hybrid feature is DEPRECATED! If you want managed cleanup, use the + * pcim_* functions instead. */ static int __pci_request_region(struct pci_dev *pdev, int bar, const char *res_name, int exclusive) { - struct pci_devres *dr; + if (pci_is_managed(pdev)) { + if (exclusive =3D=3D IORESOURCE_EXCLUSIVE) + return pcim_request_region_exclusive(pdev, bar, res_name); + + return pcim_request_region(pdev, bar, res_name); + } =20 if (pci_resource_len(pdev, bar) =3D=3D 0) return 0; @@ -3927,20 +3925,6 @@ static int __pci_request_region(struct pci_dev *pdev= , int bar, goto err_out; } =20 - /* - * This devres utility makes this function sometimes managed - * (when pcim_enable_device() has been called before). - * This is bad because it conflicts with the pcim_ functions being - * exclusively responsible for managed pci. Its "sometimes yes, sometimes - * no" nature can cause bugs. - * - * TODO: Remove this once all users that use pcim_enable_device() PLUS - * a region request function have been ported to using pcim_ functions. - */ - dr =3D find_pci_dr(pdev); - if (dr) - dr->region_mask |=3D 1 << bar; - return 0; =20 err_out: diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 9d334bf4cbc4..3452684e5611 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -830,12 +830,6 @@ struct pci_devres { unsigned int orig_intx:1; unsigned int restore_intx:1; unsigned int mwi:1; - - /* - * TODO: remove the region_mask once everyone calling - * pcim_enable_device() + pci_*region*() is ported to pcim_ functions. - */ - u32 region_mask; }; =20 struct pci_devres *find_pci_dr(struct pci_dev *pdev); diff --git a/include/linux/pci.h b/include/linux/pci.h index 5d134e833546..8964ef9f2e9b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -2330,6 +2330,7 @@ int pcim_iomap_regions_request_all(struct pci_dev *pd= ev, int mask, const char *name); void pcim_iounmap_regions(struct pci_dev *pdev, int mask); int pcim_request_region(struct pci_dev *pdev, int bar, const char *res_nam= e); +int pcim_request_region_exclusive(struct pci_dev *pdev, int bar, const cha= r *name); void pcim_release_region(struct pci_dev *pdev, int bar); void pcim_release_all_regions(struct pci_dev *pdev); int pcim_request_all_regions(struct pci_dev *pdev, const char *name); --=20 2.43.0 From nobody Sun Feb 8 03:11:43 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3FA076E607 for ; Fri, 1 Mar 2024 11:30:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292626; cv=none; b=O+T7NQdfCrfoSZQHG2bmrRaOnpagDdYRLJjP2GdVPB6yYWqGriIsLbXe0lNc/QypbC420tMuelaCH7KRXQweg744HDaJT/koEBELBh2fLteiMzG1+AgGFQC973wnXzKIdvw2MoHlUBbQo1oCSDYnYDvKCN0MAv8BZ+RdQzfbVn0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292626; c=relaxed/simple; bh=eSnyzOdtUFJhBK0qF7Mzs85BLz3XsL0UztlDw124YIU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GVF9kYRiHgZafzy+3bfa1tB2fHIHiv9qJWbEH39tmoWma4AGy3/5DlddJa1Ca16H9yp/uplts4fRwepwSizRtBYv+34bKWhoMm5G+ESmlFZVQ+H+gA4zkOvdF/i6Bq5vmiuuzKdRUkGnWcCQmwqk42fMEkslyVRNTsPS+nDQLIQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=PDJMZm+A; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="PDJMZm+A" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709292624; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=waA643Nz8VSxmSriLnjZTP86MMy861LOzD7Kbbfqeh0=; b=PDJMZm+A2rrJNJSutermJfRdW3jDbenMpu99Jo7mN+Ws8qlvzVmq1ZzbB9cmqC+0q+baN5 ADzicd47sFueNt2DytY1ztJ5ziXXzN9qINTSTUyKl7NEnsQnDDgtajrE2N+F3P0RmCA+Qd D+pJvjueTVAr8OGpjbGaXYUNZtr3uyM= Received: from mail-yw1-f198.google.com (mail-yw1-f198.google.com [209.85.128.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-630-h0qmpg32PKediVM-ZveStQ-1; Fri, 01 Mar 2024 06:30:23 -0500 X-MC-Unique: h0qmpg32PKediVM-ZveStQ-1 Received: by mail-yw1-f198.google.com with SMTP id 00721157ae682-6083dfaf44cso2560197b3.0 for ; Fri, 01 Mar 2024 03:30:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709292622; x=1709897422; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=waA643Nz8VSxmSriLnjZTP86MMy861LOzD7Kbbfqeh0=; b=b8CdgaZmBVVrgWC1bo+3969B/w6h6/oRw2j4utroNt5ccZb9gOHl1JjbzlJDJkbtXM PGC3VgVQ+YPqXp3hlTSzEZhfBcikGVLM+KWYi5izo172SN0XQwWmB8VLP8TRsoEsooqE HEAFLD7VmRBl5uoEgy4YwSA+pVEssaLGa2/6HnnvTsb6tX38rz82uEhxG54P8mfOG+63 XwLEck58ST11J8BQok5BiSxMSLIghMnnW48mBA6GP/riAEgaerCnSUoiK2em2+KptE8s RVe4FDmkhiGD00FJtsaJL7xq7XV4AJzgwclro37qyjn31qOamKZQlXscG2FRjgXVpW+v daRQ== X-Forwarded-Encrypted: i=1; AJvYcCV8fFd/YbaVhceRTzYTsPK6OWXhiWbiGR1BH7UGpNeYj5WL4bWSXes5TmoU91JaWyyS2LJUQpuzL+5CXjLoF3OZCG64wfYc46Voaxp2 X-Gm-Message-State: AOJu0Yy0AfNDu0VZi0iLhibfNmiPFLP0uG41b6fkTBak/CEGZz74DSz7 AAf3CsgKlTmACfkvbbC0BMKwHHo0i3slu6YCTQk0pdn9jUilpayP8bNjo/AI5ekWZYpNUHGq7Pg KtlS9b0ZQJX+XEO7G/GxZB2YY1q1TFvosJvhVA2eYv8ohtkU+prvbqhH5APhDTQ== X-Received: by 2002:a81:8d04:0:b0:609:8450:547 with SMTP id d4-20020a818d04000000b0060984500547mr990990ywg.4.1709292622092; Fri, 01 Mar 2024 03:30:22 -0800 (PST) X-Google-Smtp-Source: AGHT+IFFMbY2wCQKKSWifzmLpics1CUNIv9kD53c9sHws2ffoOfs+I/p72A+atlLHSEiSevaj6yoXw== X-Received: by 2002:a81:8d04:0:b0:609:8450:547 with SMTP id d4-20020a818d04000000b0060984500547mr990910ywg.4.1709292620276; Fri, 01 Mar 2024 03:30:20 -0800 (PST) Received: from pstanner-thinkpadt14sgen1.remote.csb (nat-pool-muc-t.redhat.com. [149.14.88.26]) by smtp.gmail.com with ESMTPSA id b1-20020ac86781000000b0042eb46d15bbsm1596239qtp.88.2024.03.01.03.30.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Mar 2024 03:30:20 -0800 (PST) From: Philipp Stanner To: Hans de Goede , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter , Bjorn Helgaas , Sam Ravnborg , dakr@redhat.com Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Philipp Stanner Subject: [PATCH v4 05/10] PCI: Move dev-enabled status bit to struct pci_dev Date: Fri, 1 Mar 2024 12:29:53 +0100 Message-ID: <20240301112959.21947-6-pstanner@redhat.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240301112959.21947-1-pstanner@redhat.com> References: <20240301112959.21947-1-pstanner@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The bit describing whether the PCI device is currently enabled is stored in struct pci_devres. Besides this struct being subject of a cleanup process, struct pci_device is in general the right place to store this information, since it is not devres-specific. Move the 'enabled' boolean bit to struct pci_dev. Signed-off-by: Philipp Stanner --- drivers/pci/devres.c | 11 ++++------- drivers/pci/pci.c | 17 ++++++++++------- drivers/pci/pci.h | 1 - include/linux/pci.h | 1 + 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/pci/devres.c b/drivers/pci/devres.c index 03662760d629..6bf93c6cbb66 100644 --- a/drivers/pci/devres.c +++ b/drivers/pci/devres.c @@ -403,7 +403,7 @@ static void pcim_release(struct device *gendev, void *r= es) if (this->restore_intx) pci_intx(dev, this->orig_intx); =20 - if (this->enabled && !this->pinned) + if (!this->pinned) pci_disable_device(dev); } =20 @@ -446,14 +446,11 @@ int pcim_enable_device(struct pci_dev *pdev) dr =3D get_pci_dr(pdev); if (unlikely(!dr)) return -ENOMEM; - if (dr->enabled) - return 0; =20 rc =3D pci_enable_device(pdev); - if (!rc) { + if (!rc) pdev->is_managed =3D 1; - dr->enabled =3D 1; - } + return rc; } EXPORT_SYMBOL(pcim_enable_device); @@ -471,7 +468,7 @@ void pcim_pin_device(struct pci_dev *pdev) struct pci_devres *dr; =20 dr =3D find_pci_dr(pdev); - WARN_ON(!dr || !dr->enabled); + WARN_ON(!dr || !pdev->enabled); if (dr) dr->pinned =3D 1; } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 9ff52e840d9e..862dab87732a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1990,6 +1990,9 @@ static int do_pci_enable_device(struct pci_dev *dev, = int bars) u16 cmd; u8 pin; =20 + if (dev->enabled) + return 0; + err =3D pci_set_power_state(dev, PCI_D0); if (err < 0 && err !=3D -EIO) return err; @@ -2004,7 +2007,7 @@ static int do_pci_enable_device(struct pci_dev *dev, = int bars) pci_fixup_device(pci_fixup_enable, dev); =20 if (dev->msi_enabled || dev->msix_enabled) - return 0; + goto success_out; =20 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); if (pin) { @@ -2014,6 +2017,8 @@ static int do_pci_enable_device(struct pci_dev *dev, = int bars) cmd & ~PCI_COMMAND_INTX_DISABLE); } =20 +success_out: + dev->enabled =3D true; return 0; } =20 @@ -2172,6 +2177,9 @@ static void do_pci_disable_device(struct pci_dev *dev) { u16 pci_command; =20 + if (!dev->enabled) + return; + pci_read_config_word(dev, PCI_COMMAND, &pci_command); if (pci_command & PCI_COMMAND_MASTER) { pci_command &=3D ~PCI_COMMAND_MASTER; @@ -2179,6 +2187,7 @@ static void do_pci_disable_device(struct pci_dev *dev) } =20 pcibios_disable_device(dev); + dev->enabled =3D false; } =20 /** @@ -2206,12 +2215,6 @@ void pci_disable_enabled_device(struct pci_dev *dev) */ void pci_disable_device(struct pci_dev *dev) { - struct pci_devres *dr; - - dr =3D find_pci_dr(dev); - if (dr) - dr->enabled =3D 0; - dev_WARN_ONCE(&dev->dev, atomic_read(&dev->enable_cnt) <=3D 0, "disabling already-disabled device"); =20 diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 3452684e5611..97bd1c074d26 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -825,7 +825,6 @@ static inline pci_power_t mid_pci_get_power_state(struc= t pci_dev *pdev) * then remove them from here. */ struct pci_devres { - unsigned int enabled:1; unsigned int pinned:1; unsigned int orig_intx:1; unsigned int restore_intx:1; diff --git a/include/linux/pci.h b/include/linux/pci.h index 8964ef9f2e9b..f29c9289b378 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -367,6 +367,7 @@ struct pci_dev { this is D0-D3, D0 being fully functional, and D3 being off. */ u8 pm_cap; /* PM capability offset */ + unsigned int enabled:1; /* Whether this dev is enabled */ unsigned int imm_ready:1; /* Supports Immediate Readiness */ unsigned int pme_support:5; /* Bitmask of states from which PME# can be generated */ --=20 2.43.0 From nobody Sun Feb 8 03:11:43 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 583956E60B for ; Fri, 1 Mar 2024 11:30:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292627; cv=none; b=Cao/I7XUWCd4idlEDCRhLM0QBLoR1u8T/+axKMN11pnXdnU06jXkda7gLb+POwpaGOi6XG4ev6NwM4K+lCc4wYs7HD1gIqgycbWivEDOsJDrcQyMsuUfw6MuKrJ8n7/kmKjgmGRayRHmCbARJcb5ZmoYLpQ6StZNqSQ9AnFaT9Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292627; c=relaxed/simple; bh=FDNHRtLE6hNHjH2r39UrBWAZWNGYNFSj11RRKynJczI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SG0y/TiT7Crt4tUEQCG+kzCrsTrlLDmxxCH3sUW1kV5OSBqcep303vGf6QX0ZNnBOoOPKAjmFa4oqIv5qmIriK90Xgju7jTfwD9pBr4qp8KEzTB7gv1ffQhEP/nRM/PWGYIrIejkbS8dJole9M3RmJ71SWzO1YiLeFuuKV3pdiE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=hYBECC5y; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="hYBECC5y" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709292624; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ivdu8iiMoXpDkyzYV+DyKD6eGNB0PhvUs/32A1olwX8=; b=hYBECC5y47gKaTfp76/fyMWM/1w5jnTzIp3C2ObD/YhiRsSRo2BCbv1bkfOwDPCM7uB5p/ qR245levPb96xEjX8SZyw2EsS0skM0RGB3D642UYEyrPD4LEFIRvV/B/AgM0vpubdL0/p4 u63zD5xBBdkwhGj8Kw6r25pcIcwToAs= Received: from mail-oi1-f199.google.com (mail-oi1-f199.google.com [209.85.167.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-619-IrlbSC6RNu2Myrql8Fomiw-1; Fri, 01 Mar 2024 06:30:23 -0500 X-MC-Unique: IrlbSC6RNu2Myrql8Fomiw-1 Received: by mail-oi1-f199.google.com with SMTP id 5614622812f47-3c1d23a5a67so44277b6e.0 for ; Fri, 01 Mar 2024 03:30:23 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709292622; x=1709897422; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ivdu8iiMoXpDkyzYV+DyKD6eGNB0PhvUs/32A1olwX8=; b=U8HFiJUoTDF3EnfXcPPirBngFacBL2UAEvWh7nOTHPWhie4S3e5NedXzOs6oHmNBW/ XST6afoNJEqw0Bob/HnZ9Gj/UlRwMtSzVE0z0kMTwEOkmn8pJo7gyIv5xLvptX2kpDGH LnlEpsVwHfp8bXlzBjsS65z+4E3U7kzgcF6yMuxy02o642PXJdXO0StjKiB2uWfbSSvL 0kAB9oCpVQZmOhOrSByLgEWP0e5/BYOaYb1Yy0QOSrTbG3MQ76IkWcObJiIdFtPdF3m1 vwGLttlGZ2onrcEY5rZzRe7zZZ18c0Gob7IDk35LxtaWzmeKzdzMTmgm2zyew5ezBrx0 l3Tw== X-Forwarded-Encrypted: i=1; AJvYcCVBefBZ7UUr2ZH4uuNZkHYg7/VcQf7oBZ4Y56u3ejAv9p4g7/87qgKzHyj6+wQcKjVjfoqVZS+YY8MJ5e54w0u+VuPM4ukeCvNtwE3L X-Gm-Message-State: AOJu0YxXf6VmL84/N+d9uq41pAyvtL1UEBeRRzXpe2lL4U9jM+eIqmGL NjWYs9FTqNc4ftKkfv4ye4TyDqNZ40+oWPBzIlTAuoY5SPKXpWdr3d/KaGe4dCgKLPxy29hkd76 eCdUkDKMcxspRUyPjbltFUai+vwt+PWeX93KQO6HFd8OI7hK1emJrg1TnD/ixUQ== X-Received: by 2002:a05:6870:1b89:b0:21e:be91:ae48 with SMTP id hm9-20020a0568701b8900b0021ebe91ae48mr1406127oab.1.1709292622691; Fri, 01 Mar 2024 03:30:22 -0800 (PST) X-Google-Smtp-Source: AGHT+IE8ckx+w8g4Wwwu8eFQ5kKdvTt+sQ5kL9bsz1OBV7fqZNxqMuodycq5A8JPNFFAp2o3NusiBQ== X-Received: by 2002:a05:6870:1b89:b0:21e:be91:ae48 with SMTP id hm9-20020a0568701b8900b0021ebe91ae48mr1406108oab.1.1709292622384; Fri, 01 Mar 2024 03:30:22 -0800 (PST) Received: from pstanner-thinkpadt14sgen1.remote.csb (nat-pool-muc-t.redhat.com. [149.14.88.26]) by smtp.gmail.com with ESMTPSA id b1-20020ac86781000000b0042eb46d15bbsm1596239qtp.88.2024.03.01.03.30.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Mar 2024 03:30:22 -0800 (PST) From: Philipp Stanner To: Hans de Goede , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter , Bjorn Helgaas , Sam Ravnborg , dakr@redhat.com Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Philipp Stanner Subject: [PATCH v4 06/10] PCI: Move pinned status bit to struct pci_dev Date: Fri, 1 Mar 2024 12:29:54 +0100 Message-ID: <20240301112959.21947-7-pstanner@redhat.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240301112959.21947-1-pstanner@redhat.com> References: <20240301112959.21947-1-pstanner@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The bit describing whether the PCI device is currently pinned is stored in struct pci_devres. To clean up and simplify the PCI devres API, it's better if this information is stored in struct pci_dev, because it allows for checking that device's pinned-status directly through struct pci_dev. This will later permit simplifying pcim_enable_device(). Move the 'pinned' boolean bit to struct pci_dev. Restructure bits in struct pci_dev so the pm / pme fields are next to each other. Signed-off-by: Philipp Stanner --- drivers/pci/devres.c | 14 ++++---------- drivers/pci/pci.h | 1 - include/linux/pci.h | 5 +++-- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/pci/devres.c b/drivers/pci/devres.c index 6bf93c6cbb66..076362740791 100644 --- a/drivers/pci/devres.c +++ b/drivers/pci/devres.c @@ -403,7 +403,7 @@ static void pcim_release(struct device *gendev, void *r= es) if (this->restore_intx) pci_intx(dev, this->orig_intx); =20 - if (!this->pinned) + if (!dev->pinned) pci_disable_device(dev); } =20 @@ -459,18 +459,12 @@ EXPORT_SYMBOL(pcim_enable_device); * pcim_pin_device - Pin managed PCI device * @pdev: PCI device to pin * - * Pin managed PCI device @pdev. Pinned device won't be disabled on - * driver detach. @pdev must have been enabled with - * pcim_enable_device(). + * Pin managed PCI device @pdev. Pinned device won't be disabled on driver + * detach. @pdev must have been enabled with pcim_enable_device(). */ void pcim_pin_device(struct pci_dev *pdev) { - struct pci_devres *dr; - - dr =3D find_pci_dr(pdev); - WARN_ON(!dr || !pdev->enabled); - if (dr) - dr->pinned =3D 1; + pdev->pinned =3D true; } EXPORT_SYMBOL(pcim_pin_device); =20 diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 97bd1c074d26..0a4220aa303e 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -825,7 +825,6 @@ static inline pci_power_t mid_pci_get_power_state(struc= t pci_dev *pdev) * then remove them from here. */ struct pci_devres { - unsigned int pinned:1; unsigned int orig_intx:1; unsigned int restore_intx:1; unsigned int mwi:1; diff --git a/include/linux/pci.h b/include/linux/pci.h index f29c9289b378..fdf579e0d6ec 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -367,11 +367,12 @@ struct pci_dev { this is D0-D3, D0 being fully functional, and D3 being off. */ u8 pm_cap; /* PM capability offset */ - unsigned int enabled:1; /* Whether this dev is enabled */ - unsigned int imm_ready:1; /* Supports Immediate Readiness */ unsigned int pme_support:5; /* Bitmask of states from which PME# can be generated */ unsigned int pme_poll:1; /* Poll device's PME status bit */ + unsigned int enabled:1; /* Whether this dev is enabled */ + unsigned int pinned:1; /* Whether this dev is pinned */ + unsigned int imm_ready:1; /* Supports Immediate Readiness */ unsigned int d1_support:1; /* Low power state D1 is supported */ unsigned int d2_support:1; /* Low power state D2 is supported */ unsigned int no_d1d2:1; /* D1 and D2 are forbidden */ --=20 2.43.0 From nobody Sun Feb 8 03:11:43 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7356B6EB57 for ; Fri, 1 Mar 2024 11:30:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292629; cv=none; b=PdHJ3ZqtU4IEmSAS0OLfRsGSDsp7EijmWIQXuJdb/C6b7TzzdhPbVbbB0J47u9Tj0Hvc8L/DMtQ57GkR8uf3hSBfZo6/0xGGrpBi3HpnNVMxn8XN7Guefz2IVZFaCkhFsyEIiUpOSG6niMdbXoim5Fod1aMqT9EiFxopaOrTSiE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292629; c=relaxed/simple; bh=qzll3gbZTQmG4Hgqe4U2JNI8CMMEvh2buM8H3tGASRY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mqZP8Zg8S5P4gxX0WWRTXja6UxYjs4lAMA0PCZ/psMyml9T+aPqN5Bqyx30fnpjil+vijCqawyz28qm0WZ8cd+sNMyq6UxdIWyCzP0JM0c+v5R6UFZBKjtijCBxytMeGgG8LLdj0j7G//MMJ5SB0dLtaWkyR1rhPfqOpDWzqMX4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=NRQ3SPcd; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="NRQ3SPcd" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709292626; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VnDGhpR1zPECXp+96e14QkYQqiMZF4VdGZBiE6G7ho8=; b=NRQ3SPcdKaWsLNIQZWj0qY9a0yOM9HKRzyVSRw0lwqey0Gaijtvf/o3uvYDv0H3YWNIqVi 79//HHImcBOUCOR6sm7PcBu0N4T6YawTXt3A4aPW5xlLBU/T2vJB67BisjxEqLosru9Kxd UyMulDCymhnvgYMRe3B/uNY1SgYwyUY= Received: from mail-oi1-f197.google.com (mail-oi1-f197.google.com [209.85.167.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-202-tuoG3IlkP6uNeG0Vmd3h7w-1; Fri, 01 Mar 2024 06:30:25 -0500 X-MC-Unique: tuoG3IlkP6uNeG0Vmd3h7w-1 Received: by mail-oi1-f197.google.com with SMTP id 5614622812f47-3c1acda228eso477424b6e.1 for ; Fri, 01 Mar 2024 03:30:25 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709292624; x=1709897424; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VnDGhpR1zPECXp+96e14QkYQqiMZF4VdGZBiE6G7ho8=; b=vRVXzXvbABRwR5r39RP+ZWF9k2EopDOKNSaNIoKhFg90TJVSpu39J0iaf3N9sYmfoy Jx8ZF4JJSIu4X1z/uyGm4+OktktL7EosOEFvvhjuka7jS0NJ9rD5VWEHPpHhWwNvQKpE TUmNLF+QI+FYtuc3/XnCRXpmq8mUWrNhucyVpF+DpOuvA3g2F30NaPa+uor+9jpTgSlO uLDaMp1CF1lOM1hbfF3ZYkYER3wCQsz5RNUYnNNqCDAJspAfG6o4eOoL4OS0+WV/O7wc 2hhxo168K/UTJchwS42uLNzrJsraBeFV8ztV+Obx/G4T0L71E/tIEIM4vsdOTAthV2iK eHwA== X-Forwarded-Encrypted: i=1; AJvYcCXDKvT2ZZnAeOYIHWPitBsuSSQDyAQvN9YPtmOtMyU32zOh1SHFr3J3YdjGrP+TXYpB3A5EvyuEyadK1QARS1SkhqZ40xEJuYhkf9Yc X-Gm-Message-State: AOJu0YwhQMQN3ehMpzk3nMYkcNyL95sEsNT6c8WXN7Ar8KTg3ScZkMF/ bxCu+tpRtrlzg/+chSoJxkyiRUOqKKncj/9sbfzoR+DOpqCSE933S+8m4rfjkzneP5QyTFrtuh/ 0SoZ1ArA3w5z2NRSsxqPzsiJ8IMgzewgGSrlDdpp5XO6z5nAwm1CZ5BUyFKCOlg== X-Received: by 2002:a05:6808:1a29:b0:3c1:d272:dca7 with SMTP id bk41-20020a0568081a2900b003c1d272dca7mr1735106oib.3.1709292624739; Fri, 01 Mar 2024 03:30:24 -0800 (PST) X-Google-Smtp-Source: AGHT+IH7fzu12EwwD2RTKdgoVCsRW7y+HhyKLkFOutLSchbvE7Xkn+qmX80OdLOAnw7zYZwFAwXGWg== X-Received: by 2002:a05:6808:1a29:b0:3c1:d272:dca7 with SMTP id bk41-20020a0568081a2900b003c1d272dca7mr1735086oib.3.1709292624490; Fri, 01 Mar 2024 03:30:24 -0800 (PST) Received: from pstanner-thinkpadt14sgen1.remote.csb (nat-pool-muc-t.redhat.com. [149.14.88.26]) by smtp.gmail.com with ESMTPSA id b1-20020ac86781000000b0042eb46d15bbsm1596239qtp.88.2024.03.01.03.30.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Mar 2024 03:30:24 -0800 (PST) From: Philipp Stanner To: Hans de Goede , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter , Bjorn Helgaas , Sam Ravnborg , dakr@redhat.com Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Philipp Stanner Subject: [PATCH v4 07/10] PCI: Give pcim_set_mwi() its own devres callback Date: Fri, 1 Mar 2024 12:29:55 +0100 Message-ID: <20240301112959.21947-8-pstanner@redhat.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240301112959.21947-1-pstanner@redhat.com> References: <20240301112959.21947-1-pstanner@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Managing pci_set_mwi() with devres can easily be done with its own callback, without the necessity to store any state about it in a device-related struct. Remove the MWI state from struct pci_devres. Give pcim_set_mwi() a separate devres-callback. Signed-off-by: Philipp Stanner --- drivers/pci/devres.c | 29 ++++++++++++++++++----------- drivers/pci/pci.h | 1 - 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/pci/devres.c b/drivers/pci/devres.c index 076362740791..e417bd3ea96f 100644 --- a/drivers/pci/devres.c +++ b/drivers/pci/devres.c @@ -370,24 +370,34 @@ void __iomem *devm_pci_remap_cfg_resource(struct devi= ce *dev, } EXPORT_SYMBOL(devm_pci_remap_cfg_resource); =20 +static void __pcim_clear_mwi(void *pdev_raw) +{ + struct pci_dev *pdev =3D pdev_raw; + + pci_clear_mwi(pdev); +} + /** * pcim_set_mwi - a device-managed pci_set_mwi() - * @dev: the PCI device for which MWI is enabled + * @pdev: the PCI device for which MWI is enabled * * Managed pci_set_mwi(). * * RETURNS: An appropriate -ERRNO error value on error, or zero for succes= s. */ -int pcim_set_mwi(struct pci_dev *dev) +int pcim_set_mwi(struct pci_dev *pdev) { - struct pci_devres *dr; + int ret; =20 - dr =3D find_pci_dr(dev); - if (!dr) - return -ENOMEM; + ret =3D devm_add_action(&pdev->dev, __pcim_clear_mwi, pdev); + if (ret !=3D 0) + return ret; + + ret =3D pci_set_mwi(pdev); + if (ret !=3D 0) + devm_remove_action(&pdev->dev, __pcim_clear_mwi, pdev); =20 - dr->mwi =3D 1; - return pci_set_mwi(dev); + return ret; } EXPORT_SYMBOL(pcim_set_mwi); =20 @@ -397,9 +407,6 @@ static void pcim_release(struct device *gendev, void *r= es) struct pci_dev *dev =3D to_pci_dev(gendev); struct pci_devres *this =3D res; =20 - if (this->mwi) - pci_clear_mwi(dev); - if (this->restore_intx) pci_intx(dev, this->orig_intx); =20 diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 0a4220aa303e..bbe004eabcc1 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -827,7 +827,6 @@ static inline pci_power_t mid_pci_get_power_state(struc= t pci_dev *pdev) struct pci_devres { unsigned int orig_intx:1; unsigned int restore_intx:1; - unsigned int mwi:1; }; =20 struct pci_devres *find_pci_dr(struct pci_dev *pdev); --=20 2.43.0 From nobody Sun Feb 8 03:11:43 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 698E16EF16 for ; Fri, 1 Mar 2024 11:30:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292631; cv=none; b=oEBlRRttHNAqoArqskfynu1oHW4JR6NCZFWP7NyG5CcOjyDMzRZ31dYLD7rC8CQ8gLJ0cuJE4Hu237SI1Z1lOPZ8cCTj/8gXFYPvT3ZfErt+fc3dnYYjHdG3noAmAyg8BOak1xTCK7s+0sM4rC0IJb8vmFPW0/BMjkxRDfIowgU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292631; c=relaxed/simple; bh=wGKLutgNDish9diSLXJl2upRYyiSWsXKdjBkv9G+Yqg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nczNrXQT0AXR63PsCV+PbxNNiVcHxPx7eeYshAQ1GdYgxEiGwoOywUBOze2FB5ojzavFSZZzJfq8inXHS+oY5VfgEGO1prX8hBGWoENjeFhrVXfneflmxMHsV1JKD6pWDbnEGlTHYgxqSxID/LrTlzd4bD3j4JTd8JuNP9n1VmM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=V1CW600U; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="V1CW600U" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709292628; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gFrW8U6ifOIeoCJ4m2srgLpDe6q16UWzB5DewZd74Sc=; b=V1CW600U4H3MbP3CewpfjFFWhfVN7i5MNzzCYwbOuTfSCFK9IwN8DA8Tl8AN4LPKVTzeJu M6chIPhxRsCu1UeLaGybNbqI9bDQqkBhqa6r8KVEVDIQ6tga70CamVFdV50Da0SGErxiAX NbJGIGjxn+g8KwFscJWOGwWLt2wJxbA= Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-516-Pqr-Z_mDN8WDdDGUtn2sYg-1; Fri, 01 Mar 2024 06:30:27 -0500 X-MC-Unique: Pqr-Z_mDN8WDdDGUtn2sYg-1 Received: by mail-qt1-f198.google.com with SMTP id d75a77b69052e-42da766586cso2038631cf.1 for ; Fri, 01 Mar 2024 03:30:27 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709292627; x=1709897427; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gFrW8U6ifOIeoCJ4m2srgLpDe6q16UWzB5DewZd74Sc=; b=Lma0pf8MpPAO8V7QRWtpSOf4dR8/+7RcoDtVNqKBgQfhe0Zgdh+Wc7MWu4rPGvVWOU HiTFynvPAdLZJqNYdWKFCRmh9km6x+A+ZzfTCnziaVsidz29Mz3RYTxFF79I71VHXlIn C3IA3yKkvZGB/DiEmSJzg/Kw3FreUng2/UwBPGZyoQBlZrYO+0guPS2lr7Z6aCD6CfWL 4B8kytj+DagH6r0qvpcy61zHPTjyzqKzexhakXaYsbEQpwY7Qwws2xAsZO3z4IM6tu5f WMhLSLQy5MQlk3cVknSmEqERo3zTuaE3ima09iCluHpKu4/RMmVW2WhBNWMMGdS3ThdO u/fg== X-Forwarded-Encrypted: i=1; AJvYcCX4uXQAK9Ndi0FyWtIsk0NIMZ3Y4LoJeCW4ScmoenYC1+kOJsNFqoIFaNTZS14h8DJMvUPA18dU5wuWuJdEsktpiBxoB+rIxKqSEF8t X-Gm-Message-State: AOJu0Yz2odiTXfa4/qTYuwRYV+LgHsyrc7vkb266mYOTHpb7GnoXSlnz ePwpJmTzBYfjv4ATl/xP+DSzC5mVnzvz3emkgSPAA5zuIsYDufhAgN88jlROxQ1Bj0sQrbim1oS uhsJVEbK8kQbjW2aoWmGJII2jqIvb+16Q+N5UrPEJN5NCGaQdaIaTHUq6VdU0MA== X-Received: by 2002:a05:622a:1ba8:b0:42e:b428:808d with SMTP id bp40-20020a05622a1ba800b0042eb428808dmr1172313qtb.0.1709292626853; Fri, 01 Mar 2024 03:30:26 -0800 (PST) X-Google-Smtp-Source: AGHT+IEGhT502yChHD7nPbq6Ya4luJieu8HbTHkr0kt24S6xsGaGCfqyhcYmSy34J3ytpTb8Oyflxg== X-Received: by 2002:a05:622a:1ba8:b0:42e:b428:808d with SMTP id bp40-20020a05622a1ba800b0042eb428808dmr1172294qtb.0.1709292626575; Fri, 01 Mar 2024 03:30:26 -0800 (PST) Received: from pstanner-thinkpadt14sgen1.remote.csb (nat-pool-muc-t.redhat.com. [149.14.88.26]) by smtp.gmail.com with ESMTPSA id b1-20020ac86781000000b0042eb46d15bbsm1596239qtp.88.2024.03.01.03.30.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Mar 2024 03:30:26 -0800 (PST) From: Philipp Stanner To: Hans de Goede , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter , Bjorn Helgaas , Sam Ravnborg , dakr@redhat.com Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Philipp Stanner Subject: [PATCH v4 08/10] PCI: Give pci(m)_intx its own devres callback Date: Fri, 1 Mar 2024 12:29:56 +0100 Message-ID: <20240301112959.21947-9-pstanner@redhat.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240301112959.21947-1-pstanner@redhat.com> References: <20240301112959.21947-1-pstanner@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" pci_intx() is one of the functions that have "hybrid mode" (i.e., sometimes managed, sometimes not). Providing a separate pcim_intx() function with its own device resource and cleanup callback allows for removing further large parts of the legacy pci-devres implementation. As in the region-request-functions, pci_intx() has to call into its managed counterpart for backwards compatibility. As pci_intx() is an outdated function, pcim_intx() shall not be made visible to other drivers via a public API. Implement pcim_intx() with its own device resource. Make pci_intx() call pcim_intx() in the managed case. Remove the struct pci_devres from pci.h. Signed-off-by: Philipp Stanner --- drivers/pci/devres.c | 74 +++++++++++++++++++++++++++++++++++--------- drivers/pci/pci.c | 24 +++++++------- drivers/pci/pci.h | 17 +--------- 3 files changed, 74 insertions(+), 41 deletions(-) diff --git a/drivers/pci/devres.c b/drivers/pci/devres.c index e417bd3ea96f..8a643f15140a 100644 --- a/drivers/pci/devres.c +++ b/drivers/pci/devres.c @@ -40,6 +40,11 @@ struct pcim_iomap_devres { void __iomem *table[PCI_STD_NUM_BARS]; }; =20 +/* Used to restore the old intx state on driver detach. */ +struct pcim_intx_devres { + int orig_intx; +}; + enum pcim_addr_devres_type { /* Default initializer. */ PCIM_ADDR_DEVRES_TYPE_INVALID, @@ -401,28 +406,69 @@ int pcim_set_mwi(struct pci_dev *pdev) } EXPORT_SYMBOL(pcim_set_mwi); =20 +static void pcim_intx_restore(struct device *dev, void *data) +{ + struct pci_dev *pdev =3D to_pci_dev(dev); + struct pcim_intx_devres *res =3D data; =20 -static void pcim_release(struct device *gendev, void *res) + pci_intx(pdev, res->orig_intx); +} + +static struct pcim_intx_devres *get_or_create_intx_devres(struct device *d= ev) { - struct pci_dev *dev =3D to_pci_dev(gendev); - struct pci_devres *this =3D res; + struct pcim_intx_devres *res; =20 - if (this->restore_intx) - pci_intx(dev, this->orig_intx); + res =3D devres_find(dev, pcim_intx_restore, NULL, NULL); + if (res) + return res; =20 - if (!dev->pinned) - pci_disable_device(dev); + res =3D devres_alloc(pcim_intx_restore, sizeof(*res), GFP_KERNEL); + if (res) + devres_add(dev, res); + + return res; } =20 -/* - * TODO: After the last four callers in pci.c are ported, find_pci_dr() - * needs to be made static again. +/** + * pcim_intx - managed pci_intx() + * @pdev: the PCI device to operate on + * @enable: boolean: whether to enable or disable PCI INTx + * + * Returns: 0 on success, -ENOMEM on error. + * + * Enables/disables PCI INTx for device @pdev. + * Restores the original state on driver detach. */ -struct pci_devres *find_pci_dr(struct pci_dev *pdev) +int pcim_intx(struct pci_dev *pdev, int enable) { - if (pci_is_managed(pdev)) - return devres_find(&pdev->dev, pcim_release, NULL, NULL); - return NULL; + u16 pci_command, new; + struct pcim_intx_devres *res; + + res =3D get_or_create_intx_devres(&pdev->dev); + if (!res) + return -ENOMEM; + + res->orig_intx =3D !enable; + + pci_read_config_word(pdev, PCI_COMMAND, &pci_command); + + if (enable) + new =3D pci_command & ~PCI_COMMAND_INTX_DISABLE; + else + new =3D pci_command | PCI_COMMAND_INTX_DISABLE; + + if (new !=3D pci_command) + pci_write_config_word(pdev, PCI_COMMAND, new); + + return 0; +} + +static void pcim_release(struct device *gendev, void *res) +{ + struct pci_dev *dev =3D to_pci_dev(gendev); + + if (!dev->pinned) + pci_disable_device(dev); } =20 static struct pci_devres *get_pci_dr(struct pci_dev *pdev) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 862dab87732a..8ad2ded49ab5 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3857,7 +3857,7 @@ EXPORT_SYMBOL(pci_enable_atomic_ops_to_root); void pci_release_region(struct pci_dev *pdev, int bar) { /* - * This is done for backwards compatibility, because the old pci-devres + * This is done for backwards compatibility, because the old PCI devres * API had a mode in which the function became managed if it had been * enabled with pcim_enable_device() instead of pci_enable_device(). */ @@ -4445,11 +4445,22 @@ void pci_disable_parity(struct pci_dev *dev) * This is a "hybrid" function: Its normally unmanaged, but becomes managed * when pcim_enable_device() has been called in advance. * This hybrid feature is DEPRECATED! + * Use pcim_intx() if you need a managed version. */ void pci_intx(struct pci_dev *pdev, int enable) { u16 pci_command, new; =20 + /* + * This is done for backwards compatibility, because the old PCI devres + * API had a mode in which this function became managed if the dev had + * been enabled with pcim_enable_device() instead of pci_enable_device(). + */ + if (pci_is_managed(pdev)) { + WARN_ON_ONCE(pcim_intx(pdev, enable) !=3D 0); + return; + } + pci_read_config_word(pdev, PCI_COMMAND, &pci_command); =20 if (enable) @@ -4457,17 +4468,8 @@ void pci_intx(struct pci_dev *pdev, int enable) else new =3D pci_command | PCI_COMMAND_INTX_DISABLE; =20 - if (new !=3D pci_command) { - struct pci_devres *dr; - + if (new !=3D pci_command) pci_write_config_word(pdev, PCI_COMMAND, new); - - dr =3D find_pci_dr(pdev); - if (dr && !dr->restore_intx) { - dr->restore_intx =3D 1; - dr->orig_intx =3D !enable; - } - } } EXPORT_SYMBOL_GPL(pci_intx); =20 diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index bbe004eabcc1..c6da2b554108 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -814,22 +814,7 @@ static inline pci_power_t mid_pci_get_power_state(stru= ct pci_dev *pdev) } #endif =20 -/* - * Managed PCI resources. This manages device on/off, INTx/MSI/MSI-X - * on/off and BAR regions. pci_dev itself records MSI/MSI-X status, so - * there's no need to track it separately. pci_devres is initialized - * when a device is enabled using managed PCI device enable interface. - * - * TODO: Struct pci_devres and find_pci_dr() only need to be here because - * they're used in pci.c. Port or move these functions to devres.c and - * then remove them from here. - */ -struct pci_devres { - unsigned int orig_intx:1; - unsigned int restore_intx:1; -}; - -struct pci_devres *find_pci_dr(struct pci_dev *pdev); +int pcim_intx(struct pci_dev *dev, int enable); =20 /* * Config Address for PCI Configuration Mechanism #1 --=20 2.43.0 From nobody Sun Feb 8 03:11:43 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E9EA6E607 for ; Fri, 1 Mar 2024 11:30:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292633; cv=none; b=FBcr1FDS+bGE9VIDC8Cab9P1LdSyNU2UmCNsMjagQTfc1pp6zQHsP3unjpInR8DS8eFvB8t6xsE157S/UlH3RFFvgsl0spG9cJzIZWTZze1I+wQ4vi5Zd6AOxZv8pK4YufVlTOkGaRImbTVKPbOHb3ZNXKiGAzkrvVP2TaPxXm4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292633; c=relaxed/simple; bh=TeuRzMDENTP+mrbhGHtQfvvCYg0RN9gxYq3N6G/Xkt4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WR4UTOeoiVO/Z+KUgJOLMBAbO4cG31MiwxqigotGVfggKFl4Yna5HyETAHLKO4si9AwQEfVc14TYBpSwjnbha5S/WvvjfZZH1tLLlaXRlTsTB3lOD/tyFTeDo0ceLDBFixEF3KlWb26EC2l3UP48cQ8BSugVpwLFGqa0/nNWLW0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=e2VOC9hE; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="e2VOC9hE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709292630; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nDrBrW1QyBkIZW9XXC7FxnbgE53QwXCFFfi0uuWv0Ls=; b=e2VOC9hE8hrsx4DDQYGvLVwYH4m0wlWXWKJWoA+Aq8VvtQO6cPPMqBwCdMzQTP9K+goW6v lX7PuuC/QMsENJzN7arf1iDTdyWJhgEvflZfhBsisDo98g24trlh3OtaRbDIzHqZPMDk1q Pay60vTwEROUNUJ1awzTwIDYYsKcmHk= Received: from mail-qv1-f71.google.com (mail-qv1-f71.google.com [209.85.219.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-33-HuSFKZ3MPEemUGLuWjPqYA-1; Fri, 01 Mar 2024 06:30:29 -0500 X-MC-Unique: HuSFKZ3MPEemUGLuWjPqYA-1 Received: by mail-qv1-f71.google.com with SMTP id 6a1803df08f44-68f5e085773so4419526d6.0 for ; Fri, 01 Mar 2024 03:30:29 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709292629; x=1709897429; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nDrBrW1QyBkIZW9XXC7FxnbgE53QwXCFFfi0uuWv0Ls=; b=vm4Y+57Iok6yIrzA4bIsxjw3mqKaJtHAnusKN0/OpoeY66Dvmb+EuC1L3KoUrk4DVy +CHm/qJ4lXp0k0S2WpIfoIl912uqODfzKJajhxVyuomw/iqEiwfsde8X4lO+FxAmRpVd s3RkzzNrI/G028WNpTYKLxrC5FttggwHXpsAZxim405O/2FI4UiHa30VYDa5Efr51VOl BQioTjOTmS5wyx4E732uSEpzePhQn22B4j0wOB6I75Z0La2Z1IpQpV0KKMz03GAWjCQN aYEojvAJ22/jgEbn7T86X7ul/RI2u+HbwHEs6vYEE/38A91nuHl+EcPxFfVkC+N2Jsig NN0A== X-Forwarded-Encrypted: i=1; AJvYcCUkKYayjV+jnUOgy1fFGJT3CXS/cCBSbNOWlx2WFFz1X7E4w64CQV1imrxCemHVo9JynzE4im1BxHdALibSUWloSHKefedaoCV4Oenj X-Gm-Message-State: AOJu0YyFdasgT8kk8Q2bYesa28+F5Z1vWDLNvO9ubKhcCJU6s4e5muM3 Vpw+/SbS/ivvuIR3Rq7h+mdJIKoPo5OnNf10gDlY5Rm0VtYaQzVhD0g4bfuqQj6t6h6bg33W8Dq 3RedIPrSDT+Du5JfNQR4B4foWx8rgXUwgPZAWUtp/FhXvcGkIDVPFufQXcarDHA== X-Received: by 2002:ac8:58d0:0:b0:42e:c9b2:5846 with SMTP id u16-20020ac858d0000000b0042ec9b25846mr1388317qta.5.1709292628960; Fri, 01 Mar 2024 03:30:28 -0800 (PST) X-Google-Smtp-Source: AGHT+IE0USADji0WQ4vStz8axm9yU2LeR4404cTuRyF3UBhbQb+Uq0hGVzuRwtUe65EkPR+o7q1ATQ== X-Received: by 2002:ac8:58d0:0:b0:42e:c9b2:5846 with SMTP id u16-20020ac858d0000000b0042ec9b25846mr1388291qta.5.1709292628661; Fri, 01 Mar 2024 03:30:28 -0800 (PST) Received: from pstanner-thinkpadt14sgen1.remote.csb (nat-pool-muc-t.redhat.com. [149.14.88.26]) by smtp.gmail.com with ESMTPSA id b1-20020ac86781000000b0042eb46d15bbsm1596239qtp.88.2024.03.01.03.30.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Mar 2024 03:30:28 -0800 (PST) From: Philipp Stanner To: Hans de Goede , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter , Bjorn Helgaas , Sam Ravnborg , dakr@redhat.com Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Philipp Stanner Subject: [PATCH v4 09/10] PCI: Remove legacy pcim_release() Date: Fri, 1 Mar 2024 12:29:57 +0100 Message-ID: <20240301112959.21947-10-pstanner@redhat.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240301112959.21947-1-pstanner@redhat.com> References: <20240301112959.21947-1-pstanner@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Thanks to preceding cleanup steps, pcim_release() is now not needed anymore and can be replaced by pcim_disable_device(), which is the exact counterpart to pcim_enable_device(). This permits removing further parts of the old devres API. Replace pcim_release() with pcim_disable_device(). Remove the now surplus function get_pci_dr(). Signed-off-by: Philipp Stanner --- drivers/pci/devres.c | 49 +++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/drivers/pci/devres.c b/drivers/pci/devres.c index 8a643f15140a..3e567773c556 100644 --- a/drivers/pci/devres.c +++ b/drivers/pci/devres.c @@ -463,48 +463,41 @@ int pcim_intx(struct pci_dev *pdev, int enable) return 0; } =20 -static void pcim_release(struct device *gendev, void *res) +static void pcim_disable_device(void *pdev_raw) { - struct pci_dev *dev =3D to_pci_dev(gendev); - - if (!dev->pinned) - pci_disable_device(dev); -} - -static struct pci_devres *get_pci_dr(struct pci_dev *pdev) -{ - struct pci_devres *dr, *new_dr; - - dr =3D devres_find(&pdev->dev, pcim_release, NULL, NULL); - if (dr) - return dr; + struct pci_dev *pdev =3D pdev_raw; =20 - new_dr =3D devres_alloc(pcim_release, sizeof(*new_dr), GFP_KERNEL); - if (!new_dr) - return NULL; - return devres_get(&pdev->dev, new_dr, NULL, NULL); + if (!pdev->pinned) + pci_disable_device(pdev); } =20 /** * pcim_enable_device - Managed pci_enable_device() * @pdev: PCI device to be initialized * - * Managed pci_enable_device(). + * Returns: 0 on success, negative error code on failure. + * + * Managed pci_enable_device(). Device will automatically be disabled on + * driver detach. */ int pcim_enable_device(struct pci_dev *pdev) { - struct pci_devres *dr; - int rc; + int ret; =20 - dr =3D get_pci_dr(pdev); - if (unlikely(!dr)) - return -ENOMEM; + ret =3D devm_add_action(&pdev->dev, pcim_disable_device, pdev); + if (ret !=3D 0) + return ret; =20 - rc =3D pci_enable_device(pdev); - if (!rc) - pdev->is_managed =3D 1; + /* + * We prefer removing the action in case of an error over + * devm_add_action_or_reset() because the later could theoretically be + * disturbed by users having pinned the device too soon. + */ + ret =3D pci_enable_device(pdev); + if (ret !=3D 0) + devm_remove_action(&pdev->dev, pcim_disable_device, pdev); =20 - return rc; + return ret; } EXPORT_SYMBOL(pcim_enable_device); =20 --=20 2.43.0 From nobody Sun Feb 8 03:11:43 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2CA9C6F523 for ; Fri, 1 Mar 2024 11:30:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292635; cv=none; b=jpu2yMaTsGhxqDPF8pNmQ+ZcvHKNGRE1NnQ6BcDSwEQKp+qF9b4rph7Uk6x6/l9AVFLUhsHXj+PMLXxyavlIWsdsFIwJ8aY2IwYjSAFjCOsK6RZ4zbcRI/RK/PR9fsTZuHjFO99dqPB5voFFiiu11ApLAOq5YBEe4lWGlLz+YQQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709292635; c=relaxed/simple; bh=DqC1146Gw+gtEXd1U6evjshsYPG+7+z9wKN5tAwt5no=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sSNZgLjeM6HicHVZTT26crHfrKHDBnzSYdvm00J7UhA+UrdLAadtQhZ6ruYDVKVBsh8g2m6a/GKhJyQjKX35GHvXyiEACdeb113Q1spu5X/LmwT6ZrRhmJ+s3OIp3DrcAdgwg9F/zU8Z4HPwkfCE6fzfDxaz31902s6fo21ViRo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=ZYKV9D0h; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="ZYKV9D0h" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709292633; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wFTRxYvZ76dhFqAdPDH/a2zkO7llSf+/xEzdCoge4iY=; b=ZYKV9D0hvVvacwx8yiJs+UW+XgeQ5ae1YFfaOl+yD+doMUTyju39GTB7OrCbMebSgTU8yQ UO1XjeKM5FI/nheGuk2DuVJ+yid/6aQ6YmtLuCC005RTmXi3HNb6ljcmMUFHmPJLFqAHE5 xL9O6t2vRpISMt3y711MYsTiOxwMRv0= Received: from mail-oo1-f72.google.com (mail-oo1-f72.google.com [209.85.161.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-354-qJXskIQsMqWSlqIKA682ag-1; Fri, 01 Mar 2024 06:30:32 -0500 X-MC-Unique: qJXskIQsMqWSlqIKA682ag-1 Received: by mail-oo1-f72.google.com with SMTP id 006d021491bc7-5a10aecb064so3640eaf.0 for ; Fri, 01 Mar 2024 03:30:32 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709292631; x=1709897431; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wFTRxYvZ76dhFqAdPDH/a2zkO7llSf+/xEzdCoge4iY=; b=SEOCqit+sTdjxDod1Ga+r1iu4ZrZvLbptKgBsmGE1bHcDLDENwfIuX5hspZ0GjXax7 di8i+dDLP32YgXEq25wNjupMe9eFxDvC3H8uyN3C7HRhyzCzYAdOCMnpYnm8DaJeEn2F WXI+UqQtlmLTWhObTv6CNJu0CPFYfskoUdXR4fxEKIycgglNCd8rmcxxCYXWDeTcY5Da WEvvWk4HnuIsY0l9FuIkBT3WTVr6MyY65AlP+yIFpQwDxNR7QgfeO/61904oLt69hG9K Pv56NVawbh4tylYo4PqphIA3hwaIu4uG075ClX+vovwPJmuJcwR1U6jHmiCnm9mH62b0 Cw8A== X-Forwarded-Encrypted: i=1; AJvYcCWyMP8HYFRx4Rxw632mBCGCbiE8qGBjZf23SnIZlHvMWuYXToJQ0/awlITE8PDaBDH6tszVuSxOzgIOjWupWFQ92VU9tPsB+3SOp98Q X-Gm-Message-State: AOJu0YytOidQdsMcCQ1Yf1L/akzUbXAnWBe58MkRVgjYJNNUlh8IVYSt CKK+6NTGb7rKjsdhHV+6Oal9M7cvpstHiE8G/Ug3yaLaxJ8E8T318HMH2P96NIU6urB7ZWetAXs FD5vj9ZDYNg8MgcB3vPEJlSAhTBvMj1wKPMlg8oD2FlPIC1aeNDdA3L4AL76rVbukXpnVQw== X-Received: by 2002:a05:6358:5923:b0:178:9f1d:65e4 with SMTP id g35-20020a056358592300b001789f1d65e4mr1147489rwf.3.1709292631170; Fri, 01 Mar 2024 03:30:31 -0800 (PST) X-Google-Smtp-Source: AGHT+IE/dYBpHA/2LZIcNaPDDpZ49F70JHds10e81JbU90eBR8pmO8IjXPGhx9tXuvUpPM6IQ4Mw1Q== X-Received: by 2002:a05:6358:5923:b0:178:9f1d:65e4 with SMTP id g35-20020a056358592300b001789f1d65e4mr1147459rwf.3.1709292630853; Fri, 01 Mar 2024 03:30:30 -0800 (PST) Received: from pstanner-thinkpadt14sgen1.remote.csb (nat-pool-muc-t.redhat.com. [149.14.88.26]) by smtp.gmail.com with ESMTPSA id b1-20020ac86781000000b0042eb46d15bbsm1596239qtp.88.2024.03.01.03.30.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Mar 2024 03:30:30 -0800 (PST) From: Philipp Stanner To: Hans de Goede , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter , Bjorn Helgaas , Sam Ravnborg , dakr@redhat.com Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Philipp Stanner , stable@kernel.vger.org Subject: [PATCH v4 10/10] drm/vboxvideo: fix mapping leaks Date: Fri, 1 Mar 2024 12:29:58 +0100 Message-ID: <20240301112959.21947-11-pstanner@redhat.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240301112959.21947-1-pstanner@redhat.com> References: <20240301112959.21947-1-pstanner@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When the PCI devres API was introduced to this driver, it was wrongly assumed that initializing the device with pcim_enable_device() instead of pci_enable_device() will make all PCI functions managed. This is wrong and was caused by the quite confusing PCI devres API in which some, but not all, functions become managed that way. The function pci_iomap_range() is never managed. Replace pci_iomap_range() with the actually managed function pcim_iomap_range(). CC: # v5.10+ Fixes: 8558de401b5f ("drm/vboxvideo: use managed pci functions") Signed-off-by: Philipp Stanner Reviewed-by: Hans de Goede --- drivers/gpu/drm/vboxvideo/vbox_main.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/vboxvideo/vbox_main.c b/drivers/gpu/drm/vboxvi= deo/vbox_main.c index 42c2d8a99509..d4ade9325401 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_main.c +++ b/drivers/gpu/drm/vboxvideo/vbox_main.c @@ -42,12 +42,11 @@ static int vbox_accel_init(struct vbox_private *vbox) /* Take a command buffer for each screen from the end of usable VRAM. */ vbox->available_vram_size -=3D vbox->num_crtcs * VBVA_MIN_BUFFER_SIZE; =20 - vbox->vbva_buffers =3D pci_iomap_range(pdev, 0, - vbox->available_vram_size, - vbox->num_crtcs * - VBVA_MIN_BUFFER_SIZE); - if (!vbox->vbva_buffers) - return -ENOMEM; + vbox->vbva_buffers =3D pcim_iomap_range( + pdev, 0, vbox->available_vram_size, + vbox->num_crtcs * VBVA_MIN_BUFFER_SIZE); + if (IS_ERR(vbox->vbva_buffers)) + return PTR_ERR(vbox->vbva_buffers); =20 for (i =3D 0; i < vbox->num_crtcs; ++i) { vbva_setup_buffer_context(&vbox->vbva_info[i], @@ -116,11 +115,10 @@ int vbox_hw_init(struct vbox_private *vbox) DRM_INFO("VRAM %08x\n", vbox->full_vram_size); =20 /* Map guest-heap at end of vram */ - vbox->guest_heap =3D - pci_iomap_range(pdev, 0, GUEST_HEAP_OFFSET(vbox), - GUEST_HEAP_SIZE); - if (!vbox->guest_heap) - return -ENOMEM; + vbox->guest_heap =3D pcim_iomap_range(pdev, 0, + GUEST_HEAP_OFFSET(vbox), GUEST_HEAP_SIZE); + if (IS_ERR(vbox->guest_heap)) + return PTR_ERR(vbox->guest_heap); =20 /* Create guest-heap mem-pool use 2^4 =3D 16 byte chunks */ vbox->guest_pool =3D devm_gen_pool_create(vbox->ddev.dev, 4, -1, --=20 2.43.0