linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/7] PCI: Convert dynamic PCI resources sysfs objects into static
@ 2021-09-10 20:26 Krzysztof Wilczyński
  2021-09-10 20:26 ` [PATCH v2 1/7] PCI/sysfs: Add pci_dev_resource_attr_is_visible() helper Krzysztof Wilczyński
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Krzysztof Wilczyński @ 2021-09-10 20:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Greg Kroah-Hartman, Pali Rohár, Oliver O'Halloran,
	Krzysztof Hałasa, linux-pci

Hello,

Currently, a lot of PCI-related sysfs objects are dynamically created
under the "/sys/bus/pci/devices/..." path when either the PCI driver is
initialised or when a new device is hot-added.

When PCI driver loads and the PCI sub-system initialises, the sysfs
attributes are then added when late_initcall() function is called:

    pci_sysfs_init
      sysfs_initialized = 1
      for_each_pci_dev
        pci_create_sysfs_dev_files
          sysfs_create_bin_file

Otherwise, for hot-added devices, the sysfs attributes are then added
when the pci_bus_add_devices() function is called:

  pci_bus_add_devices
    pci_bus_add_device
      pci_create_sysfs_dev_files
        if (!sysfs_initialized)
	  return
        sysfs_create_bin_file

When a device is removed the pci_remove_sysfs_dev_files() function is
called from pci_stop_dev() to remove all the attributes that were
previously added:

  pci_stop_bus_device
    pci_stop_dev
      if (pci_dev_is_added)
        pci_remove_sysfs_dev_files
          sysfs_remove_bin_file

The current implementation is known to cause problems:

  https://lore.kernel.org/linux-pci/1366196798-15929-1-git-send-email-artem.savkov@gmail.com/
  https://lore.kernel.org/linux-pci/20200716110423.xtfyb3n6tn5ixedh@pali/
  https://lore.kernel.org/linux-pci/m3eebg9puj.fsf@t19.piap.pl/
  https://lore.kernel.org/linux-pci/20210507102706.7658-1-danijel.slivka@amd.com/

Most of the PCI-related attributes do not need to be created and removed
dynamically and there is no need to also manage their create and remove
life cycle manually.

The aim is also to first reduce the reliance on using late_initcall() to
eventually remove the need for it completely.

This particular series focusing on PCI resources files on platforms that
provide either the HAVE_PCI_MMAP or ARCH_GENERIC_PCI_MMAP_RESOURCE
definitions (other platforms, such as the Alpha platform, will not be
affected) continues the on-going effort to convert the majority of the
dynamic sysfs objects into static ones so that the PCI driver core can
add and remove sysfs objects and related attributes automatically.

Please note that this series depends on the commits from the following
series to be added prior to applying it:

  https://lore.kernel.org/linux-pci/20210729233235.1508920-1-kw@linux.com/
  https://lore.kernel.org/linux-pci/20210812132144.791268-1-kw@linux.com/

	Krzysztof

---
Changes in v2:
  Refactored code so that the macros, helpers and internal functions can
  be used to correctly leverage the read(), write() and mmap() callbacks
  rather than to use the .is_bin_visible() callback to set up sysfs
  objects internals as this is not supported.
  Refactored some if-statements to check for a resource flag first, and
  then call either arch_can_pci_mmap_io() or arch_can_pci_mmap_wc(),
  plus store result of testing for IORESOURCE_MEM and
  IORESOURCE_PREFETCH flags into a boolean variable, as per Bjorn
  Helgaas' suggestion.
  Renamed pci_read_resource_io() and pci_write_resource_io() callbacks
  so that these are not specifically tied to I/O BARs read() and write()
  operations also as per Bjorn Helgaas' suggestion.
  Updated style for code handling bitwise operations to match the style
  that is preferred as per Bjorn Helgaas' suggestion.
  Updated commit messages adding more details about the implementation
  as requested by Bjorn Helgaas.

Krzysztof Wilczyński (7):
  PCI/sysfs: Add pci_dev_resource_attr_is_visible() helper
  PCI/sysfs: Add pci_dev_resource_attr() macro
  PCI/sysfs: Only allow IORESOURCE_IO in pci_resource_io()
  PCI/sysfs: Only allow supported resource type in pci_mmap_resource()
  PCI/sysfs: Convert PCI resource files to static attributes
  PCI/sysfs: Rename pci_read_resource_io() and pci_write_resource_io()
  PCI/sysfs: Update code to match the preferred style

 drivers/pci/pci-sysfs.c | 213 +++++++++++++++++++++-------------------
 include/linux/pci.h     |   2 +
 2 files changed, 116 insertions(+), 99 deletions(-)

-- 
2.33.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/7] PCI/sysfs: Add pci_dev_resource_attr_is_visible() helper
  2021-09-10 20:26 [PATCH v2 0/7] PCI: Convert dynamic PCI resources sysfs objects into static Krzysztof Wilczyński
@ 2021-09-10 20:26 ` Krzysztof Wilczyński
  2021-09-10 20:26 ` [PATCH v2 2/7] PCI/sysfs: Add pci_dev_resource_attr() macro Krzysztof Wilczyński
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Wilczyński @ 2021-09-10 20:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Greg Kroah-Hartman, Pali Rohár, Oliver O'Halloran,
	Krzysztof Hałasa, linux-pci

This helper controls how a static sysfs attribute is exposed, where
depending on whether a particular resource is available (the BAR address
space requested has non-zero size) or whether the write-combine feature
is supported, the sysfs attribute will be made either visible or hidden.

After the conversion to use static sysfs objects when exposing each PCI
BAR address space this helper is to be called from the .is_bin_visible()
callback for each of the PCI resources attributes groups.

A single BAR will have a dedicated attribute group with two attributes
in it - one normal resource and one that can potentially support the
write-combine feature.

Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
---
 drivers/pci/pci-sysfs.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 7fb5cd17cc98..4272d1aba205 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1237,6 +1237,30 @@ static int pci_create_resource_files(struct pci_dev *pdev)
 	}
 	return 0;
 }
+
+static umode_t pci_dev_resource_attr_is_visible(struct kobject *kobj,
+						struct bin_attribute *a,
+						int bar, bool write_combine)
+{
+	struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
+	resource_size_t resource_size = pci_resource_len(pdev, bar);
+	bool prefetch;
+
+	if (!resource_size)
+		return 0;
+
+	prefetch = (pci_resource_flags(pdev, bar) &
+		    (IORESOURCE_MEM | IORESOURCE_PREFETCH)) ==
+			(IORESOURCE_MEM | IORESOURCE_PREFETCH);
+
+	if (write_combine && !(prefetch && arch_can_pci_mmap_wc()))
+		return 0;
+
+	a->size = resource_size;
+
+	return a->attr.mode;
+};
+
 #else /* !(defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)) */
 int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
 void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/7] PCI/sysfs: Add pci_dev_resource_attr() macro
  2021-09-10 20:26 [PATCH v2 0/7] PCI: Convert dynamic PCI resources sysfs objects into static Krzysztof Wilczyński
  2021-09-10 20:26 ` [PATCH v2 1/7] PCI/sysfs: Add pci_dev_resource_attr_is_visible() helper Krzysztof Wilczyński
@ 2021-09-10 20:26 ` Krzysztof Wilczyński
  2021-09-10 20:26 ` [PATCH v2 3/7] PCI/sysfs: Only allow IORESOURCE_IO in pci_resource_io() Krzysztof Wilczyński
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Wilczyński @ 2021-09-10 20:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Greg Kroah-Hartman, Pali Rohár, Oliver O'Halloran,
	Krzysztof Hałasa, linux-pci

The pci_dev_resource_attr() macro will be used to declare and define
each of the PCI resource sysfs objects statically while also reducing
unnecessary code repetition.

This macro aims to also replace functions pci_create_resource_files()
and pci_create_attr() that are currently involved in the PCI resource
sysfs objects dynamic creation and set up once the.

Internally this macro relies on the pci_dev_resource_attr_is_visible()
helper which should correctly handle creating either normal and/or
write-combine attributes as required.

Two other macros were also added to help reduce code duplication, the
pci_dev_bin_attribute() and pci_dev_resource_group().

The pci_dev_bin_attribute() macro abstracts the declaration and
definition of a binary attribute with all the required fields from
struct bin_attribute set as needed for a given PCI resource sysfs
attribute.

The pci_dev_resource_group() macro will be used to reduce unnecessary
code repetition following the use of the pci_dev_resource_attr() macro
when adding each of the many newly created resource groups to the list
of other PCI sysfs objects stored in the pci_dev_groups array.

The conversion to static sysfs objects will result in two sysfs
attributes to be created for each PCI resource (the underlying BAR)
independently, one for a normal resource, and one for a resource
that is write-combine capable, should this feature be supported.

Each such resource will be then placed in a dedicated attribute
resource group so that access to it can be controlled using a
dedicated .is_bin_visible() callback where depending on what the
underlying resource (a given BAR) supports will be either made
visible or hidden.

Therefore, for six standard PCI BARs, a total of twelve attribute
groups will be thus created per device.

Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
---
 drivers/pci/pci-sysfs.c | 61 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 4272d1aba205..ccdd1e34aeee 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1261,6 +1261,67 @@ static umode_t pci_dev_resource_attr_is_visible(struct kobject *kobj,
 	return a->attr.mode;
 };
 
+#define pci_dev_bin_attribute(_name, _mmap, _bar)		\
+struct bin_attribute pci_dev_##_name##_attr = {			\
+	.attr = { .name = __stringify(_name), .mode = 0600 },	\
+	.read = pci_read_resource_io,				\
+	.write = pci_write_resource_io,				\
+	.mmap = _mmap,						\
+	.private = (void *)(unsigned long)_bar,			\
+	.f_mapping = iomem_get_mapping,				\
+}
+
+#define pci_dev_resource_attr(_bar)					\
+static pci_dev_bin_attribute(resource##_bar,				\
+			     pci_mmap_resource_uc,			\
+			     _bar);					\
+									\
+static struct bin_attribute *pci_dev_resource##_bar##_attrs[] = {	\
+	&pci_dev_resource##_bar##_attr,					\
+	NULL,								\
+};									\
+									\
+static umode_t								\
+pci_dev_resource##_bar##_attr_is_visible(struct kobject *kobj,		\
+					 struct bin_attribute *a,	\
+					 int n)				\
+{									\
+	return pci_dev_resource_attr_is_visible(kobj, a, _bar, false);	\
+};									\
+									\
+static const struct							\
+attribute_group pci_dev_resource##_bar##_attr_group = {			\
+	.bin_attrs = pci_dev_resource##_bar##_attrs,			\
+	.is_bin_visible = pci_dev_resource##_bar##_attr_is_visible,	\
+};									\
+									\
+static pci_dev_bin_attribute(resource##_bar##_wc,			\
+			     pci_mmap_resource_wc,			\
+			     _bar);					\
+									\
+static struct bin_attribute *pci_dev_resource##_bar##_wc_attrs[] = {	\
+	&pci_dev_resource##_bar##_wc_attr,				\
+	NULL,								\
+};									\
+									\
+static umode_t								\
+pci_dev_resource##_bar##_wc_attr_is_visible(struct kobject *kobj,	\
+					    struct bin_attribute *a,	\
+					    int n)			\
+{									\
+	return pci_dev_resource_attr_is_visible(kobj, a, _bar, true);	\
+};									\
+									\
+static const struct							\
+attribute_group pci_dev_resource##_bar##_wc_attr_group = {		\
+	.bin_attrs = pci_dev_resource##_bar##_wc_attrs,			\
+	.is_bin_visible = pci_dev_resource##_bar##_wc_attr_is_visible,	\
+}
+
+#define pci_dev_resource_group(_bar)		\
+	&pci_dev_resource##_bar##_attr_group,	\
+	&pci_dev_resource##_bar##_wc_attr_group
+
 #else /* !(defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)) */
 int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
 void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/7] PCI/sysfs: Only allow IORESOURCE_IO in pci_resource_io()
  2021-09-10 20:26 [PATCH v2 0/7] PCI: Convert dynamic PCI resources sysfs objects into static Krzysztof Wilczyński
  2021-09-10 20:26 ` [PATCH v2 1/7] PCI/sysfs: Add pci_dev_resource_attr_is_visible() helper Krzysztof Wilczyński
  2021-09-10 20:26 ` [PATCH v2 2/7] PCI/sysfs: Add pci_dev_resource_attr() macro Krzysztof Wilczyński
@ 2021-09-10 20:26 ` Krzysztof Wilczyński
  2021-09-10 20:26 ` [PATCH v2 4/7] PCI/sysfs: Only allow supported resource type in pci_mmap_resource() Krzysztof Wilczyński
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Wilczyński @ 2021-09-10 20:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Greg Kroah-Hartman, Pali Rohár, Oliver O'Halloran,
	Krzysztof Hałasa, linux-pci

Currently, when the sysfs attributes for PCI resources are added
dynamically, the read() and write() callbacks will only ever be set when
the underlying resource (a given BAR) has the IORESOURCE_IO flag set,
otherwise the callbacks will be NULL and any attempt to read from such
sysfs attribute will inherently fail.

After the conversion to the static sysfs objects, the read() and write()
callbacks will be always set for a given binary attribute (a particular
sysfs object). Thus, a check is added to the pci_resource_io() function
to ensure that a read against the underlying resource is supported and
that the IORESOURCE_IO flag is set.

Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
---
 drivers/pci/pci-sysfs.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index ccdd1e34aeee..e151d635fe04 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1084,6 +1084,9 @@ static ssize_t pci_resource_io(struct file *filp, struct kobject *kobj,
 	int bar = (unsigned long)attr->private;
 	unsigned long port = off;
 
+	if (!(pci_resource_flags(pdev, bar) & IORESOURCE_IO))
+		return -EIO;
+
 	port += pci_resource_start(pdev, bar);
 
 	if (port > pci_resource_end(pdev, bar))
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 4/7] PCI/sysfs: Only allow supported resource type in pci_mmap_resource()
  2021-09-10 20:26 [PATCH v2 0/7] PCI: Convert dynamic PCI resources sysfs objects into static Krzysztof Wilczyński
                   ` (2 preceding siblings ...)
  2021-09-10 20:26 ` [PATCH v2 3/7] PCI/sysfs: Only allow IORESOURCE_IO in pci_resource_io() Krzysztof Wilczyński
@ 2021-09-10 20:26 ` Krzysztof Wilczyński
  2021-09-10 20:26 ` [PATCH v2 5/7] PCI/sysfs: Convert PCI resource files to static attributes Krzysztof Wilczyński
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Wilczyński @ 2021-09-10 20:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Greg Kroah-Hartman, Pali Rohár, Oliver O'Halloran,
	Krzysztof Hałasa, linux-pci

Currently, when the sysfs attributes for PCI resources are added
dynamically, the mmap() callback will only ever be set when the
underlying resource (a given BAR) has either the IORESOURCE_MEM (which
currently is implied) or IORESOURCE_IO flag set and where the latter
requires that the underlying architecture supports mmap() for I/O BARs,
otherwise the callbacks are set to NULL and any attempt to read from
such sysfs attribute will inherently fail.

Following the conversion to the static sysfs objects, the mmap()
callbacks will be always set for a given binary attribute (a particular
sysfs object). Thus, a check is added to the pci_mmap_resource()
function to ensure that a read against the underlying resource is
supported and that either the IORESOURCE_MEM or IORESOURCE_IO flag is
set with the platform supporting mmap() for I/O BARs as required.

Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
---
 drivers/pci/pci-sysfs.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index e151d635fe04..2031b5da6bcf 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1051,6 +1051,10 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
 	if (ret)
 		return ret;
 
+	if (!(res->flags & IORESOURCE_MEM ||
+	    ((res->flags & IORESOURCE_IO) && arch_can_pci_mmap_io())))
+		return -EIO;
+
 	if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
 		return -EINVAL;
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 5/7] PCI/sysfs: Convert PCI resource files to static attributes
  2021-09-10 20:26 [PATCH v2 0/7] PCI: Convert dynamic PCI resources sysfs objects into static Krzysztof Wilczyński
                   ` (3 preceding siblings ...)
  2021-09-10 20:26 ` [PATCH v2 4/7] PCI/sysfs: Only allow supported resource type in pci_mmap_resource() Krzysztof Wilczyński
@ 2021-09-10 20:26 ` Krzysztof Wilczyński
  2021-09-10 20:26 ` [PATCH v2 6/7] PCI/sysfs: Rename pci_read_resource_io() and pci_write_resource_io() Krzysztof Wilczyński
  2021-09-10 20:26 ` [PATCH v2 7/7] PCI/sysfs: Update code to match the preferred style Krzysztof Wilczyński
  6 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Wilczyński @ 2021-09-10 20:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Greg Kroah-Hartman, Pali Rohár, Oliver O'Halloran,
	Krzysztof Hałasa, linux-pci

The PCI resource files are a series of sysfs objects that allow for
access to the PCI BAR address space.

Previously, the PCI resource files for platforms that provide either
the HAVE_PCI_MMAP or ARCH_GENERIC_PCI_MMAP_RESOURCE definitions were
dynamically created by pci_bus_add_device() or the pci_sysfs_init()
late_initcall, but since these objects do not need to be created or
removed dynamically, we can use static attributes so the device model
takes care of addition and removal automatically.

Thus, convert the PCI resources files to static attributes on supported
platforms using the pci_dev_resource_attr() macro.  This macro makes use
of the .is_bin_visible() callback to support creating either normal or
write-combine attributes as required.

Platforms that do currently do not define either the HAVE_PCI_MMAP or
ARCH_GENERIC_PCI_MMAP_RESOURCE such as the Alpha platform can keep using
their platform-specific methods for adding PCI resources files.

Also remove pci_create_resource_files(), pci_remove_resource_files() and
pci_create_attr() functions, which are no longer needed.

The PCI resource files were first added in the pre-Git era:
  https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/drivers/pci/pci-sysfs.c?id=42298be0eeb5ae98453b3374c36161b05a46c5dc

Support for write-combine resources was added in commit 45aec1a ("x86:
PAT export resource_wc in pci sysfs").

Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
---
 drivers/pci/pci-sysfs.c | 129 ++++++++--------------------------------
 include/linux/pci.h     |   2 +
 2 files changed, 28 insertions(+), 103 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 2031b5da6bcf..084c386c94c4 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1142,109 +1142,6 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
 	return pci_resource_io(filp, kobj, attr, buf, off, count, true);
 }
 
-/**
- * pci_remove_resource_files - cleanup resource files
- * @pdev: dev to cleanup
- *
- * If we created resource files for @pdev, remove them from sysfs and
- * free their resources.
- */
-static void pci_remove_resource_files(struct pci_dev *pdev)
-{
-	int i;
-
-	for (i = 0; i < PCI_STD_NUM_BARS; i++) {
-		struct bin_attribute *res_attr;
-
-		res_attr = pdev->res_attr[i];
-		if (res_attr) {
-			sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
-			kfree(res_attr);
-		}
-
-		res_attr = pdev->res_attr_wc[i];
-		if (res_attr) {
-			sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
-			kfree(res_attr);
-		}
-	}
-}
-
-static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
-{
-	/* allocate attribute structure, piggyback attribute name */
-	int name_len = write_combine ? 13 : 10;
-	struct bin_attribute *res_attr;
-	char *res_attr_name;
-	int retval;
-
-	res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC);
-	if (!res_attr)
-		return -ENOMEM;
-
-	res_attr_name = (char *)(res_attr + 1);
-
-	sysfs_bin_attr_init(res_attr);
-	if (write_combine) {
-		pdev->res_attr_wc[num] = res_attr;
-		sprintf(res_attr_name, "resource%d_wc", num);
-		res_attr->mmap = pci_mmap_resource_wc;
-	} else {
-		pdev->res_attr[num] = res_attr;
-		sprintf(res_attr_name, "resource%d", num);
-		if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
-			res_attr->read = pci_read_resource_io;
-			res_attr->write = pci_write_resource_io;
-			if (arch_can_pci_mmap_io())
-				res_attr->mmap = pci_mmap_resource_uc;
-		} else {
-			res_attr->mmap = pci_mmap_resource_uc;
-		}
-	}
-	if (res_attr->mmap)
-		res_attr->f_mapping = iomem_get_mapping;
-	res_attr->attr.name = res_attr_name;
-	res_attr->attr.mode = 0600;
-	res_attr->size = pci_resource_len(pdev, num);
-	res_attr->private = (void *)(unsigned long)num;
-	retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
-	if (retval)
-		kfree(res_attr);
-
-	return retval;
-}
-
-/**
- * pci_create_resource_files - create resource files in sysfs for @dev
- * @pdev: dev in question
- *
- * Walk the resources in @pdev creating files for each resource available.
- */
-static int pci_create_resource_files(struct pci_dev *pdev)
-{
-	int i;
-	int retval;
-
-	/* Expose the PCI resources from this device as files */
-	for (i = 0; i < PCI_STD_NUM_BARS; i++) {
-
-		/* skip empty resources */
-		if (!pci_resource_len(pdev, i))
-			continue;
-
-		retval = pci_create_attr(pdev, i, 0);
-		/* for prefetchable resources, create a WC mappable file */
-		if (!retval && arch_can_pci_mmap_wc() &&
-		    pdev->resource[i].flags & IORESOURCE_PREFETCH)
-			retval = pci_create_attr(pdev, i, 1);
-		if (retval) {
-			pci_remove_resource_files(pdev);
-			return retval;
-		}
-	}
-	return 0;
-}
-
 static umode_t pci_dev_resource_attr_is_visible(struct kobject *kobj,
 						struct bin_attribute *a,
 						int bar, bool write_combine)
@@ -1329,6 +1226,13 @@ attribute_group pci_dev_resource##_bar##_wc_attr_group = {		\
 	&pci_dev_resource##_bar##_attr_group,	\
 	&pci_dev_resource##_bar##_wc_attr_group
 
+pci_dev_resource_attr(0);
+pci_dev_resource_attr(1);
+pci_dev_resource_attr(2);
+pci_dev_resource_attr(3);
+pci_dev_resource_attr(4);
+pci_dev_resource_attr(5);
+
 #else /* !(defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)) */
 int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
 void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
@@ -1470,6 +1374,10 @@ static const struct attribute_group pci_dev_reset_attr_group = {
 	.is_visible = pci_dev_reset_attr_is_visible,
 };
 
+#if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
+int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev) { return 0; }
+void pci_remove_sysfs_dev_files(struct pci_dev *pdev) { }
+#else /* !(defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)) */
 int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
 {
 	if (!sysfs_initialized)
@@ -1491,9 +1399,15 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
 
 	pci_remove_resource_files(pdev);
 }
+#endif
 
 static int __init pci_sysfs_init(void)
 {
+#if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
+	struct pci_bus *pbus = NULL;
+
+	sysfs_initialized = 1;
+#else /* !(defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)) */
 	struct pci_dev *pdev = NULL;
 	struct pci_bus *pbus = NULL;
 	int retval;
@@ -1507,6 +1421,7 @@ static int __init pci_sysfs_init(void)
 		}
 	}
 
+#endif
 	while ((pbus = pci_find_next_bus(pbus)))
 		pci_create_legacy_files(pbus);
 
@@ -1580,6 +1495,14 @@ static const struct attribute_group pci_dev_group = {
 
 const struct attribute_group *pci_dev_groups[] = {
 	&pci_dev_group,
+#if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
+	pci_dev_resource_group(0),
+	pci_dev_resource_group(1),
+	pci_dev_resource_group(2),
+	pci_dev_resource_group(3),
+	pci_dev_resource_group(4),
+	pci_dev_resource_group(5),
+#endif
 	&pci_dev_config_attr_group,
 	&pci_dev_rom_attr_group,
 	&pci_dev_reset_attr_group,
diff --git a/include/linux/pci.h b/include/linux/pci.h
index cd8aa6fce204..51c632e5d0f7 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -459,8 +459,10 @@ struct pci_dev {
 	u32		saved_config_space[16]; /* Config space saved at suspend time */
 	struct hlist_head saved_cap_space;
 	int		rom_attr_enabled;	/* Display of ROM attribute enabled? */
+#if !(defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE))
 	struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
 	struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
+#endif
 
 #ifdef CONFIG_HOTPLUG_PCI_PCIE
 	unsigned int	broken_cmd_compl:1;	/* No compl for some cmds */
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 6/7] PCI/sysfs: Rename pci_read_resource_io() and pci_write_resource_io()
  2021-09-10 20:26 [PATCH v2 0/7] PCI: Convert dynamic PCI resources sysfs objects into static Krzysztof Wilczyński
                   ` (4 preceding siblings ...)
  2021-09-10 20:26 ` [PATCH v2 5/7] PCI/sysfs: Convert PCI resource files to static attributes Krzysztof Wilczyński
@ 2021-09-10 20:26 ` Krzysztof Wilczyński
  2021-09-10 20:26 ` [PATCH v2 7/7] PCI/sysfs: Update code to match the preferred style Krzysztof Wilczyński
  6 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Wilczyński @ 2021-09-10 20:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Greg Kroah-Hartman, Pali Rohár, Oliver O'Halloran,
	Krzysztof Hałasa, linux-pci

The pci_read_resource_io() and pci_write_resource_io() functions are
used for the corresponding read() and write() callbacks when declaring
and defining a static sysfs object for a given PCI resource.

Currently, only reading and writing against an I/O BARs is supported,
but we might change this in the future to also include memory-mapped
resources.

Thus, rename to read() and write() callbacks to be more generic and drop
the I/O BARs-specific suffix from them.

Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
---
 drivers/pci/pci-sysfs.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 084c386c94c4..17535f4028af 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1122,16 +1122,16 @@ static ssize_t pci_resource_io(struct file *filp, struct kobject *kobj,
 	return -EINVAL;
 }
 
-static ssize_t pci_read_resource_io(struct file *filp, struct kobject *kobj,
-				    struct bin_attribute *attr, char *buf,
-				    loff_t off, size_t count)
+static ssize_t pci_read_resource(struct file *filp, struct kobject *kobj,
+				 struct bin_attribute *attr, char *buf,
+				 loff_t off, size_t count)
 {
 	return pci_resource_io(filp, kobj, attr, buf, off, count, false);
 }
 
-static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
-				     struct bin_attribute *attr, char *buf,
-				     loff_t off, size_t count)
+static ssize_t pci_write_resource(struct file *filp, struct kobject *kobj,
+				  struct bin_attribute *attr, char *buf,
+				  loff_t off, size_t count)
 {
 	int ret;
 
@@ -1168,8 +1168,8 @@ static umode_t pci_dev_resource_attr_is_visible(struct kobject *kobj,
 #define pci_dev_bin_attribute(_name, _mmap, _bar)		\
 struct bin_attribute pci_dev_##_name##_attr = {			\
 	.attr = { .name = __stringify(_name), .mode = 0600 },	\
-	.read = pci_read_resource_io,				\
-	.write = pci_write_resource_io,				\
+	.read = pci_read_resource,				\
+	.write = pci_write_resource,				\
 	.mmap = _mmap,						\
 	.private = (void *)(unsigned long)_bar,			\
 	.f_mapping = iomem_get_mapping,				\
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 7/7] PCI/sysfs: Update code to match the preferred style
  2021-09-10 20:26 [PATCH v2 0/7] PCI: Convert dynamic PCI resources sysfs objects into static Krzysztof Wilczyński
                   ` (5 preceding siblings ...)
  2021-09-10 20:26 ` [PATCH v2 6/7] PCI/sysfs: Rename pci_read_resource_io() and pci_write_resource_io() Krzysztof Wilczyński
@ 2021-09-10 20:26 ` Krzysztof Wilczyński
  6 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Wilczyński @ 2021-09-10 20:26 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Greg Kroah-Hartman, Pali Rohár, Oliver O'Halloran,
	Krzysztof Hałasa, linux-pci

Update code to match the preferred style while making the bitwise
operations less ambiguous with added extra parentheses surrounding the
expression.

Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
---
 drivers/pci/pci-sysfs.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 17535f4028af..fdfe4aa70875 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1013,7 +1013,7 @@ int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
 	unsigned long nr, start, size;
 	resource_size_t pci_start = 0, pci_end;
 
-	if (pci_resource_len(pdev, resno) == 0)
+	if (!pci_resource_len(pdev, resno))
 		return 0;
 	nr = vma_pages(vma);
 	start = vma->vm_pgoff;
@@ -1055,13 +1055,13 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
 	    ((res->flags & IORESOURCE_IO) && arch_can_pci_mmap_io())))
 		return -EIO;
 
-	if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
+	if ((res->flags & IORESOURCE_MEM) && iomem_is_exclusive(res->start))
 		return -EINVAL;
 
 	if (!pci_mmap_fits(pdev, bar, vma, PCI_MMAP_SYSFS))
 		return -EINVAL;
 
-	mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
+	mmap_type = (res->flags & IORESOURCE_MEM) ? pci_mmap_mem : pci_mmap_io;
 
 	return pci_mmap_resource_range(pdev, bar, vma, mmap_type, write_combine);
 }
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-09-10 20:26 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-10 20:26 [PATCH v2 0/7] PCI: Convert dynamic PCI resources sysfs objects into static Krzysztof Wilczyński
2021-09-10 20:26 ` [PATCH v2 1/7] PCI/sysfs: Add pci_dev_resource_attr_is_visible() helper Krzysztof Wilczyński
2021-09-10 20:26 ` [PATCH v2 2/7] PCI/sysfs: Add pci_dev_resource_attr() macro Krzysztof Wilczyński
2021-09-10 20:26 ` [PATCH v2 3/7] PCI/sysfs: Only allow IORESOURCE_IO in pci_resource_io() Krzysztof Wilczyński
2021-09-10 20:26 ` [PATCH v2 4/7] PCI/sysfs: Only allow supported resource type in pci_mmap_resource() Krzysztof Wilczyński
2021-09-10 20:26 ` [PATCH v2 5/7] PCI/sysfs: Convert PCI resource files to static attributes Krzysztof Wilczyński
2021-09-10 20:26 ` [PATCH v2 6/7] PCI/sysfs: Rename pci_read_resource_io() and pci_write_resource_io() Krzysztof Wilczyński
2021-09-10 20:26 ` [PATCH v2 7/7] PCI/sysfs: Update code to match the preferred style Krzysztof Wilczyński

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).