linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7 0/5] EEH Support for PowerNV platform
@ 2013-06-20 10:13 Gavin Shan
  2013-06-20 10:13 ` [PATCH 1/5] powernv/opal: Notifier for OPAL events Gavin Shan
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Gavin Shan @ 2013-06-20 10:13 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan


It resends the last 5 patches ([27/31] - [31/31]) of the series to support EEH
for PowerNV platform.

v6 -> v7:
	* Use atomic notifier to replace the original OPAL notifier according
	  to Ben's suggestion.
	* Avoid registering duplicated notifiers for OPAL_EVENT_PCI_ERROR.

---

arch/powerpc/include/asm/opal.h           |    5 ++
arch/powerpc/platforms/powernv/eeh-ioda.c |   72 ++++++++++++++++++++++++++++-
arch/powerpc/platforms/powernv/opal.c     |   69 +++++++++++++++++++++++++++-
arch/powerpc/platforms/powernv/pci-ioda.c |   23 +++++++++
arch/powerpc/platforms/powernv/pci.h      |    4 ++
arch/powerpc/platforms/powernv/setup.c    |    4 ++
6 files changed, 175 insertions(+), 2 deletions(-)

Thanks,
Gavin

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

* [PATCH 1/5] powernv/opal: Notifier for OPAL events
  2013-06-20 10:13 [PATCH v7 0/5] EEH Support for PowerNV platform Gavin Shan
@ 2013-06-20 10:13 ` Gavin Shan
  2013-06-20 10:13 ` [PATCH 2/5] powernv/opal: Disable OPAL notifier upon poweroff Gavin Shan
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Gavin Shan @ 2013-06-20 10:13 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan

This patch implements a notifier to receive a notification on OPAL
event mask changes. The notifier is only called as a result of an OPAL
interrupt, which will happen upon reception of FSP messages or PCI errors.
Any event mask change detected as a result of opal_poll_events() will not
result in a notifier call.

[benh: changelog]
Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/opal.h       |    5 ++
 arch/powerpc/platforms/powernv/opal.c |   69 ++++++++++++++++++++++++++++++++-
 2 files changed, 73 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 2880797..029fe85 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -644,6 +644,11 @@ extern void hvc_opal_init_early(void);
 extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
 				   int depth, void *data);
 
+extern int opal_notifier_register(struct notifier_block *nb);
+extern void opal_notifier_enable(void);
+extern void opal_notifier_disable(void);
+extern void opal_notifier_update_evt(uint64_t evt_mask, uint64_t evt_val);
+
 extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
 extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
 
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 628c564..106301f 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -15,6 +15,7 @@
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/interrupt.h>
+#include <linux/notifier.h>
 #include <linux/slab.h>
 #include <asm/opal.h>
 #include <asm/firmware.h>
@@ -31,6 +32,10 @@ static DEFINE_SPINLOCK(opal_write_lock);
 extern u64 opal_mc_secondary_handler[];
 static unsigned int *opal_irqs;
 static unsigned int opal_irq_count;
+static ATOMIC_NOTIFIER_HEAD(opal_notifier_head);
+static DEFINE_SPINLOCK(opal_notifier_lock);
+static uint64_t last_notified_mask = 0x0ul;
+static atomic_t opal_notifier_hold = ATOMIC_INIT(0);
 
 int __init early_init_dt_scan_opal(unsigned long node,
 				   const char *uname, int depth, void *data)
@@ -95,6 +100,68 @@ static int __init opal_register_exception_handlers(void)
 
 early_initcall(opal_register_exception_handlers);
 
+int opal_notifier_register(struct notifier_block *nb)
+{
+	if (!nb) {
+		pr_warning("%s: Invalid argument (%p)\n",
+			   __func__, nb);
+		return -EINVAL;
+	}
+
+	atomic_notifier_chain_register(&opal_notifier_head, nb);
+	return 0;
+}
+
+static void opal_do_notifier(uint64_t events)
+{
+	unsigned long flags;
+	uint64_t changed_mask;
+
+	if (atomic_read(&opal_notifier_hold))
+		return;
+
+	spin_lock_irqsave(&opal_notifier_lock, flags);
+	changed_mask = last_notified_mask ^ events;
+	last_notified_mask = events;
+	spin_unlock_irqrestore(&opal_notifier_lock, flags);
+
+	/*
+	 * We feed with the event bits and changed bits for
+	 * enough information to the callback.
+	 */
+	atomic_notifier_call_chain(&opal_notifier_head,
+				   events, (void *)changed_mask);
+}
+
+void opal_notifier_update_evt(uint64_t evt_mask,
+			      uint64_t evt_val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&opal_notifier_lock, flags);
+	last_notified_mask &= ~evt_mask;
+	last_notified_mask |= evt_val;
+	spin_unlock_irqrestore(&opal_notifier_lock, flags);
+}
+
+void opal_notifier_enable(void)
+{
+	int64_t rc;
+	uint64_t evt = 0;
+
+	atomic_set(&opal_notifier_hold, 0);
+
+	/* Process pending events */
+	rc = opal_poll_events(&evt);
+	if (rc == OPAL_SUCCESS && evt)
+		opal_do_notifier(evt);
+}
+
+void opal_notifier_disable(void)
+{
+	atomic_set(&opal_notifier_hold, 1);
+}
+
 int opal_get_chars(uint32_t vtermno, char *buf, int count)
 {
 	s64 len, rc;
@@ -297,7 +364,7 @@ static irqreturn_t opal_interrupt(int irq, void *data)
 
 	opal_handle_interrupt(virq_to_hw(irq), &events);
 
-	/* XXX TODO: Do something with the events */
+	opal_do_notifier(events);
 
 	return IRQ_HANDLED;
 }
-- 
1.7.5.4

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

* [PATCH 2/5] powernv/opal: Disable OPAL notifier upon poweroff
  2013-06-20 10:13 [PATCH v7 0/5] EEH Support for PowerNV platform Gavin Shan
  2013-06-20 10:13 ` [PATCH 1/5] powernv/opal: Notifier for OPAL events Gavin Shan
@ 2013-06-20 10:13 ` Gavin Shan
  2013-06-20 10:13 ` [PATCH 3/5] powerpc/eeh: Register OPAL notifier for PCI error Gavin Shan
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Gavin Shan @ 2013-06-20 10:13 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan

While we're restarting or powering off the system, we needn't
the OPAL notifier any more. So just to disable that.

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/powernv/setup.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index d4459bf..84438af 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -93,6 +93,8 @@ static void  __noreturn pnv_restart(char *cmd)
 {
 	long rc = OPAL_BUSY;
 
+	opal_notifier_disable();
+
 	while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
 		rc = opal_cec_reboot();
 		if (rc == OPAL_BUSY_EVENT)
@@ -108,6 +110,8 @@ static void __noreturn pnv_power_off(void)
 {
 	long rc = OPAL_BUSY;
 
+	opal_notifier_disable();
+
 	while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
 		rc = opal_cec_power_down(0);
 		if (rc == OPAL_BUSY_EVENT)
-- 
1.7.5.4

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

* [PATCH 3/5] powerpc/eeh: Register OPAL notifier for PCI error
  2013-06-20 10:13 [PATCH v7 0/5] EEH Support for PowerNV platform Gavin Shan
  2013-06-20 10:13 ` [PATCH 1/5] powernv/opal: Notifier for OPAL events Gavin Shan
  2013-06-20 10:13 ` [PATCH 2/5] powernv/opal: Disable OPAL notifier upon poweroff Gavin Shan
@ 2013-06-20 10:13 ` Gavin Shan
  2013-06-20 10:13 ` [PATCH 4/5] powerpc/powernv: Debugfs directory for PHB Gavin Shan
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Gavin Shan @ 2013-06-20 10:13 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan

The patch registers OPAL event notifier and process the PCI errors
from firmware. If we have pending PCI errors, special EEH event
(without binding PE) will be sent to EEH core for processing.

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/powernv/eeh-ioda.c |   41 ++++++++++++++++++++++++++++-
 1 files changed, 40 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c
index a3eebd1..2b7689e 100644
--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
+++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
@@ -18,6 +18,7 @@
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/msi.h>
+#include <linux/notifier.h>
 #include <linux/pci.h>
 #include <linux/string.h>
 
@@ -42,6 +43,26 @@
 #endif
 
 static char *hub_diag = NULL;
+static int ioda_eeh_nb_init = 0;
+
+static int ioda_eeh_event(struct notifier_block *nb,
+			  unsigned long events, void *change)
+{
+	uint64_t changed_evts = (uint64_t)change;
+
+	/* We simply send special EEH event */
+	if ((changed_evts & OPAL_EVENT_PCI_ERROR) &&
+	    (events & OPAL_EVENT_PCI_ERROR))
+		eeh_send_failure_event(NULL);
+
+	return 0;
+}
+
+static struct notifier_block ioda_eeh_nb = {
+	.notifier_call	= ioda_eeh_event,
+	.next		= NULL,
+	.priority	= 0
+};
 
 /**
  * ioda_eeh_post_init - Chip dependent post initialization
@@ -54,6 +75,19 @@ static char *hub_diag = NULL;
 static int ioda_eeh_post_init(struct pci_controller *hose)
 {
 	struct pnv_phb *phb = hose->private_data;
+	int ret;
+
+	/* Register OPAL event notifier */
+	if (!ioda_eeh_nb_init) {
+		ret = opal_notifier_register(&ioda_eeh_nb);
+		if (ret) {
+			pr_err("%s: Can't register OPAL event notifier (%d)\n",
+			       __func__, ret);
+			return ret;
+		}
+
+		ioda_eeh_nb_init = 1;
+	}
 
 	/* FIXME: Enable it for PHB3 later */
 	if (phb->type == PNV_PHB_IODA1) {
@@ -736,8 +770,13 @@ static int ioda_eeh_next_error(struct eeh_pe **pe)
 	long rc;
 	int ret = 1;
 
-	/* While running here, it's safe to purge the event queue */
+	/*
+	 * While running here, it's safe to purge the event queue.
+	 * And we should keep the cached OPAL notifier event sychronized
+	 * between the kernel and firmware.
+	 */
 	eeh_remove_event(NULL);
+	opal_notifier_update_evt(OPAL_EVENT_PCI_ERROR, 0x0ul);
 
 	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
 		/*
-- 
1.7.5.4

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

* [PATCH 4/5] powerpc/powernv: Debugfs directory for PHB
  2013-06-20 10:13 [PATCH v7 0/5] EEH Support for PowerNV platform Gavin Shan
                   ` (2 preceding siblings ...)
  2013-06-20 10:13 ` [PATCH 3/5] powerpc/eeh: Register OPAL notifier for PCI error Gavin Shan
@ 2013-06-20 10:13 ` Gavin Shan
  2013-06-20 10:13 ` [PATCH 5/5] powerpc/eeh: Debugfs for error injection Gavin Shan
  2013-06-20 10:17 ` [PATCH v7 0/5] EEH Support for PowerNV platform Gavin Shan
  5 siblings, 0 replies; 7+ messages in thread
From: Gavin Shan @ 2013-06-20 10:13 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan

The patch creates one debugfs directory ("powerpc/PCIxxxx") for
each PHB so that we can hook EEH error injection debugfs entry
there in proceeding patch.

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/powernv/pci-ioda.c |   23 +++++++++++++++++++++++
 arch/powerpc/platforms/powernv/pci.h      |    4 ++++
 2 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 48b0940..3e5c3d5 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -13,6 +13,7 @@
 
 #include <linux/kernel.h>
 #include <linux/pci.h>
+#include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/init.h>
@@ -32,6 +33,7 @@
 #include <asm/iommu.h>
 #include <asm/tce.h>
 #include <asm/xics.h>
+#include <asm/debug.h>
 
 #include "powernv.h"
 #include "pci.h"
@@ -968,12 +970,33 @@ static void pnv_pci_ioda_setup_DMA(void)
 	}
 }
 
+static void pnv_pci_ioda_create_dbgfs(void)
+{
+#ifdef CONFIG_DEBUG_FS
+	struct pci_controller *hose, *tmp;
+	struct pnv_phb *phb;
+	char name[16];
+
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+		phb = hose->private_data;
+
+		sprintf(name, "PCI%04x", hose->global_number);
+		phb->dbgfs = debugfs_create_dir(name, powerpc_debugfs_root);
+		if (!phb->dbgfs)
+			pr_warning("%s: Error on creating debugfs on PHB#%x\n",
+				__func__, hose->global_number);
+	}
+#endif /* CONFIG_DEBUG_FS */
+}
+
 static void pnv_pci_ioda_fixup(void)
 {
 	pnv_pci_ioda_setup_PEs();
 	pnv_pci_ioda_setup_seg();
 	pnv_pci_ioda_setup_DMA();
 
+	pnv_pci_ioda_create_dbgfs();
+
 #ifdef CONFIG_EEH
 	eeh_addr_cache_build();
 	eeh_init();
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index 3656a240..43906e3 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -96,6 +96,10 @@ struct pnv_phb {
 	int			removed;
 #endif
 
+#ifdef CONFIG_DEBUG_FS
+	struct dentry		*dbgfs;
+#endif
+
 #ifdef CONFIG_PCI_MSI
 	unsigned int		msi_base;
 	unsigned int		msi32_support;
-- 
1.7.5.4

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

* [PATCH 5/5] powerpc/eeh: Debugfs for error injection
  2013-06-20 10:13 [PATCH v7 0/5] EEH Support for PowerNV platform Gavin Shan
                   ` (3 preceding siblings ...)
  2013-06-20 10:13 ` [PATCH 4/5] powerpc/powernv: Debugfs directory for PHB Gavin Shan
@ 2013-06-20 10:13 ` Gavin Shan
  2013-06-20 10:17 ` [PATCH v7 0/5] EEH Support for PowerNV platform Gavin Shan
  5 siblings, 0 replies; 7+ messages in thread
From: Gavin Shan @ 2013-06-20 10:13 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan

The patch creates debugfs entries (powerpc/PCIxxxx/err_injct) for
injecting EEH errors for testing purpose.

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/powernv/eeh-ioda.c |   31 +++++++++++++++++++++++++++++
 1 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c
index 2b7689e..84f3036 100644
--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
+++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
@@ -12,6 +12,7 @@
  */
 
 #include <linux/bootmem.h>
+#include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/io.h>
@@ -64,6 +65,29 @@ static struct notifier_block ioda_eeh_nb = {
 	.priority	= 0
 };
 
+#ifdef CONFIG_DEBUG_FS
+static int ioda_eeh_dbgfs_set(void *data, u64 val)
+{
+	struct pci_controller *hose = data;
+	struct pnv_phb *phb = hose->private_data;
+
+	out_be64(phb->regs + 0xD10, val);
+	return 0;
+}
+
+static int ioda_eeh_dbgfs_get(void *data, u64 *val)
+{
+	struct pci_controller *hose = data;
+	struct pnv_phb *phb = hose->private_data;
+
+	*val = in_be64(phb->regs + 0xD10);
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_dbgfs_ops, ioda_eeh_dbgfs_get,
+			ioda_eeh_dbgfs_set, "0x%llx\n");
+#endif /* CONFIG_DEBUG_FS */
+
 /**
  * ioda_eeh_post_init - Chip dependent post initialization
  * @hose: PCI controller
@@ -101,6 +125,13 @@ static int ioda_eeh_post_init(struct pci_controller *hose)
 			}
 		}
 
+#ifdef CONFIG_DEBUG_FS
+		if (phb->dbgfs)
+			debugfs_create_file("err_injct", 0600,
+					    phb->dbgfs, hose,
+					    &ioda_eeh_dbgfs_ops);
+#endif
+
 		phb->eeh_enabled = 1;
 	}
 
-- 
1.7.5.4

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

* Re: [PATCH v7 0/5] EEH Support for PowerNV platform
  2013-06-20 10:13 [PATCH v7 0/5] EEH Support for PowerNV platform Gavin Shan
                   ` (4 preceding siblings ...)
  2013-06-20 10:13 ` [PATCH 5/5] powerpc/eeh: Debugfs for error injection Gavin Shan
@ 2013-06-20 10:17 ` Gavin Shan
  5 siblings, 0 replies; 7+ messages in thread
From: Gavin Shan @ 2013-06-20 10:17 UTC (permalink / raw)
  To: Gavin Shan; +Cc: linuxppc-dev

On Thu, Jun 20, 2013 at 06:13:21PM +0800, Gavin Shan wrote:
>
>It resends the last 5 patches ([27/31] - [31/31]) of the series to support EEH
>for PowerNV platform.
>
>v6 -> v7:
>	* Use atomic notifier to replace the original OPAL notifier according
>	  to Ben's suggestion.
>	* Avoid registering duplicated notifiers for OPAL_EVENT_PCI_ERROR.
>

It also fixes the problem pointed by Mikey:

	* Included <asm/debug.h> in pci-ioda.c for correct reference to
	  "powerpc_debugfs_root".

Thanks,
Gavin

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

end of thread, other threads:[~2013-06-20 10:44 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-20 10:13 [PATCH v7 0/5] EEH Support for PowerNV platform Gavin Shan
2013-06-20 10:13 ` [PATCH 1/5] powernv/opal: Notifier for OPAL events Gavin Shan
2013-06-20 10:13 ` [PATCH 2/5] powernv/opal: Disable OPAL notifier upon poweroff Gavin Shan
2013-06-20 10:13 ` [PATCH 3/5] powerpc/eeh: Register OPAL notifier for PCI error Gavin Shan
2013-06-20 10:13 ` [PATCH 4/5] powerpc/powernv: Debugfs directory for PHB Gavin Shan
2013-06-20 10:13 ` [PATCH 5/5] powerpc/eeh: Debugfs for error injection Gavin Shan
2013-06-20 10:17 ` [PATCH v7 0/5] EEH Support for PowerNV platform Gavin Shan

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