diff mbox series

[2/2] pci: Make fast reboot creset PHBs in parallel

Message ID 20180222002652.31721-2-mikey@neuling.org
State Accepted
Headers show
Series [1/2] pci: Move code around | expand

Commit Message

Michael Neuling Feb. 22, 2018, 12:26 a.m. UTC
In this patch, we added a creset to the fast reboot path:

  commit a1eba9d29d17ff44fca1293b071023a9fbf4b938
  Author: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
  fast-reboot: creset PHBs on fast reboot

Unfortunately, this does the creset in serial rather than in
parallel.

This patch changes the creset on fast reboot to operate in
parallel. It simplifies the code by abstracting pci_init_slots() so
that it can be used on boot and fast reboot to perform all the PCI
retraining.

This improves fast reboot PCI training on a dual chip P9 from ~12
seconds down to ~2 seconds. Similar improvements for P8 are achieved
as well.

This means the time to download the BOOTKERNEL is the bottleneck for
fast reboot.

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
 core/pci.c | 51 +++++++++++++++++++++------------------------------
 1 file changed, 21 insertions(+), 30 deletions(-)

Comments

Russell Currey Feb. 22, 2018, 2:25 a.m. UTC | #1
On Thu, 2018-02-22 at 11:26 +1100, Michael Neuling wrote:
> In this patch, we added a creset to the fast reboot path:
> 
>   commit a1eba9d29d17ff44fca1293b071023a9fbf4b938
>   Author: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
>   fast-reboot: creset PHBs on fast reboot
> 
> Unfortunately, this does the creset in serial rather than in
> parallel.
> 
> This patch changes the creset on fast reboot to operate in
> parallel. It simplifies the code by abstracting pci_init_slots() so
> that it can be used on boot and fast reboot to perform all the PCI
> retraining.
> 
> This improves fast reboot PCI training on a dual chip P9 from ~12
> seconds down to ~2 seconds. Similar improvements for P8 are achieved
> as well.
> 
> This means the time to download the BOOTKERNEL is the bottleneck for
> fast reboot.
> 
> Signed-off-by: Michael Neuling <mikey@neuling.org>
> 
Reviewed-by: Russell Currey <ruscur@russell.cc>
Andrew Donnellan Feb. 22, 2018, 2:59 a.m. UTC | #2
On 22/02/18 11:26, Michael Neuling wrote:
> In this patch, we added a creset to the fast reboot path:
> 
>    commit a1eba9d29d17ff44fca1293b071023a9fbf4b938
>    Author: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
>    fast-reboot: creset PHBs on fast reboot
> 
> Unfortunately, this does the creset in serial rather than in
> parallel.
> 
> This patch changes the creset on fast reboot to operate in
> parallel. It simplifies the code by abstracting pci_init_slots() so
> that it can be used on boot and fast reboot to perform all the PCI
> retraining.
> 
> This improves fast reboot PCI training on a dual chip P9 from ~12
> seconds down to ~2 seconds. Similar improvements for P8 are achieved
> as well.
> 
> This means the time to download the BOOTKERNEL is the bottleneck for
> fast reboot.
> 
> Signed-off-by: Michael Neuling <mikey@neuling.org>

Acked-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
Nicholas Piggin Feb. 23, 2018, 3:17 a.m. UTC | #3
On Thu, 22 Feb 2018 11:26:52 +1100
Michael Neuling <mikey@neuling.org> wrote:

> In this patch, we added a creset to the fast reboot path:
> 
>   commit a1eba9d29d17ff44fca1293b071023a9fbf4b938
>   Author: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
>   fast-reboot: creset PHBs on fast reboot
> 
> Unfortunately, this does the creset in serial rather than in
> parallel.
> 
> This patch changes the creset on fast reboot to operate in
> parallel. It simplifies the code by abstracting pci_init_slots() so
> that it can be used on boot and fast reboot to perform all the PCI
> retraining.
> 
> This improves fast reboot PCI training on a dual chip P9 from ~12
> seconds down to ~2 seconds. Similar improvements for P8 are achieved
> as well.

Very nice result!
Stewart Smith March 1, 2018, 4:03 a.m. UTC | #4
Michael Neuling <mikey@neuling.org> writes:
> In this patch, we added a creset to the fast reboot path:
>
>   commit a1eba9d29d17ff44fca1293b071023a9fbf4b938
>   Author: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
>   fast-reboot: creset PHBs on fast reboot
>
> Unfortunately, this does the creset in serial rather than in
> parallel.
>
> This patch changes the creset on fast reboot to operate in
> parallel. It simplifies the code by abstracting pci_init_slots() so
> that it can be used on boot and fast reboot to perform all the PCI
> retraining.
>
> This improves fast reboot PCI training on a dual chip P9 from ~12
> seconds down to ~2 seconds. Similar improvements for P8 are achieved
> as well.
>
> This means the time to download the BOOTKERNEL is the bottleneck for
> fast reboot.
>
> Signed-off-by: Michael Neuling <mikey@neuling.org>
> ---
>  core/pci.c | 51 +++++++++++++++++++++------------------------------
>  1 file changed, 21 insertions(+), 30 deletions(-)

Cheers, fast reboot being even faster is always a bonus!

Series merged to master as of fe6d86b92a0054f7f063cd957091889f4ccd853a
diff mbox series

Patch

diff --git a/core/pci.c b/core/pci.c
index 2ed3e05d15..e4b824aa9b 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -973,13 +973,13 @@  static void pci_reset_phb(void *data)
 	struct pci_slot *slot = phb->slot;
 	int64_t rc;
 
-	if (!slot || !slot->ops.freset) {
-		PCINOTICE(phb, 0, "Cannot issue fundamental reset\n");
+	if (!slot || !slot->ops.run_sm) {
+		PCINOTICE(phb, 0, "Cannot issue reset\n");
 		return;
 	}
 
 	pci_slot_add_flags(slot, PCI_SLOT_FLAG_BOOTUP);
-	rc = slot->ops.freset(slot);
+	rc = slot->ops.run_sm(slot);
 	while (rc > 0) {
 		PCITRACE(phb, 0, "Waiting %ld ms\n", tb_to_msecs(rc));
 		time_wait(rc);
@@ -987,7 +987,7 @@  static void pci_reset_phb(void *data)
 	}
 	pci_slot_remove_flags(slot, PCI_SLOT_FLAG_BOOTUP);
 	if (rc < 0)
-		PCIERR(phb, 0, "Error %lld fundamental resetting\n", rc);
+		PCIERR(phb, 0, "Error %lld resetting\n", rc);
 }
 
 static void pci_scan_phb(void *data)
@@ -1680,7 +1680,7 @@  static void pci_do_jobs(void (*fn)(void *))
 	free(jobs);
 }
 
-void pci_init_slots(void)
+static void __pci_init_slots(void)
 {
 	unsigned int i;
 
@@ -1748,46 +1748,37 @@  static void __pci_reset(struct list_head *list)
 int64_t pci_reset(void)
 {
 	unsigned int i;
-	struct pci_slot *slot;
-	int64_t rc;
 
 	prlog(PR_NOTICE, "PCI: Clearing all devices...\n");
 
-	/* XXX Do those in parallel (at least the power up
-	 * state machine could be done in parallel)
-	 */
 	for (i = 0; i < ARRAY_SIZE(phbs); i++) {
 		struct phb *phb = phbs[i];
 		if (!phb)
 			continue;
 		__pci_reset(&phb->devices);
 
-		slot = phb->slot;
-		if (!slot || !slot->ops.creset) {
-			PCINOTICE(phb, 0, "Can't do complete reset\n");
-		} else {
-			rc = slot->ops.creset(slot);
-			while (rc > 0) {
-				time_wait(rc);
-				rc = slot->ops.run_sm(slot);
-			}
-			if (rc < 0) {
-				PCIERR(phb, 0, "Complete reset failed "
-				               "(rc=%lld)\n", rc);
-				return rc;
-			}
-		}
-
-		if (phb->ops->ioda_reset)
-			phb->ops->ioda_reset(phb, true);
+		pci_slot_set_state(phb->slot, PCI_SLOT_STATE_CRESET_START);
 	}
 
-	/* Re-Initialize all discovered PCI slots */
-	pci_init_slots();
+	/* Do init and discovery of PCI slots in parallel */
+	__pci_init_slots();
 
 	return 0;
 }
 
+void pci_init_slots(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(phbs); i++) {
+		struct phb *phb = phbs[i];
+		if (!phb)
+			continue;
+		pci_slot_set_state(phb->slot, PCI_SLOT_STATE_FRESET_POWER_OFF);
+	}
+	__pci_init_slots();
+}
+
 /*
  * Complete iteration on current level before switching to
  * child level, which is the proper order for restoring