LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/4] perf/Power7: Use macros to identify perf events
From: Sukadev Bhattiprolu @ 2012-11-07 19:18 UTC (permalink / raw)
  To: Peter Zijlstra, Paul Mackerras, Ingo Molnar,
	Arnaldo Carvalho de Melo, Anton Blanchard, robert.richter
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20121107191818.GA16211@us.ibm.com>


>From 8a0dbd8f3fce2834292efa50c15ca64d4f6a6536 Mon Sep 17 00:00:00 2001
From: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Date: Wed, 7 Nov 2012 09:36:14 -0800
Subject: [PATCH 2/4] perf/Power7: Use macros to identify perf events

Define and use macros to identify perf events codes This would make it
easier and more readable when these event codes need to be used in more
than one place.

Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
---
 arch/powerpc/perf/power7-pmu.c |   25 +++++++++++++++++--------
 1 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c
index 441af08..256db4f 100644
--- a/arch/powerpc/perf/power7-pmu.c
+++ b/arch/powerpc/perf/power7-pmu.c
@@ -295,15 +295,24 @@ static void power7_disable_pmc(unsigned int pmc, unsigned long mmcr[])
 		mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SH(pmc));
 }
 
+#define	PM_CYC				0x1e
+#define	PM_GCT_NOSLOT_CYC		0x100f8
+#define	PM_CMPLU_STALL			0x4000a
+#define	PM_INST_CMPL			0x2
+#define	PM_LD_REF_L1			0xc880
+#define	PM_LD_MISS_L1			0x400f0
+#define	PM_BRU_FIN			0x10068
+#define	PM_BRU_MPRED			0x400f6
+
 static int power7_generic_events[] = {
-	[PERF_COUNT_HW_CPU_CYCLES] = 0x1e,
-	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x100f8, /* GCT_NOSLOT_CYC */
-	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x4000a,  /* CMPLU_STALL */
-	[PERF_COUNT_HW_INSTRUCTIONS] = 2,
-	[PERF_COUNT_HW_CACHE_REFERENCES] = 0xc880,	/* LD_REF_L1_LSU*/
-	[PERF_COUNT_HW_CACHE_MISSES] = 0x400f0,		/* LD_MISS_L1	*/
-	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x10068,	/* BRU_FIN	*/
-	[PERF_COUNT_HW_BRANCH_MISSES] = 0x400f6,	/* BR_MPRED	*/
+	[PERF_COUNT_HW_CPU_CYCLES] = 			PM_CYC,
+	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 	PM_GCT_NOSLOT_CYC,
+	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 	PM_CMPLU_STALL,
+	[PERF_COUNT_HW_INSTRUCTIONS] = 			PM_INST_CMPL,
+	[PERF_COUNT_HW_CACHE_REFERENCES] = 		PM_LD_REF_L1,
+	[PERF_COUNT_HW_CACHE_MISSES] = 			PM_LD_MISS_L1,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 		PM_BRU_FIN,
+	[PERF_COUNT_HW_BRANCH_MISSES] = 		PM_BRU_MPRED,
 };
 
 #define C(x)	PERF_COUNT_HW_CACHE_##x
-- 
1.7.1

^ permalink raw reply related

* Re: [PATCH][V2] powerpc/fsl-pci: Add PCI controller ATMU PM support
From: Timur Tabi @ 2012-11-07 15:57 UTC (permalink / raw)
  To: Jia Hongtao; +Cc: B07421, linuxppc-dev
In-Reply-To: <1352275806-5754-1-git-send-email-B38951@freescale.com>

Jia Hongtao wrote:
> Power supply for PCI controller ATMU registers is off when system go to
> deep-sleep state. So ATMU registers should be re-setup during PCI
> controllers resume from sleep.
> 
> Signed-off-by: Jia Hongtao <B38951@freescale.com>
> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
>  arch/powerpc/sysdev/fsl_pci.c |   37 +++++++++++++++++++++++++++++++++++--
>  1 files changed, 35 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
> index ffb93ae..e6ab952 100644
> --- a/arch/powerpc/sysdev/fsl_pci.c
> +++ b/arch/powerpc/sysdev/fsl_pci.c
> @@ -89,7 +89,7 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
>  	return 0;
>  }
>  
> -static int __init setup_one_atmu(struct ccsr_pci __iomem *pci,
> +static int setup_one_atmu(struct ccsr_pci __iomem *pci,
>  	unsigned int index, const struct resource *res,
>  	resource_size_t offset)
>  {
> @@ -126,7 +126,7 @@ static int __init setup_one_atmu(struct ccsr_pci __iomem *pci,
>  }
>  
>  /* atmu setup for fsl pci/pcie controller */
> -static void __init setup_pci_atmu(struct pci_controller *hose,
> +static void setup_pci_atmu(struct pci_controller *hose,
>  				  struct resource *rsrc)
>  {
>  	struct ccsr_pci __iomem *pci;
> @@ -902,9 +902,42 @@ static int __devinit fsl_pci_probe(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_PM
> +static int fsl_pci_resume(struct device *dev)
> +{
> +	struct pci_controller *hose;
> +	struct resource pci_rsrc;
> +
> +	hose = pci_find_hose_for_OF_device(dev->of_node);
> +	if (!hose)
> +		return -ENODEV;
> +
> +	if (of_address_to_resource(dev->of_node, 0, &pci_rsrc)) {
> +		pr_warning("Get pci register base failed");
> +		return -ENOMEM;

dev_err

and it's not -ENOMEM.  ENOMEM means that you've run out of memory.  This
should also be ENODEV.

> +	}
> +
> +	setup_pci_atmu(hose, &pci_rsrc);
> +
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops pci_pm_ops = {
> +	.resume = fsl_pci_resume,
> +};
> +
> +#define PCI_PM_OPS (&pci_pm_ops)
> +
> +#else
> +
> +#define PCI_PM_OPS NULL
> +
> +#endif
> +
>  static struct platform_driver fsl_pci_driver = {
>  	.driver = {
>  		.name = "fsl-pci",
> +		.pm = PCI_PM_OPS,
>  		.of_match_table = pci_ids,
>  	},
>  	.probe = fsl_pci_probe,
> 


-- 
Timur Tabi
Linux kernel developer at Freescale

^ permalink raw reply

* [PATCH][V2] powerpc/fsl-pci: Add PCI controller ATMU PM support
From: Jia Hongtao @ 2012-11-07  8:10 UTC (permalink / raw)
  To: linuxppc-dev, galak; +Cc: B07421, B04825, b38951

Power supply for PCI controller ATMU registers is off when system go to
deep-sleep state. So ATMU registers should be re-setup during PCI
controllers resume from sleep.

Signed-off-by: Jia Hongtao <B38951@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
 arch/powerpc/sysdev/fsl_pci.c |   37 +++++++++++++++++++++++++++++++++++--
 1 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index ffb93ae..e6ab952 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -89,7 +89,7 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
 	return 0;
 }
 
-static int __init setup_one_atmu(struct ccsr_pci __iomem *pci,
+static int setup_one_atmu(struct ccsr_pci __iomem *pci,
 	unsigned int index, const struct resource *res,
 	resource_size_t offset)
 {
@@ -126,7 +126,7 @@ static int __init setup_one_atmu(struct ccsr_pci __iomem *pci,
 }
 
 /* atmu setup for fsl pci/pcie controller */
-static void __init setup_pci_atmu(struct pci_controller *hose,
+static void setup_pci_atmu(struct pci_controller *hose,
 				  struct resource *rsrc)
 {
 	struct ccsr_pci __iomem *pci;
@@ -902,9 +902,42 @@ static int __devinit fsl_pci_probe(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int fsl_pci_resume(struct device *dev)
+{
+	struct pci_controller *hose;
+	struct resource pci_rsrc;
+
+	hose = pci_find_hose_for_OF_device(dev->of_node);
+	if (!hose)
+		return -ENODEV;
+
+	if (of_address_to_resource(dev->of_node, 0, &pci_rsrc)) {
+		pr_warning("Get pci register base failed");
+		return -ENOMEM;
+	}
+
+	setup_pci_atmu(hose, &pci_rsrc);
+
+	return 0;
+}
+
+static const struct dev_pm_ops pci_pm_ops = {
+	.resume = fsl_pci_resume,
+};
+
+#define PCI_PM_OPS (&pci_pm_ops)
+
+#else
+
+#define PCI_PM_OPS NULL
+
+#endif
+
 static struct platform_driver fsl_pci_driver = {
 	.driver = {
 		.name = "fsl-pci",
+		.pm = PCI_PM_OPS,
 		.of_match_table = pci_ids,
 	},
 	.probe = fsl_pci_probe,
-- 
1.7.5.1

^ permalink raw reply related

* [PATCH] Update start_pfn in zone and pg_data when spanned_pages == 0.
From: Tang Chen @ 2012-11-07  7:40 UTC (permalink / raw)
  To: wency
  Cc: linux-s390, linux-ia64, len.brown, linux-acpi, linux-sh, x86,
	linux-kernel, cmetcalf, linux-mm, isimatu.yasuaki, paulus,
	minchan.kim, kosaki.motohiro, rientjes, sparclinux, cl,
	linuxppc-dev, akpm, liuj97
In-Reply-To: <1350988250-31294-11-git-send-email-wency@cn.fujitsu.com>

On 10/23/2012 06:30 PM, wency@cn.fujitsu.com wrote:
> From: Yasuaki Ishimatsu<isimatu.yasuaki@jp.fujitsu.com>
......
> +	/* The zone has no valid section */
> +	zone->zone_start_pfn = 0;
> +	zone->spanned_pages = 0;
> +	zone_span_writeunlock(zone);
> +}
> +
> +static void shrink_pgdat_span(struct pglist_data *pgdat,
> +			      unsigned long start_pfn, unsigned long end_pfn)
> +{
......
> +	/* The pgdat has no valid section */
> +	pgdat->node_start_pfn = 0;
> +	pgdat->node_spanned_pages = 0;
> +}

Hi,

If we hot-remove memory only and leave the cpus alive, the corresponding
node will not be removed. But the node_start_pfn and node_spanned_pages
in pg_data will be reset to 0. In this case, when we hot-add the memory
back next time, the node_start_pfn will always be 0 because no pfn is less
than 0. After that, if we hot-remove the memory again, it will cause kernel
panic in function find_biggest_section_pfn() when it tries to scan all 
the pfns.

The zone will also have the same problem.

This patch sets start_pfn to the start_pfn of the section being added when
spanned_pages of the zone or pg_data is 0.

---How to reproduce---

1. hot-add a container with some memory and cpus;
2. hot-remove the container's memory, and leave cpus there;
3. hot-add these memory again;
4. hot-remove them again;

then, the kernel will panic.

---Call trace---

[10530.646285] BUG: unable to handle kernel paging request at 
00000fff82a8cc38
[10530.729670] IP: [<ffffffff811c0d55>] find_biggest_section_pfn+0xe5/0x180
......
[10533.064975] Call Trace:
[10533.094162]  [<ffffffff811c0fcf>] ? __remove_zone+0x2f/0x1b0
[10533.161757]  [<ffffffff811c1124>] __remove_zone+0x184/0x1b0
[10533.228318]  [<ffffffff811c11dc>] __remove_section+0x8c/0xb0
[10533.295916]  [<ffffffff811c12e7>] __remove_pages+0xe7/0x120
[10533.362476]  [<ffffffff81654f7c>] arch_remove_memory+0x2c/0x80
[10533.432151]  [<ffffffff81655bb6>] remove_memory+0x56/0x90
[10533.496633]  [<ffffffff813da0c8>] 
acpi_memory_device_remove_memory+0x48/0x73
[10533.580846]  [<ffffffff813da55a>] acpi_memory_device_notify+0x153/0x274
[10533.659865]  [<ffffffff813a63cf>] ? acpi_bus_get_device+0x2f/0x77
[10533.732653]  [<ffffffff813a6589>] ? acpi_bus_notify+0xb5/0xec
[10533.801291]  [<ffffffff813b6786>] acpi_ev_notify_dispatch+0x41/0x5f
[10533.876156]  [<ffffffff813a3867>] acpi_os_execute_deferred+0x27/0x34
[10533.952062]  [<ffffffff81090589>] process_one_work+0x219/0x680
[10534.021736]  [<ffffffff81090528>] ? process_one_work+0x1b8/0x680
[10534.093488]  [<ffffffff813a3840>] ? 
acpi_os_wait_events_complete+0x23/0x23
[10534.175622]  [<ffffffff810923be>] worker_thread+0x12e/0x320
[10534.242181]  [<ffffffff81092290>] ? manage_workers+0x110/0x110
[10534.311855]  [<ffffffff81098396>] kthread+0xc6/0xd0
[10534.370111]  [<ffffffff8167c7c4>] kernel_thread_helper+0x4/0x10
[10534.440824]  [<ffffffff81672230>] ? retint_restore_args+0x13/0x13
[10534.513612]  [<ffffffff810982d0>] ? __init_kthread_worker+0x70/0x70
[10534.588480]  [<ffffffff8167c7c0>] ? gs_change+0x13/0x13
......
[10535.045543] ---[ end trace 96d845dbf33fee11 ]---


Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
---
  mm/memory_hotplug.c |    4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 56b758a..4aa313c 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -212,7 +212,7 @@ static void grow_zone_span(struct zone *zone, 
unsigned long start_pfn,
         zone_span_writelock(zone);

         old_zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
-       if (start_pfn < zone->zone_start_pfn)
+       if (!zone->spanned_pages || start_pfn < zone->zone_start_pfn)
                 zone->zone_start_pfn = start_pfn;

         zone->spanned_pages = max(old_zone_end_pfn, end_pfn) -
@@ -227,7 +227,7 @@ static void grow_pgdat_span(struct pglist_data 
*pgdat, unsigned long start_pfn,
         unsigned long old_pgdat_end_pfn =
                 pgdat->node_start_pfn + pgdat->node_spanned_pages;

-       if (start_pfn < pgdat->node_start_pfn)
+       if (!pgdat->node_spanned_pages || start_pfn < pgdat->node_start_pfn)
                 pgdat->node_start_pfn = start_pfn;

         pgdat->node_spanned_pages = max(old_pgdat_end_pfn, end_pfn) -
-- 
1.7.10.1

^ permalink raw reply related

* Re: [PATCH 1/2] powerpc/pseries: Allow firmware features to match partial strings
From: Stephen Rothwell @ 2012-11-07  5:30 UTC (permalink / raw)
  To: Michael Neuling; +Cc: Linux PPC dev
In-Reply-To: <1352249356-29671-1-git-send-email-mikey@neuling.org>

[-- Attachment #1: Type: text/plain, Size: 659 bytes --]

Hi Mikey,

On Wed,  7 Nov 2012 11:49:15 +1100 Michael Neuling <mikey@neuling.org> wrote:
>
> This allows firmware_features_table names to add a '*' at the end so that only
> partial strings are matched.
> 
> When a '*' is added, only upto the '*' is matched when setting firmware feature
> bits.
> 
> This is useful for the matching best energy feature.
> 
> Signed-off-by: Michael Neuling <mikey@neuling.org>
> cc: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
> cc: Linux PPC dev <linuxppc-dev@ozlabs.org>

Reviewed-by: Stephen Rothwell <sfr@canb.auug.org.au>

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* [PATCH 2/2] powerpc/pseries: Cleanup best_energy_hcall detection
From: Michael Neuling @ 2012-11-07  0:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Linux PPC dev, Michael Neuling
In-Reply-To: <1352249356-29671-1-git-send-email-mikey@neuling.org>

Currently we search for the best_energy hcall using a custom function.  Move
this to using the firmware_feature_table.

Signed-off-by: Michael Neuling <mikey@neuling.org>
cc: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
cc: Linux PPC dev <linuxppc-dev@ozlabs.org>
---
 arch/powerpc/include/asm/firmware.h             |    4 ++-
 arch/powerpc/platforms/pseries/firmware.c       |    1 +
 arch/powerpc/platforms/pseries/pseries_energy.c |   37 ++---------------------
 3 files changed, 6 insertions(+), 36 deletions(-)

diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h
index ad0b751..ecec46a 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -49,6 +49,7 @@
 #define FW_FEATURE_XCMO		ASM_CONST(0x0000000008000000)
 #define FW_FEATURE_OPAL		ASM_CONST(0x0000000010000000)
 #define FW_FEATURE_OPALv2	ASM_CONST(0x0000000020000000)
+#define FW_FEATURE_BEST_ENERGY	ASM_CONST(0x0000000040000000)
 
 #ifndef __ASSEMBLY__
 
@@ -62,7 +63,8 @@ enum {
 		FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
 		FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR |
 		FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
-		FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO,
+		FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO | 
+	        FW_FEATURE_BEST_ENERGY,
 	FW_FEATURE_PSERIES_ALWAYS = 0,
 	FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2,
 	FW_FEATURE_POWERNV_ALWAYS = 0,
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index 448c053..5bc10cb 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -61,6 +61,7 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
 	{FW_FEATURE_MULTITCE,		"hcall-multi-tce"},
 	{FW_FEATURE_SPLPAR,		"hcall-splpar"},
 	{FW_FEATURE_VPHN,		"hcall-vphn"},
+	{FW_FEATURE_BEST_ENERGY,	"hcall-best-energy-1*"},
 };
 
 /* Build up the firmware features bitmask using the contents of
diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c
index af281dc..a91e6da 100644
--- a/arch/powerpc/platforms/pseries/pseries_energy.c
+++ b/arch/powerpc/platforms/pseries/pseries_energy.c
@@ -21,6 +21,7 @@
 #include <asm/cputhreads.h>
 #include <asm/page.h>
 #include <asm/hvcall.h>
+#include <asm/firmware.h>
 
 
 #define MODULE_VERS "1.0"
@@ -32,40 +33,6 @@ static int sysfs_entries;
 
 /* Helper routines */
 
-/*
- * Routine to detect firmware support for hcall
- * return 1 if H_BEST_ENERGY is supported
- * else return 0
- */
-
-static int check_for_h_best_energy(void)
-{
-	struct device_node *rtas = NULL;
-	const char *hypertas, *s;
-	int length;
-	int rc = 0;
-
-	rtas = of_find_node_by_path("/rtas");
-	if (!rtas)
-		return 0;
-
-	hypertas = of_get_property(rtas, "ibm,hypertas-functions", &length);
-	if (!hypertas) {
-		of_node_put(rtas);
-		return 0;
-	}
-
-	/* hypertas will have list of strings with hcall names */
-	for (s = hypertas; s < hypertas + length; s += strlen(s) + 1) {
-		if (!strncmp("hcall-best-energy-1", s, 19)) {
-			rc = 1; /* Found the string */
-			break;
-		}
-	}
-	of_node_put(rtas);
-	return rc;
-}
-
 /* Helper Routines to convert between drc_index to cpu numbers */
 
 static u32 cpu_to_drc_index(int cpu)
@@ -262,7 +229,7 @@ static int __init pseries_energy_init(void)
 	int cpu, err;
 	struct device *cpu_dev;
 
-	if (!check_for_h_best_energy()) {
+	if (!firmware_has_feature(FW_FEATURE_BEST_ENERGY)) {
 		printk(KERN_INFO "Hypercall H_BEST_ENERGY not supported\n");
 		return 0;
 	}
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 1/2] powerpc/pseries: Allow firmware features to match partial strings
From: Michael Neuling @ 2012-11-07  0:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Linux PPC dev, Michael Neuling

This allows firmware_features_table names to add a '*' at the end so that only
partial strings are matched.

When a '*' is added, only upto the '*' is matched when setting firmware feature
bits.

This is useful for the matching best energy feature.

Signed-off-by: Michael Neuling <mikey@neuling.org>
cc: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
cc: Linux PPC dev <linuxppc-dev@ozlabs.org>
---
 arch/powerpc/platforms/pseries/firmware.c |   20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index 0b0eff0..448c053 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -33,6 +33,11 @@ typedef struct {
     char * name;
 } firmware_feature_t;
 
+/*
+ * The names in this table match names in rtas/ibm,hypertas-functions.  If the
+ * entry ends in a '*', only upto the '*' is matched.  Otherwise the entire
+ * string must match.
+ */
 static __initdata firmware_feature_t
 firmware_features_table[FIRMWARE_MAX_FEATURES] = {
 	{FW_FEATURE_PFT,		"hcall-pft"},
@@ -71,9 +76,20 @@ void __init fw_feature_init(const char *hypertas, unsigned long len)
 
 	for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) {
 		for (i = 0; i < FIRMWARE_MAX_FEATURES; i++) {
+			const char *name = firmware_features_table[i].name;
+			size_t size;
 			/* check value against table of strings */
-			if (!firmware_features_table[i].name ||
-			    strcmp(firmware_features_table[i].name, s))
+			if (!name)
+				continue;
+			/*
+			 * If there is a '*' at the end of name, only check
+			 * upto there
+			 */
+			size = strlen(name);
+			if (size && name[size - 1] == '*') {
+				if (strncmp(name, s, size - 1))
+					continue;
+			} else if (strcmp(name, s))
 				continue;
 
 			/* we have a match */
-- 
1.7.9.5

^ permalink raw reply related

* 3.7-rc4: BUG: MAX_STACK_TRACE_ENTRIES too low!
From: Christian Kujau @ 2012-11-06 23:51 UTC (permalink / raw)
  To: LKML; +Cc: linuxppc-dev

Hi,

after upgrading from 3.6.0-08492-gd43 to 3.7.0-rc4 and running it for a 
day or so, this happened:

[27148.965634] BUG: MAX_STACK_TRACE_ENTRIES too low!
[27148.967356] turning off the locking correctness validator.
[27148.968967] Call Trace:
[27148.970577] [ec633d00] [c0009064] show_stack+0x70/0x1bc (unreliable)
[27148.972229] [ec633d40] [c0077460] save_trace+0xfc/0x114
[27148.973855] [ec633d50] [c0078578] mark_lock+0x1b4/0x678
[27148.975472] [ec633d80] [c007ad70] __lock_acquire+0x4b8/0x19b8
[27148.977098] [ec633e20] [c007c2c0] lock_acquire+0x50/0x70
[27148.978717] [ec633e40] [c004ee88] process_one_work+0x1c4/0x49c
[27148.980302] [ec633e80] [c004f644] worker_thread+0x14c/0x400
[27148.981866] [ec633eb0] [c0057634] kthread+0xbc/0xc0
[27148.983385] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64

The last message is repeated several times, see below. The machine 
(PowerPC G4) is still up & running and no ill behaviour can be seen for
now. I still wonder if this would be a sign for trouble...

Christian.

[27148.984860] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27148.986259] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27148.987583] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27148.988854] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27148.990086] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27148.991305] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27148.992495] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27148.993668] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27148.994809] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27148.995947] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27148.997070] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27148.998182] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27148.999282] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.000365] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.001436] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.002450] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.003417] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.004378] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.005324] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.006260] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.007181] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.008087] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.008972] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.009833] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.010656] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.011443] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.012203] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.012935] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.013642] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.014314] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.014951] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.015568] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.016168] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.016744] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.017293] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.017814] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.018313] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.018796] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.019257] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.019701] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.020120] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.020519] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.020900] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.021283] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.021880] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.022275] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.022659] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.023043] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.023427] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.023810] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.024191] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.024573] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.024955] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.025339] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.025723] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64
[27149.026106] [ec633f40] [c0011ad4] ret_from_kernel_thread+0x5c/0x64

$ zgrep DEBUG /proc/config.gz | grep =y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_SLUB_DEBUG=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_SHIRQ=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_PI_LIST=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DEBUGGER=y

-- 
BOFH excuse #248:

Too much radiation coming from the soil.

^ permalink raw reply

* Re: [PATCH] Enable hardware breakpoint upon re-registering
From: Michael Neuling @ 2012-11-06 20:53 UTC (permalink / raw)
  To: Aravinda Prasad; +Cc: linuxppc-dev, linux-kernel, fweisbec
In-Reply-To: <20121105081527.29141.11384.stgit@aravinda>

Aravinda Prasad <aravinda@linux.vnet.ibm.com> wrote:

> On powerpc, ptrace will disable hardware breakpoint request once the
> breakpoint is hit. It is the responsibility of the caller to set it
> again. However, when the caller sets the hardware breakpoint again
> using ptrace(PTRACE_SET_DEBUGREG, child_pid, 0, addr), the hardware
> breakpoint is not enabled.
> 
> While gdb's approach is to unregister and re-register the hardware
> breakpoint every time the breakpoint is hit - which is working fine,
> this could affect other programs trying to re-register hardware
> breakpoint without unregistering.
> 
> This patch enables hardware breakpoint if the caller is re-registering.
> 
> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>

Passes my tests here and I don't think it'll break existing gdb.  So FWIW

Acked-by: Michael Neuling <mikey@neuling.org>

Thanks!

> ---
>  arch/powerpc/kernel/ptrace.c |    4 ++++
>  1 files changed, 4 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
> index 79d8e56..09371d0 100644
> --- a/arch/powerpc/kernel/ptrace.c
> +++ b/arch/powerpc/kernel/ptrace.c
> @@ -952,6 +952,10 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
>  		arch_bp_generic_fields(data &
>  					(DABR_DATA_WRITE | DABR_DATA_READ),
>  							&attr.bp_type);
> +
> +		/* Enable breakpoint */
> +		attr.disabled = false;
> +
>  		ret =  modify_user_hw_breakpoint(bp, &attr);
>  		if (ret) {
>  			ptrace_put_breakpoints(task);
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
> 

^ permalink raw reply

* Re: powerpc: Don't silently handle machine checks from userspace
From: Scott Wood @ 2012-11-06 20:13 UTC (permalink / raw)
  To: Micha Nelissen
  Cc: Martijn de Gouw, linuxppc-dev@lists.ozlabs.org, Anton Blanchard
In-Reply-To: <39F93B8F6D09AC4DA45E2F19603FA69C324F2605@exc02.bk.prodrive.nl>

On 11/06/2012 10:43:19 AM, Micha Nelissen wrote:
> From: Scott Wood [mailto:scottwood@freescale.com]
> >> Hmm I guess there is no simple solution then, since the "recover"
> >> function also prints the kernel messages about the machine check
> >> being in kernel mode without having checked whether it really was =20
> in
> >> kernel mode. In the past the user mode check was in between.
> >
> > It shouldn't be that difficult to make it say "in user mode" or "in
> > kernel mode" depending on which it was... or just remove that phrase
> > altogether and let the following output indicate whether it was in
> > kernel mode.
>=20
> Well printing the correct message is only part of it: do "we" want to =20
> pass guarded load errors (RapidIO bus errors) to user space or not?

Yes.

> And if we pass them, should we print a kernel message at all?

Yes (but maybe ratelimited).

-Scott=

^ permalink raw reply

* RE: powerpc: Don't silently handle machine checks from userspace
From: Micha Nelissen @ 2012-11-06 16:43 UTC (permalink / raw)
  To: 'Scott Wood'
  Cc: Martijn de Gouw, linuxppc-dev@lists.ozlabs.org, Anton Blanchard
In-Reply-To: <1352219655.21833.0@snotra>

From: Scott Wood [mailto:scottwood@freescale.com]
>> Hmm I guess there is no simple solution then, since the "recover"
>> function also prints the kernel messages about the machine check
>> being in kernel mode without having checked whether it really was in
>> kernel mode. In the past the user mode check was in between.
>=20
> It shouldn't be that difficult to make it say "in user mode" or "in
> kernel mode" depending on which it was... or just remove that phrase
> altogether and let the following output indicate whether it was in
> kernel mode.

Well printing the correct message is only part of it: do "we" want to pass =
guarded load errors (RapidIO bus errors) to user space or not? And if we pa=
ss them, should we print a kernel message at all?

Micha

^ permalink raw reply

* Re: powerpc: Don't silently handle machine checks from userspace
From: Scott Wood @ 2012-11-06 16:34 UTC (permalink / raw)
  To: Micha Nelissen
  Cc: Martijn de Gouw, linuxppc-dev@lists.ozlabs.org, Anton Blanchard
In-Reply-To: <39F93B8F6D09AC4DA45E2F19603FA69C324EEDCD@exc02.bk.prodrive.nl>

On 11/06/2012 03:21:37 AM, Micha Nelissen wrote:
> From: Scott Wood [mailto:scottwood@freescale.com]
> > > Therefore I request to put this check back, and even to put the
> > > removed code at the top of the machine check handler because =20
> there is
> > > no point in trying to recover from a user space bus error anyway.
> >
> > Why is there no point trying to recover?  For example, see =20
> MCSR_ICPERR
> > and MCSR_DCPERR_MC in machine_check_e500mc.  The machine check is =20
> just
> > letting us know that there was an error and the read-only cache got
> > dumped (i.e. it was a correctable error).
>=20
> Oh I overlooked those cases; those correctable errors shouldn't be =20
> bus errors for the user space process?
>=20
> Hmm I guess there is no simple solution then, since the "recover" =20
> function also prints the kernel messages about the machine check =20
> being in kernel mode without having checked whether it really was in =20
> kernel mode. In the past the user mode check was in between.

It shouldn't be that difficult to make it say "in user mode" or "in =20
kernel mode" depending on which it was... or just remove that phrase =20
altogether and let the following output indicate whether it was in =20
kernel mode.

-Scott=

^ permalink raw reply

* Re: [PATCH] powermac/cpufreq_32: set non-infinite transition time for 7447A driver
From: Michel Dänzer @ 2012-11-06 12:28 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linuxppc-dev
In-Reply-To: <m24nld1vx9.fsf@igel.home>

On Mon, 2012-10-29 at 10:15 +0100, Andreas Schwab wrote:=20
> The transition time for the 7447A is around 8ms which makes it possible
> to use the ondemand governor.  This has been tested on the iBook G4
> (PowerBook6,7).
>=20
> Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>

Tested-by: Michel D=E4nzer <michel@daenzer.net>


--=20
Earthling Michel D=E4nzer           |                   http://www.amd.com
Libre software enthusiast         |          Debian, X and DRI developer

^ permalink raw reply

* Re: RFC: book3e: DCR MMIO for IBM Blue Gene/Q
From: Benjamin Herrenschmidt @ 2012-11-06 11:48 UTC (permalink / raw)
  To: Jimi Xenidis; +Cc: linuxppc-dev
In-Reply-To: <749146C7-B9A8-4001-9580-3B87A041A580@pobox.com>

On Mon, 2012-11-05 at 09:25 -0600, Jimi Xenidis wrote:
> So Axon, being 64-bit, would break with the changes proposed, since it
> is 64-bit bit and assumes 32bit accessors.
> I'll simply add 64bit accessors for now.

Well, either that, or you add a "64-bit" property to the DCR controller
node. IE. you keep the API "unsigned long" but whether it uses 32 or
64-bit accessors depends on that property.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH 1/2] powerpc/perf: Fix finding overflowed PMC in interrupt
From: Anshuman Khandual @ 2012-11-06 10:42 UTC (permalink / raw)
  To: Michael Neuling
  Cc: Linux PPC dev, Sukadev Bhattiprolu, Paul Mackerras,
	Anton Blanchard
In-Reply-To: <21513.1352197182@neuling.org>

On 11/06/2012 03:49 PM, Michael Neuling wrote:
>>
>>
>> I have couple of questions. 
>>
>> Can the buggy overflow happen on any of the available counters PMC1-PMC4 ?
> 
> No.  It's limited to certain events and I believe it can only happen on
> PMC2 and 4.  This code doesn't bother trying to make this distinction
> though.
> 
>> Will this approach never reset an actual user defined event (with
>> sample period < 256) ? Is this related to the counter or the event
>> which it is counting ? Just wondering if we have to do something more
>> than checking for the count < 256. Just a thought.
> 
> 
> I don't understand what you mean by these questions.  Can you explain a
> bit more?
> 

Thats fine. The previous answer explains it well. Thanks !

^ permalink raw reply

* Re: [PATCH 1/2] powerpc/perf: Fix finding overflowed PMC in interrupt
From: Michael Neuling @ 2012-11-06 10:19 UTC (permalink / raw)
  To: Anshuman Khandual
  Cc: Sukadev Bhattiprolu, Paul Mackerras, Anton Blanchard,
	Linux PPC dev
In-Reply-To: <5098B28B.2070703@linux.vnet.ibm.com>

Anshuman Khandual <khandual@linux.vnet.ibm.com> wrote:

> On 11/06/2012 07:23 AM, Michael Neuling wrote:
> 
> > +	if (!found && pvr_version_is(PVR_POWER7)) {
> > +		/* check active counters for special buggy p7 overflow */
> > +		for (i = 0; i < cpuhw->n_events; ++i) {
> > +			event = cpuhw->event[i];
> > +			if (!event->hw.idx || is_limited_pmc(event->hw.idx))
> >  				continue;
> > -			val = read_pmc(i + 1);
> > -			if (pmc_overflow(val))
> > -				write_pmc(i + 1, 0);
> > +			if (pmc_overflow_power7(val[event->hw.idx - 1])) {
> 
> 
> I have couple of questions. 
> 
> Can the buggy overflow happen on any of the available counters PMC1-PMC4 ?

No.  It's limited to certain events and I believe it can only happen on
PMC2 and 4.  This code doesn't bother trying to make this distinction
though.

> Will this approach never reset an actual user defined event (with
> sample period < 256) ? Is this related to the counter or the event
> which it is counting ? Just wondering if we have to do something more
> than checking for the count < 256. Just a thought.


I don't understand what you mean by these questions.  Can you explain a
bit more?

Mikey

^ permalink raw reply

* RE: powerpc: Don't silently handle machine checks from userspace
From: Micha Nelissen @ 2012-11-06  9:21 UTC (permalink / raw)
  To: 'Scott Wood', Martijn de Gouw
  Cc: linuxppc-dev@lists.ozlabs.org, Anton Blanchard
In-Reply-To: <1351874164.5089.1@snotra>

From: Scott Wood [mailto:scottwood@freescale.com]
> > Therefore I request to put this check back, and even to put the
> > removed code at the top of the machine check handler because there is
> > no point in trying to recover from a user space bus error anyway.
>=20
> Why is there no point trying to recover?  For example, see MCSR_ICPERR
> and MCSR_DCPERR_MC in machine_check_e500mc.  The machine check is just
> letting us know that there was an error and the read-only cache got
> dumped (i.e. it was a correctable error).

Oh I overlooked those cases; those correctable errors shouldn't be bus erro=
rs for the user space process?

Hmm I guess there is no simple solution then, since the "recover" function =
also prints the kernel messages about the machine check being in kernel mod=
e without having checked whether it really was in kernel mode. In the past =
the user mode check was in between.

Micha

^ permalink raw reply

* Re: [PATCH 1/2] powerpc/perf: Fix finding overflowed PMC in interrupt
From: Anshuman Khandual @ 2012-11-06  6:47 UTC (permalink / raw)
  To: Michael Neuling
  Cc: Sukadev Bhattiprolu, Paul Mackerras, Anton Blanchard,
	Linux PPC dev
In-Reply-To: <1352166835-27980-1-git-send-email-mikey@neuling.org>

On 11/06/2012 07:23 AM, Michael Neuling wrote:

> +	if (!found && pvr_version_is(PVR_POWER7)) {
> +		/* check active counters for special buggy p7 overflow */
> +		for (i = 0; i < cpuhw->n_events; ++i) {
> +			event = cpuhw->event[i];
> +			if (!event->hw.idx || is_limited_pmc(event->hw.idx))
>  				continue;
> -			val = read_pmc(i + 1);
> -			if (pmc_overflow(val))
> -				write_pmc(i + 1, 0);
> +			if (pmc_overflow_power7(val[event->hw.idx - 1])) {


I have couple of questions. 

Can the buggy overflow happen on any of the available counters PMC1-PMC4 ?
Will this approach never reset an actual user defined event (with sample period < 256) ?
Is this related to the counter or the event which it is counting ? Just wondering if we
have to do something more than checking for the count < 256. Just a thought.

Regards
Anshuman

^ permalink raw reply

* [PATCH 1/2] powerpc/perf: Fix finding overflowed PMC in interrupt
From: Michael Neuling @ 2012-11-06  1:53 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Linux PPC dev, Michael Neuling, Sukadev Bhattiprolu,
	Paul Mackerras, Anton Blanchard
In-Reply-To: <20121106122559.38ea906f@kryten>

If a PMC is about to overflow on a counter that's on an active perf event
(ie. less than 256 from the end) and a _different_ PMC overflows just at this
time (a PMC that's not on an active perf event), we currently mark the event as
found, but in reality it's not as it's likely the other PMC that caused the
IRQ.  Since we mark it as found the second catch all for overflows doesn't run,
and we don't reset the overflowing PMC ever.  Hence we keep hitting that same
PMC IRQ over and over and don't reset the actual overflowing counter.

This is a rewrite of the perf interrupt handler for book3s to get around this.
We now check to see if any of the PMCs have actually overflowed (ie >=
0x80000000).  If yes, record it for active counters and just reset it for
inactive counters.  If it's not overflowed, then we check to see if it's one of
the buggy power7 counters and if it is, record it and continue.  If none of the
PMCs match this, then we make note that we couldn't find the PMC that caused
the IRQ.

Signed-off-by: Michael Neuling <mikey@neuling.org>
Reviewed-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
cc: Paul Mackerras <paulus@samba.org>
cc: Anton Blanchard <anton@samba.org>
cc: Linux PPC dev <linuxppc-dev@ozlabs.org>
---
 arch/powerpc/perf/core-book3s.c |   83 +++++++++++++++++++++++++--------------
 1 file changed, 54 insertions(+), 29 deletions(-)

diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index aa2465e..53fc7b8 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -1412,11 +1412,8 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs)
 		return regs->nip;
 }
 
-static bool pmc_overflow(unsigned long val)
+static bool pmc_overflow_power7(unsigned long val)
 {
-	if ((int)val < 0)
-		return true;
-
 	/*
 	 * Events on POWER7 can roll back if a speculative event doesn't
 	 * eventually complete. Unfortunately in some rare cases they will
@@ -1428,7 +1425,15 @@ static bool pmc_overflow(unsigned long val)
 	 * PMCs because a user might set a period of less than 256 and we
 	 * don't want to mistakenly reset them.
 	 */
-	if (pvr_version_is(PVR_POWER7) && ((0x80000000 - val) <= 256))
+	if ((0x80000000 - val) <= 256)
+		return true;
+
+	return false;
+}
+
+static bool pmc_overflow(unsigned long val)
+{
+	if ((int)val < 0)
 		return true;
 
 	return false;
@@ -1439,11 +1444,11 @@ static bool pmc_overflow(unsigned long val)
  */
 static void perf_event_interrupt(struct pt_regs *regs)
 {
-	int i;
+	int i, j;
 	struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
 	struct perf_event *event;
-	unsigned long val;
-	int found = 0;
+	unsigned long val[8];
+	int found, active;
 	int nmi;
 
 	if (cpuhw->n_limited)
@@ -1458,33 +1463,53 @@ static void perf_event_interrupt(struct pt_regs *regs)
 	else
 		irq_enter();
 
-	for (i = 0; i < cpuhw->n_events; ++i) {
-		event = cpuhw->event[i];
-		if (!event->hw.idx || is_limited_pmc(event->hw.idx))
+	/* Read all the PMCs since we'll need them a bunch of times */
+	for (i = 0; i < ppmu->n_counter; ++i)
+		val[i] = read_pmc(i + 1);
+
+	/* Try to find what caused the IRQ */
+	found = 0;
+	for (i = 0; i < ppmu->n_counter; ++i) {
+		if (!pmc_overflow(val[i]))
 			continue;
-		val = read_pmc(event->hw.idx);
-		if ((int)val < 0) {
-			/* event has overflowed */
-			found = 1;
-			record_and_restart(event, val, regs);
+		if (is_limited_pmc(i + 1))
+			continue; /* these won't generate IRQs */
+		/*
+		 * We've found one that's overflowed.  For active
+		 * counters we need to log this.  For inactive
+		 * counters, we need to reset it anyway
+		 */
+		found = 1;
+		active = 0;
+		for (j = 0; j < cpuhw->n_events; ++j) {
+			event = cpuhw->event[j];
+			if (event->hw.idx == (i + 1)) {
+				active = 1;
+				record_and_restart(event, val[i], regs);
+				break;
+			}
 		}
+		if (!active)
+			/* reset non active counters that have overflowed */
+			write_pmc(i + 1, 0);
 	}
-
-	/*
-	 * In case we didn't find and reset the event that caused
-	 * the interrupt, scan all events and reset any that are
-	 * negative, to avoid getting continual interrupts.
-	 * Any that we processed in the previous loop will not be negative.
-	 */
-	if (!found) {
-		for (i = 0; i < ppmu->n_counter; ++i) {
-			if (is_limited_pmc(i + 1))
+	if (!found && pvr_version_is(PVR_POWER7)) {
+		/* check active counters for special buggy p7 overflow */
+		for (i = 0; i < cpuhw->n_events; ++i) {
+			event = cpuhw->event[i];
+			if (!event->hw.idx || is_limited_pmc(event->hw.idx))
 				continue;
-			val = read_pmc(i + 1);
-			if (pmc_overflow(val))
-				write_pmc(i + 1, 0);
+			if (pmc_overflow_power7(val[event->hw.idx - 1])) {
+				/* event has overflowed in a buggy way*/
+				found = 1;
+				record_and_restart(event,
+						   val[event->hw.idx - 1],
+						   regs);
+			}
 		}
 	}
+	if ((!found) && printk_ratelimit())
+		printk(KERN_WARNING "Can't find PMC that caused IRQ\n");
 
 	/*
 	 * Reset MMCR0 to its normal value.  This will set PMXE and
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH 1/2] powerpc/perf: Fix finding overflowed PMC in interrupt
From: Michael Neuling @ 2012-11-06  1:53 UTC (permalink / raw)
  To: Anton Blanchard; +Cc: Sukadev Bhattiprolu, Paul Mackerras, Linux PPC dev
In-Reply-To: <20121106122559.38ea906f@kryten>

> Thanks for looking into this mess. One small thing we can fix in a
> follow up patch:
> > +	if (!found)
> > +		printk(KERN_WARNING "Can't find PMC that caused
> 
> I think it would be worth making that a printk_ratelimited. We are
> probably dead at this stage but we shouldn't spam the console
> at ludicrous speed in the process.

Thanks, good point.

Mikey

^ permalink raw reply

* Re: [PATCH 1/2] powerpc/perf: Fix finding overflowed PMC in interrupt
From: Anton Blanchard @ 2012-11-06  1:25 UTC (permalink / raw)
  To: Michael Neuling
  Cc: Linux PPC dev, Sukadev Bhattiprolu, Paul Mackerras,
	Benjamin Herrenschmidt
In-Reply-To: <1352164118-19450-1-git-send-email-mikey@neuling.org>


Hi,

Thanks for looking into this mess. One small thing we can fix in a
follow up patch:

> +	if (!found)
> +		printk(KERN_WARNING "Can't find PMC that caused

I think it would be worth making that a printk_ratelimited. We are
probably dead at this stage but we shouldn't spam the console
at ludicrous speed in the process.

Anton

^ permalink raw reply

* [PATCH 2/2] powerpc/perf: Fix for PMCs not making progress
From: Michael Neuling @ 2012-11-06  1:08 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Linux PPC dev, Michael Neuling, Sukadev Bhattiprolu,
	Paul Mackerras, Anton Blanchard
In-Reply-To: <1352164118-19450-1-git-send-email-mikey@neuling.org>

On POWER7 when we have really small counts left before overflow, we can take a
PMU IRQ, but the PMC gets wound back to just before the overflow.

If the kernel is setting the PMC to a value just before the overflow, we can
get interrupted again without the PMC making any progress (ie another buggy
overflow).  In this case, we can end up making no forward progress, with the
PMC interrupt returning us to the same count over and over.

The below detects when we are making no forward progress (ie. delta = 0) and
then increases the amount left before the overflow.  This stops us from locking
up.

Signed-off-by: Michael Neuling <mikey@neuling.org>
Reviewed-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
cc: Paul Mackerras <paulus@samba.org>
cc: Anton Blanchard <anton@samba.org>
cc: Linux PPC dev <linuxppc-dev@ozlabs.org>
---
 arch/powerpc/perf/core-book3s.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 3575def..f1018c8 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -1349,6 +1349,8 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
 	 */
 	val = 0;
 	left = local64_read(&event->hw.period_left) - delta;
+	if (delta == 0)
+		left++;
 	if (period) {
 		if (left <= 0) {
 			left += period;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 1/2] powerpc/perf: Fix finding overflowed PMC in interrupt
From: Michael Neuling @ 2012-11-06  1:08 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Linux PPC dev, Michael Neuling, Sukadev Bhattiprolu,
	Paul Mackerras, Anton Blanchard
In-Reply-To: <20120921003805.GA4507@us.ibm.com>

If a PMC is about to overflow on a counter that's on an active perf event
(ie. less than 256 from the end) and a _different_ PMC overflows just at this
time (a PMC that's not on an active perf event), we currently mark the event as
found, but in reality it's not as it's likely the other PMC that caused the
IRQ.  Since we mark it as found the second catch all for overflows doesn't run,
and we don't reset the overflowing PMC ever.  Hence we keep hitting that same
PMC IRQ over and over and don't reset the actual overflowing counter.

This is a rewrite of the perf interrupt handler for book3s to get around this.
We now check to see if any of the PMCs have actually overflowed (ie >=
0x80000000).  If yes, record it for active counters and just reset it for
inactive counters.  If it's not overflowed, then we check to see if it's one of
the buggy power7 counters and if it is, record it and continue.  If none of the
PMCs match this, then we make note that we couldn't find the PMC that caused
the IRQ.

Signed-off-by: Michael Neuling <mikey@neuling.org>
Reviewed-by: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
cc: Paul Mackerras <paulus@samba.org>
cc: Anton Blanchard <anton@samba.org>
cc: Linux PPC dev <linuxppc-dev@ozlabs.org>
---
 arch/powerpc/perf/core-book3s.c |   83 +++++++++++++++++++++++++--------------
 1 file changed, 54 insertions(+), 29 deletions(-)

diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index aa2465e..3575def 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -1412,11 +1412,8 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs)
 		return regs->nip;
 }
 
-static bool pmc_overflow(unsigned long val)
+static bool pmc_overflow_power7(unsigned long val)
 {
-	if ((int)val < 0)
-		return true;
-
 	/*
 	 * Events on POWER7 can roll back if a speculative event doesn't
 	 * eventually complete. Unfortunately in some rare cases they will
@@ -1428,7 +1425,15 @@ static bool pmc_overflow(unsigned long val)
 	 * PMCs because a user might set a period of less than 256 and we
 	 * don't want to mistakenly reset them.
 	 */
-	if (pvr_version_is(PVR_POWER7) && ((0x80000000 - val) <= 256))
+	if ((0x80000000 - val) <= 256)
+		return true;
+
+	return false;
+}
+
+static bool pmc_overflow(unsigned long val)
+{
+	if ((int)val < 0)
 		return true;
 
 	return false;
@@ -1439,11 +1444,11 @@ static bool pmc_overflow(unsigned long val)
  */
 static void perf_event_interrupt(struct pt_regs *regs)
 {
-	int i;
+	int i, j;
 	struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
 	struct perf_event *event;
-	unsigned long val;
-	int found = 0;
+	unsigned long val[8];
+	int found, active;
 	int nmi;
 
 	if (cpuhw->n_limited)
@@ -1458,33 +1463,53 @@ static void perf_event_interrupt(struct pt_regs *regs)
 	else
 		irq_enter();
 
-	for (i = 0; i < cpuhw->n_events; ++i) {
-		event = cpuhw->event[i];
-		if (!event->hw.idx || is_limited_pmc(event->hw.idx))
+	/* Read all the PMCs since we'll need them a bunch of times */
+	for (i = 0; i < ppmu->n_counter; ++i)
+		val[i] = read_pmc(i + 1);
+
+	/* Try to find what caused the IRQ */
+	found = 0;
+	for (i = 0; i < ppmu->n_counter; ++i) {
+		if (!pmc_overflow(val[i]))
 			continue;
-		val = read_pmc(event->hw.idx);
-		if ((int)val < 0) {
-			/* event has overflowed */
-			found = 1;
-			record_and_restart(event, val, regs);
+		if (is_limited_pmc(i + 1))
+			continue; /* these won't generate IRQs */
+		/*
+		 * We've found one that's overflowed.  For active
+		 * counters we need to log this.  For inactive
+		 * counters, we need to reset it anyway
+		 */
+		found = 1;
+		active = 0;
+		for (j = 0; j < cpuhw->n_events; ++j) {
+			event = cpuhw->event[j];
+			if (event->hw.idx == (i + 1)) {
+				active = 1;
+				record_and_restart(event, val[i], regs);
+				break;
+			}
 		}
+		if (!active)
+			/* reset non active counters that have overflowed */
+			write_pmc(i + 1, 0);
 	}
-
-	/*
-	 * In case we didn't find and reset the event that caused
-	 * the interrupt, scan all events and reset any that are
-	 * negative, to avoid getting continual interrupts.
-	 * Any that we processed in the previous loop will not be negative.
-	 */
-	if (!found) {
-		for (i = 0; i < ppmu->n_counter; ++i) {
-			if (is_limited_pmc(i + 1))
+	if (!found && pvr_version_is(PVR_POWER7)) {
+		/* check active counters for special buggy p7 overflow */
+		for (i = 0; i < cpuhw->n_events; ++i) {
+			event = cpuhw->event[i];
+			if (!event->hw.idx || is_limited_pmc(event->hw.idx))
 				continue;
-			val = read_pmc(i + 1);
-			if (pmc_overflow(val))
-				write_pmc(i + 1, 0);
+			if (pmc_overflow_power7(val[event->hw.idx - 1])) {
+				/* event has overflowed in a buggy way*/
+				found = 1;
+				record_and_restart(event,
+						   val[event->hw.idx - 1],
+						   regs);
+			}
 		}
 	}
+	if (!found)
+		printk(KERN_WARNING "Can't find PMC that caused IRQ\n");
 
 	/*
 	 * Reset MMCR0 to its normal value.  This will set PMXE and
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH 3/4 v4] iommu/fsl: Add iommu domain attributes required by fsl PAMU driver.
From: Scott Wood @ 2012-11-05 23:56 UTC (permalink / raw)
  To: Varun Sethi
  Cc: joerg.roedel, linux-kernel, iommu, Varun Sethi, linuxppc-dev,
	timur
In-Reply-To: <1352114361-25192-3-git-send-email-Varun.Sethi@freescale.com>

On 11/05/2012 05:19:20 AM, Varun Sethi wrote:
> Added the following domain attributes required by FSL PAMU driver:
> 1. Subwindows field added to the iommu domain geometry attribute.
> 2. Added new iommu stash attribute, which allows setting of the
>    LIODN specific stash id parameter through IOMMU API.
> 3. Added an attribute for enabling/disabling DMA to a particular
>    memory window.
>=20
>=20
> Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>
> ---
> changes in v4:
> - Updated comment explaining subwindows(as mentioned by Scott).
> change in v3:
> -renamed the stash attribute targets
>  include/linux/iommu.h |   36 ++++++++++++++++++++++++++++++++++++
>  1 files changed, 36 insertions(+), 0 deletions(-)
>=20
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index f3b99e1..e72f5e5 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -44,6 +44,34 @@ struct iommu_domain_geometry {
>  	dma_addr_t aperture_start; /* First address that can be =20
> mapped    */
>  	dma_addr_t aperture_end;   /* Last address that can be =20
> mapped     */
>  	bool force_aperture;       /* DMA only allowed in mappable =20
> range? */
> +
> +	/**
> +	 * There could be a single contiguous window tha maps the entire
> +	 * geometry or it could be split in to multiple subwindows.

...or it could be a normal IOMMU that supports arbitrary paging =20
throughout the aperture.

> +	 * Subwindows allow for supporting physically discontiguous =20
> mappings.

...in the absence of arbitrary paging.

> +	 * This attribute indicates number of DMA subwindows supported =20
> by
> +	 * the geometry.

s/indicates number/indicates the number/

>   If there is a single window that maps the entire
> +	 * geometry, attribute must be set to "1". A value of "0" =20
> implies
> +	 * that there are 256 subwindows each of size 4K. Value other =20
> than
> +	 * "0" or "1" indicates the actual number of subwindows.

No, a value of "0" indicates that this mechanism is not in use at all, =20
and normal paging is used.  PAMU specific things like "256 subwindows" =20
must not be a default value in a generic API.

In the case of PAMU, if you specify 0 here, the aperture is limited to =20
1 MiB because that is the limit of PAMU's ability to simulate arbitrary =20
paging with subwindows, but this is only the limit of one =20
implementation.  It's not part of the API.

-Scott=

^ permalink raw reply

* Re: [PATCH 4/4 v4] iommu/fsl: Freescale PAMU driver and IOMMU API implementation.
From: Scott Wood @ 2012-11-05 23:11 UTC (permalink / raw)
  To: Timur Tabi; +Cc: Varun Sethi, iommu, linuxppc-dev, linux-kernel, joerg.roedel
In-Reply-To: <509845ED.2060904@freescale.com>

On 11/05/2012 05:04:13 PM, Timur Tabi wrote:
> Varun Sethi wrote:
> > +	/* PAACE Offset 0x00 */
> > +	u32 wbah;				/* only valid for =20
> Primary PAACE */
> > +	u32 addr_bitfields;		/* See P/S PAACE_AF_* */
> > +
> > +	/* PAACE Offset 0x08 */
> > +	/* Interpretation of first 32 bits dependent on DD above */
> > +	union {
> > +		struct {
> > +			/* Destination ID, see PAACE_DID_* defines */
> > +			u8 did;
> > +			/* Partition ID */
> > +			u8 pid;
> > +			/* Snoop ID */
> > +			u8 snpid;
> > +			/* coherency_required : 1 reserved : 7 */
>=20
> Please use this format, which is easier to read:
>=20
> 			/* 1 =3D=3D coherency required, 7 =3D=3D reserved */
>=20
> Every time I look at this comment, I think you are using bitfields.

It is meant as a pseudo-bitfield.  "7 =3D=3D reserved" doesn't make much =20
sense -- that would leave a lot of other values neither defined nor =20
explicitly reserved.

That said, the "See PAACE_DA_*" comment should be sufficient and avoids =20
making people have to care about what bitfield ordering the comment =20
writer was assuming.

-Scott=

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox