linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sergey Miroshnichenko <s.miroshnichenko@yadro.com>
To: <linux-pci@vger.kernel.org>, <linuxppc-dev@lists.ozlabs.org>
Cc: Bjorn Helgaas <helgaas@kernel.org>, <linux@yadro.com>,
	Sergey Miroshnichenko <s.miroshnichenko@yadro.com>
Subject: [PATCH RFC 10/11] PCI: hotplug: movable bus numbers: rename proc and sysfs entries
Date: Thu, 24 Oct 2019 20:21:56 +0300	[thread overview]
Message-ID: <20191024172157.878735-11-s.miroshnichenko@yadro.com> (raw)
In-Reply-To: <20191024172157.878735-1-s.miroshnichenko@yadro.com>

Changing the number of a bus (therefore changing addresses of this bus, of
its children and all the buses next in the tree) invalidates entries in
/sys/devices/pci*, /proc/bus/pci/* and symlinks in /sys/bus/pci/devices/*
for all the renamed devices and buses.

Remove the affected proc and sysfs entries and symlinks before renaming the
bus, then created them back.

Signed-off-by: Sergey Miroshnichenko <s.miroshnichenko@yadro.com>
---
 drivers/pci/probe.c | 105 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 104 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index be9e5754cac7..fe9bf012ef33 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1096,12 +1096,99 @@ static void pci_enable_crs(struct pci_dev *pdev)
 					 PCI_EXP_RTCTL_CRSSVE);
 }
 
+static void pci_buses_remove_sysfs(int domain, int busnr, int max_bus_number)
+{
+	struct pci_bus *bus;
+	struct pci_dev *dev = NULL;
+
+	bus = pci_find_bus(domain, busnr);
+	if (!bus)
+		return;
+
+	if (busnr < max_bus_number)
+		pci_buses_remove_sysfs(domain, busnr + 1, max_bus_number);
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		device_remove_class_symlinks(&dev->dev);
+		pci_remove_sysfs_dev_files(dev);
+		pci_proc_detach_device(dev);
+		bus_disconnect_device(&dev->dev);
+	}
+
+	device_remove_class_symlinks(&bus->dev);
+	pci_proc_detach_bus(bus);
+}
+
+static void pci_buses_create_sysfs(int domain, int busnr, int max_bus_number)
+{
+	struct pci_bus *bus;
+	struct pci_dev *dev = NULL;
+
+	bus = pci_find_bus(domain, busnr);
+	if (!bus)
+		return;
+
+	device_add_class_symlinks(&bus->dev);
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		bus_add_device(&dev->dev);
+		if (pci_dev_is_added(dev)) {
+			pci_proc_attach_device(dev);
+			pci_create_sysfs_dev_files(dev);
+			device_add_class_symlinks(&dev->dev);
+		}
+	}
+
+	if (busnr < max_bus_number)
+		pci_buses_create_sysfs(domain, busnr + 1, max_bus_number);
+}
+
+static void pci_rename_bus(struct pci_bus *bus, const char *new_bus_name)
+{
+	struct class *class;
+	int err;
+
+	class = bus->dev.class;
+	bus->dev.class = NULL;
+	err = device_rename(&bus->dev, new_bus_name);
+	bus->dev.class = class;
+}
+
+static void pci_rename_bus_devices(struct pci_bus *bus, const int domain,
+				   const int new_busnr)
+{
+	struct pci_dev *dev = NULL;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		char old_name[64];
+		char new_name[64];
+		struct class *class;
+		int err;
+		int i;
+
+		strncpy(old_name, dev_name(&dev->dev), sizeof(old_name));
+		sprintf(new_name, "%04x:%02x:%02x.%d", domain, new_busnr,
+			PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+		class = dev->dev.class;
+		dev->dev.class = NULL;
+		err = device_rename(&dev->dev, new_name);
+		dev->dev.class = class;
+
+		for (i = 0; i < PCI_BRIDGE_RESOURCES; i++)
+			dev->resource[i].name = pci_name(dev);
+	}
+}
+
 static void pci_do_move_buses(const int domain, int busnr, int first_moved_busnr,
 			      int delta, const struct resource *valid_range)
 {
 	struct pci_bus *bus;
-	int subordinate;
+	int subordinate, old_primary;
 	u32 old_buses, buses;
+	char old_bus_name[64];
+	char new_bus_name[64];
+	struct resource old_res;
+	int new_busnr = busnr + delta;
 
 	if (busnr < valid_range->start || busnr > valid_range->end)
 		return;
@@ -1110,11 +1197,21 @@ static void pci_do_move_buses(const int domain, int busnr, int first_moved_busnr
 	if (!bus)
 		return;
 
+	old_primary = bus->primary;
+	strncpy(old_bus_name, dev_name(&bus->dev), sizeof(old_bus_name));
+	sprintf(new_bus_name, "%04x:%02x", domain, new_busnr);
+
 	if (delta > 0) {
 		pci_do_move_buses(domain, busnr + 1, first_moved_busnr,
 				  delta, valid_range);
+		pci_rename_bus_devices(bus, domain, new_busnr);
+		pci_rename_bus(bus, new_bus_name);
+	} else {
+		pci_rename_bus(bus, new_bus_name);
+		pci_rename_bus_devices(bus, domain, new_busnr);
 	}
 
+	memcpy(&old_res, &bus->busn_res, sizeof(old_res));
 	bus->number += delta;
 	bus->busn_res.start += delta;
 
@@ -1132,6 +1229,10 @@ static void pci_do_move_buses(const int domain, int busnr, int first_moved_busnr
 	buses |= (unsigned int)(subordinate << 16);
 	pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses);
 
+	dev_warn(&bus->dev, "Renamed bus %s (%02x-%pR) to %s (%02x-%pR)\n",
+		 old_bus_name, old_primary, &old_res,
+		 new_bus_name, bus->primary, &bus->busn_res);
+
 	if (delta < 0)
 		pci_do_move_buses(domain, busnr + 1, first_moved_busnr,
 				  delta, valid_range);
@@ -1192,8 +1293,10 @@ static int pci_move_buses(int domain, int busnr, int delta,
 		}
 	}
 
+	pci_buses_remove_sysfs(domain, busnr, valid_range->end);
 	pci_do_move_buses(domain, busnr, busnr,
 			  delta, valid_range);
+	pci_buses_create_sysfs(domain, busnr + delta, valid_range->end);
 
 	return 0;
 }
-- 
2.23.0


  parent reply	other threads:[~2019-10-24 17:22 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-24 17:21 [PATCH RFC 00/11] PCI: hotplug: Movable bus numbers Sergey Miroshnichenko
2019-10-24 17:21 ` [PATCH RFC 01/11] PCI: sysfs: Nullify freed pointers Sergey Miroshnichenko
2019-10-24 17:21 ` [PATCH RFC 02/11] PCI: proc: Nullify a freed pointer Sergey Miroshnichenko
2019-10-24 17:21 ` [PATCH RFC 03/11] drivers: base: Make bus_add_device() public Sergey Miroshnichenko
2019-10-24 17:21 ` [PATCH RFC 04/11] drivers: base: Make device_{add|remove}_class_symlinks() public Sergey Miroshnichenko
2019-10-24 17:21 ` [PATCH RFC 05/11] drivers: base: Add bus_disconnect_device() Sergey Miroshnichenko
2019-10-24 17:21 ` [PATCH RFC 06/11] powerpc/pci: Enable assigning bus numbers instead of reading them from DT Sergey Miroshnichenko
2019-10-24 17:21 ` [PATCH RFC 07/11] powerpc/pci: Don't reduce the host bridge bus range Sergey Miroshnichenko
2019-10-24 17:21 ` [PATCH RFC 08/11] PCI: Allow expanding the bridges Sergey Miroshnichenko
2019-10-24 17:21 ` [PATCH RFC 09/11] PCI: hotplug: Add initial support for movable bus numbers Sergey Miroshnichenko
2019-10-24 17:21 ` Sergey Miroshnichenko [this message]
2019-10-24 17:21 ` [PATCH RFC 11/11] PCI: hotplug: movable bus numbers: compact the gaps in numbering Sergey Miroshnichenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191024172157.878735-11-s.miroshnichenko@yadro.com \
    --to=s.miroshnichenko@yadro.com \
    --cc=helgaas@kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux@yadro.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).