linux-hyperv.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 0/5] PCI: Use the private field of pci_host_bridge for ACPI device
@ 2021-08-11 15:36 Boqun Feng
  2021-08-11 15:36 ` [RFC 1/5] PCI: Introduce pci_create_root_bus_priv() Boqun Feng
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Boqun Feng @ 2021-08-11 15:36 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Catalin Marinas, Will Deacon, Bjorn Helgaas, Rafael J. Wysocki,
	Len Brown, K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger,
	Wei Liu, Dexuan Cui, Rob Herring, Krzysztof Wilczyński,
	Boqun Feng, linux-arm-kernel, linux-kernel, linux-pci,
	linux-acpi, linux-hyperv, Sunil Muthuswamy, Marc Zyngier,
	Arnd Bergmann

Hi Lorenzo,

As our previous discussion, I make a patchset showing the required
effort if we want to use ->private in pci_host_bridge to store ACPI
device pointer on ARM64. This patchset is mostly for discussion purpose.

This patchset is based onto the v5 of my Hyper-V PCI on ARM64 patchset:

	https://lore.kernel.org/lkml/20210726180657.142727-1-boqun.feng@gmail.com/

, and I've tested it with other code under development to fully enable
Hyper-V virtual PCI on ARM64.

Regards,
Boqun


Boqun Feng (5):
  PCI: Introduce pci_create_root_bus_priv()
  PCI/ACPI: Store ACPI device information in the host bridge structure
  PCI: hv: Set NULL as the ACPI device for the PCI host bridge
  arm64: PCI: Retrieve ACPI device information directly from host
    bridges
  PCI: hv: Remove the dependency of pci_config_window

 arch/arm64/kernel/pci.c             | 14 +-------------
 drivers/acpi/pci_root.c             |  5 +++--
 drivers/pci/controller/pci-hyperv.c | 20 +++++++++++++++-----
 drivers/pci/probe.c                 | 15 ++++++++++++---
 include/linux/pci-acpi.h            |  5 +++++
 include/linux/pci.h                 |  3 +++
 6 files changed, 39 insertions(+), 23 deletions(-)

-- 
2.32.0


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

* [RFC 1/5] PCI: Introduce pci_create_root_bus_priv()
  2021-08-11 15:36 [RFC 0/5] PCI: Use the private field of pci_host_bridge for ACPI device Boqun Feng
@ 2021-08-11 15:36 ` Boqun Feng
  2021-08-11 15:36 ` [RFC 2/5] PCI/ACPI: Store ACPI device information in the host bridge structure Boqun Feng
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Boqun Feng @ 2021-08-11 15:36 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Catalin Marinas, Will Deacon, Bjorn Helgaas, Rafael J. Wysocki,
	Len Brown, K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger,
	Wei Liu, Dexuan Cui, Rob Herring, Krzysztof Wilczyński,
	Boqun Feng, linux-arm-kernel, linux-kernel, linux-pci,
	linux-acpi, linux-hyperv, Sunil Muthuswamy, Marc Zyngier,
	Arnd Bergmann

In order to allow root bus creation to populate the ->private of the
pci_host_bridge at the same, pci_create_root_bus_priv() is introduced.
The new function will be used to support passing the corresponding ACPI
device as the ->private field when creating the PCI root bus.

No functional change.

Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
---
 drivers/pci/probe.c | 15 ++++++++++++---
 include/linux/pci.h |  3 +++
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ea7f2a57e2f5..8f5fea2a7bd9 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2991,13 +2991,14 @@ void __weak pcibios_remove_bus(struct pci_bus *bus)
 {
 }
 
-struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+struct pci_bus *pci_create_root_bus_priv(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources,
+		void *private, size_t priv_size)
 {
 	int error;
 	struct pci_host_bridge *bridge;
 
-	bridge = pci_alloc_host_bridge(0);
+	bridge = pci_alloc_host_bridge(priv_size);
 	if (!bridge)
 		return NULL;
 
@@ -3008,6 +3009,9 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	bridge->busnr = bus;
 	bridge->ops = ops;
 
+	if (priv_size)
+		memcpy(bridge->private, private, priv_size);
+
 	error = pci_register_host_bridge(bridge);
 	if (error < 0)
 		goto err_out;
@@ -3018,6 +3022,11 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	put_device(&bridge->dev);
 	return NULL;
 }
+struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	return pci_create_root_bus_priv(parent, bus, ops, sysdata, resources, NULL, 0);
+}
 EXPORT_SYMBOL_GPL(pci_create_root_bus);
 
 int pci_host_probe(struct pci_host_bridge *bridge)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 01aa201e1df0..119356312979 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1041,6 +1041,9 @@ void pcibios_scan_specific_bus(int busn);
 struct pci_bus *pci_find_bus(int domain, int busnr);
 void pci_bus_add_devices(const struct pci_bus *bus);
 struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
+struct pci_bus *pci_create_root_bus_priv(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources,
+		void *private, size_t priv_size);
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 				    struct pci_ops *ops, void *sysdata,
 				    struct list_head *resources);
-- 
2.32.0


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

* [RFC 2/5] PCI/ACPI: Store ACPI device information in the host bridge structure
  2021-08-11 15:36 [RFC 0/5] PCI: Use the private field of pci_host_bridge for ACPI device Boqun Feng
  2021-08-11 15:36 ` [RFC 1/5] PCI: Introduce pci_create_root_bus_priv() Boqun Feng
@ 2021-08-11 15:36 ` Boqun Feng
  2021-08-11 15:36 ` [RFC 3/5] PCI: hv: Set NULL as the ACPI device for the PCI host bridge Boqun Feng
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Boqun Feng @ 2021-08-11 15:36 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Catalin Marinas, Will Deacon, Bjorn Helgaas, Rafael J. Wysocki,
	Len Brown, K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger,
	Wei Liu, Dexuan Cui, Rob Herring, Krzysztof Wilczyński,
	Boqun Feng, linux-arm-kernel, linux-kernel, linux-pci,
	linux-acpi, linux-hyperv, Sunil Muthuswamy, Marc Zyngier,
	Arnd Bergmann

In order to decouple the ACPI device information of a PCI host bridge
from the sysdata, ->private of pci_host_bridge is used to store the ACPI
device, and it's done by the new pci_create_root_bus_priv().

A reader function is also added, to retrieve the ACPI device information
in pci_host_bridge.

Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
---
 drivers/acpi/pci_root.c  | 5 +++--
 include/linux/pci-acpi.h | 5 +++++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index d7deedf3548e..82824841cbda 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -894,8 +894,9 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 
 	pci_acpi_root_add_resources(info);
 	pci_add_resource(&info->resources, &root->secondary);
-	bus = pci_create_root_bus(NULL, busnum, ops->pci_ops,
-				  sysdata, &info->resources);
+	bus = pci_create_root_bus_priv(NULL, busnum, ops->pci_ops, sysdata,
+				       &info->resources, &root->device,
+				       sizeof(struct acpi_device *));
 	if (!bus)
 		goto out_release_info;
 
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index 5ba475ca9078..21d4cc80aa55 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -80,6 +80,11 @@ extern struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 					    struct acpi_pci_root_ops *ops,
 					    struct acpi_pci_root_info *info,
 					    void *sd);
+static inline struct acpi_device *
+acpi_pci_root_device(struct pci_host_bridge *bridge)
+{
+	return *((struct acpi_device **)bridge->private);
+}
 
 void acpi_pci_add_bus(struct pci_bus *bus);
 void acpi_pci_remove_bus(struct pci_bus *bus);
-- 
2.32.0


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

* [RFC 3/5] PCI: hv: Set NULL as the ACPI device for the PCI host bridge
  2021-08-11 15:36 [RFC 0/5] PCI: Use the private field of pci_host_bridge for ACPI device Boqun Feng
  2021-08-11 15:36 ` [RFC 1/5] PCI: Introduce pci_create_root_bus_priv() Boqun Feng
  2021-08-11 15:36 ` [RFC 2/5] PCI/ACPI: Store ACPI device information in the host bridge structure Boqun Feng
@ 2021-08-11 15:36 ` Boqun Feng
  2021-08-11 15:36 ` [RFC 4/5] arm64: PCI: Retrieve ACPI device information directly from host bridges Boqun Feng
  2021-08-11 15:36 ` [RFC 5/5] PCI: hv: Remove the dependency of pci_config_window Boqun Feng
  4 siblings, 0 replies; 6+ messages in thread
From: Boqun Feng @ 2021-08-11 15:36 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Catalin Marinas, Will Deacon, Bjorn Helgaas, Rafael J. Wysocki,
	Len Brown, K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger,
	Wei Liu, Dexuan Cui, Rob Herring, Krzysztof Wilczyński,
	Boqun Feng, linux-arm-kernel, linux-kernel, linux-pci,
	linux-acpi, linux-hyperv, Sunil Muthuswamy, Marc Zyngier,
	Arnd Bergmann

A PCI host bridge of Hyper-V doesn't have the corresponding ACPI device,
therefore a NULL pointer needs to be set as the ->private of
pci_host_bridge since for platforms with ACPI ->private is used to store
the ACPI device information for the host bridges.

And since kzalloc() is used to allocate pci_host_bridge, as a result,
what is needed is just setting the correct size of ->private, kzalloc()
will zero the field as if set a NULL pointer to it.

Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
---
 drivers/pci/controller/pci-hyperv.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index 62dbe98d1fe1..fd3792b5edcc 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -3021,7 +3021,12 @@ static int hv_pci_probe(struct hv_device *hdev,
 	 */
 	BUILD_BUG_ON(sizeof(*hbus) > HV_HYP_PAGE_SIZE);
 
-	bridge = devm_pci_alloc_host_bridge(&hdev->device, 0);
+	/*
+	 * devm_pci_alloc_host_bridge() use kzalloc(), and we want to set
+	 * ->private as a NULL pointer, therefore no need to set ->private after
+	 * allocation.
+	 */
+	bridge = devm_pci_alloc_host_bridge(&hdev->device, sizeof(struct acpi_device *));
 	if (!bridge)
 		return -ENOMEM;
 
-- 
2.32.0


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

* [RFC 4/5] arm64: PCI: Retrieve ACPI device information directly from host bridges
  2021-08-11 15:36 [RFC 0/5] PCI: Use the private field of pci_host_bridge for ACPI device Boqun Feng
                   ` (2 preceding siblings ...)
  2021-08-11 15:36 ` [RFC 3/5] PCI: hv: Set NULL as the ACPI device for the PCI host bridge Boqun Feng
@ 2021-08-11 15:36 ` Boqun Feng
  2021-08-11 15:36 ` [RFC 5/5] PCI: hv: Remove the dependency of pci_config_window Boqun Feng
  4 siblings, 0 replies; 6+ messages in thread
From: Boqun Feng @ 2021-08-11 15:36 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Catalin Marinas, Will Deacon, Bjorn Helgaas, Rafael J. Wysocki,
	Len Brown, K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger,
	Wei Liu, Dexuan Cui, Rob Herring, Krzysztof Wilczyński,
	Boqun Feng, linux-arm-kernel, linux-kernel, linux-pci,
	linux-acpi, linux-hyperv, Sunil Muthuswamy, Marc Zyngier,
	Arnd Bergmann

Now since we store the corresponding ACPI device pointer in the
->private of pci_host_bridge, use it instead of the sysdata to retrieve
the ACPI device information. Doing this decouples the dependency on the
pci_config_window structure in Hyper-V virtual PCI, because passing a
NULL pointer as the ACPI device is the soly reason of the dependency.

The decoupling avoids adding pci_config_window in hv_pcibus_dev and also
makes the code cleaner.

Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
---
 arch/arm64/kernel/pci.c | 14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
index 2276689b5411..783971749eb7 100644
--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -82,25 +82,13 @@ int acpi_pci_bus_find_domain_nr(struct pci_bus *bus)
 
 int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
 {
-	struct pci_config_window *cfg;
 	struct acpi_device *adev;
 	struct device *bus_dev;
 
 	if (acpi_disabled)
 		return 0;
 
-	cfg = bridge->bus->sysdata;
-
-	/*
-	 * On Hyper-V there is no corresponding ACPI device for a root bridge,
-	 * therefore ->parent is set as NULL by the driver. And set 'adev' as
-	 * NULL in this case because there is no proper ACPI device.
-	 */
-	if (!cfg->parent)
-		adev = NULL;
-	else
-		adev = to_acpi_device(cfg->parent);
-
+	adev = acpi_pci_root_device(bridge);
 	bus_dev = &bridge->bus->dev;
 
 	ACPI_COMPANION_SET(&bridge->dev, adev);
-- 
2.32.0


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

* [RFC 5/5] PCI: hv: Remove the dependency of pci_config_window
  2021-08-11 15:36 [RFC 0/5] PCI: Use the private field of pci_host_bridge for ACPI device Boqun Feng
                   ` (3 preceding siblings ...)
  2021-08-11 15:36 ` [RFC 4/5] arm64: PCI: Retrieve ACPI device information directly from host bridges Boqun Feng
@ 2021-08-11 15:36 ` Boqun Feng
  4 siblings, 0 replies; 6+ messages in thread
From: Boqun Feng @ 2021-08-11 15:36 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Catalin Marinas, Will Deacon, Bjorn Helgaas, Rafael J. Wysocki,
	Len Brown, K. Y. Srinivasan, Haiyang Zhang, Stephen Hemminger,
	Wei Liu, Dexuan Cui, Rob Herring, Krzysztof Wilczyński,
	Boqun Feng, linux-arm-kernel, linux-kernel, linux-pci,
	linux-acpi, linux-hyperv, Sunil Muthuswamy, Marc Zyngier,
	Arnd Bergmann

The ACPI device information is now correctly set via ->private of
pci_host_bridge, therefore no need to use pci_config_window in
hv_pcibus_device, so remove it.

Note we still need an empty pci_sysdata structure for non-x86, because
it's x86-specific.

Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
---
 drivers/pci/controller/pci-hyperv.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
index fd3792b5edcc..f2b977ef7b84 100644
--- a/drivers/pci/controller/pci-hyperv.c
+++ b/drivers/pci/controller/pci-hyperv.c
@@ -448,12 +448,17 @@ enum hv_pcibus_state {
 	hv_pcibus_maximum
 };
 
+/*
+ * Defines a empty struct for non-x86 architecture, this is OK because we only
+ * use this field as an "anchor" to get back to hv_pcibus_device object on
+ * non-x86 architecture.
+ */
+#ifndef CONFIG_X86
+struct pci_sysdata { };
+#endif
+
 struct hv_pcibus_device {
-#ifdef CONFIG_X86
 	struct pci_sysdata sysdata;
-#elif defined(CONFIG_ARM64)
-	struct pci_config_window sysdata;
-#endif
 	struct pci_host_bridge *bridge;
 	struct fwnode_handle *fwnode;
 	/* Protocol version negotiated with the host */
-- 
2.32.0


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

end of thread, other threads:[~2021-08-11 15:36 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-11 15:36 [RFC 0/5] PCI: Use the private field of pci_host_bridge for ACPI device Boqun Feng
2021-08-11 15:36 ` [RFC 1/5] PCI: Introduce pci_create_root_bus_priv() Boqun Feng
2021-08-11 15:36 ` [RFC 2/5] PCI/ACPI: Store ACPI device information in the host bridge structure Boqun Feng
2021-08-11 15:36 ` [RFC 3/5] PCI: hv: Set NULL as the ACPI device for the PCI host bridge Boqun Feng
2021-08-11 15:36 ` [RFC 4/5] arm64: PCI: Retrieve ACPI device information directly from host bridges Boqun Feng
2021-08-11 15:36 ` [RFC 5/5] PCI: hv: Remove the dependency of pci_config_window Boqun Feng

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).