diff options
Diffstat (limited to 'arch/powerpc/perf')
| -rw-r--r-- | arch/powerpc/perf/Makefile | 1 | ||||
| -rw-r--r-- | arch/powerpc/perf/core-book3s.c | 5 | ||||
| -rw-r--r-- | arch/powerpc/perf/hv-24x7-catalog.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/perf/hv-24x7-domains.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/perf/hv-24x7.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/perf/hv-common.c | 1 | ||||
| -rw-r--r-- | arch/powerpc/perf/hv-common.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/perf/hv-gpci-requests.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/perf/hv-gpci.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/perf/imc-pmu.c | 57 | ||||
| -rw-r--r-- | arch/powerpc/perf/req-gen/_begin.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/perf/req-gen/_clear.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/perf/req-gen/_request-begin.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/perf/req-gen/_request-end.h | 1 | ||||
| -rw-r--r-- | arch/powerpc/perf/req-gen/perf.h | 1 | 
15 files changed, 68 insertions, 7 deletions
| diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile index 3f3a5ce66495..225c9c86d7c0 100644 --- a/arch/powerpc/perf/Makefile +++ b/arch/powerpc/perf/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0  subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror  obj-$(CONFIG_PERF_EVENTS)	+= callchain.o perf_regs.o diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 2e3eb7431571..9e3da168d54c 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -793,6 +793,11 @@ void perf_event_print_debug(void)  	u32 pmcs[MAX_HWEVENTS];  	int i; +	if (!ppmu) { +		pr_info("Performance monitor hardware not registered.\n"); +		return; +	} +  	if (!ppmu->n_counter)  		return; diff --git a/arch/powerpc/perf/hv-24x7-catalog.h b/arch/powerpc/perf/hv-24x7-catalog.h index 69e2e1faf902..5fab5a397da9 100644 --- a/arch/powerpc/perf/hv-24x7-catalog.h +++ b/arch/powerpc/perf/hv-24x7-catalog.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #ifndef LINUX_POWERPC_PERF_HV_24X7_CATALOG_H_  #define LINUX_POWERPC_PERF_HV_24X7_CATALOG_H_ diff --git a/arch/powerpc/perf/hv-24x7-domains.h b/arch/powerpc/perf/hv-24x7-domains.h index 49c1efd50045..6f91f62e0aa6 100644 --- a/arch/powerpc/perf/hv-24x7-domains.h +++ b/arch/powerpc/perf/hv-24x7-domains.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  /*   * DOMAIN(name, num, index_kind, is_physical) diff --git a/arch/powerpc/perf/hv-24x7.h b/arch/powerpc/perf/hv-24x7.h index 5092c4a222a6..ae4ae4813e16 100644 --- a/arch/powerpc/perf/hv-24x7.h +++ b/arch/powerpc/perf/hv-24x7.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #ifndef LINUX_POWERPC_PERF_HV_24X7_H_  #define LINUX_POWERPC_PERF_HV_24X7_H_ diff --git a/arch/powerpc/perf/hv-common.c b/arch/powerpc/perf/hv-common.c index 7dce8f109967..0370518edd20 100644 --- a/arch/powerpc/perf/hv-common.c +++ b/arch/powerpc/perf/hv-common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0  #include <asm/io.h>  #include <asm/hvcall.h> diff --git a/arch/powerpc/perf/hv-common.h b/arch/powerpc/perf/hv-common.h index 349aaba4d2d1..2cce17bc321c 100644 --- a/arch/powerpc/perf/hv-common.h +++ b/arch/powerpc/perf/hv-common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #ifndef LINUX_POWERPC_PERF_HV_COMMON_H_  #define LINUX_POWERPC_PERF_HV_COMMON_H_ diff --git a/arch/powerpc/perf/hv-gpci-requests.h b/arch/powerpc/perf/hv-gpci-requests.h index acd17648cd18..e608f9db12dd 100644 --- a/arch/powerpc/perf/hv-gpci-requests.h +++ b/arch/powerpc/perf/hv-gpci-requests.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #include "req-gen/_begin.h" diff --git a/arch/powerpc/perf/hv-gpci.h b/arch/powerpc/perf/hv-gpci.h index 86ede8275961..a3053eda5dcc 100644 --- a/arch/powerpc/perf/hv-gpci.h +++ b/arch/powerpc/perf/hv-gpci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #ifndef LINUX_POWERPC_PERF_HV_GPCI_H_  #define LINUX_POWERPC_PERF_HV_GPCI_H_ diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 9ccac86f3463..36344117c680 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -399,6 +399,20 @@ static void nest_imc_counters_release(struct perf_event *event)  	/* Take the mutex lock for this node and then decrement the reference count */  	mutex_lock(&ref->lock); +	if (ref->refc == 0) { +		/* +		 * The scenario where this is true is, when perf session is +		 * started, followed by offlining of all cpus in a given node. +		 * +		 * In the cpuhotplug offline path, ppc_nest_imc_cpu_offline() +		 * function set the ref->count to zero, if the cpu which is +		 * about to offline is the last cpu in a given node and make +		 * an OPAL call to disable the engine in that node. +		 * +		 */ +		mutex_unlock(&ref->lock); +		return; +	}  	ref->refc--;  	if (ref->refc == 0) {  		rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST, @@ -523,8 +537,8 @@ static int core_imc_mem_init(int cpu, int size)  	/* We need only vbase for core counters */  	mem_info->vbase = page_address(alloc_pages_node(phys_id, -					  GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, -					  get_order(size))); +					  GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE | +					  __GFP_NOWARN, get_order(size)));  	if (!mem_info->vbase)  		return -ENOMEM; @@ -593,6 +607,20 @@ static int ppc_core_imc_cpu_offline(unsigned int cpu)  	if (!cpumask_test_and_clear_cpu(cpu, &core_imc_cpumask))  		return 0; +	/* +	 * Check whether core_imc is registered. We could end up here +	 * if the cpuhotplug callback registration fails. i.e, callback +	 * invokes the offline path for all sucessfully registered cpus. +	 * At this stage, core_imc pmu will not be registered and we +	 * should return here. +	 * +	 * We return with a zero since this is not an offline failure. +	 * And cpuhp_setup_state() returns the actual failure reason +	 * to the caller, which inturn will call the cleanup routine. +	 */ +	if (!core_imc_pmu->pmu.event_init) +		return 0; +  	/* Find any online cpu in that core except the current "cpu" */  	ncpu = cpumask_any_but(cpu_sibling_mask(cpu), cpu); @@ -646,6 +674,20 @@ static void core_imc_counters_release(struct perf_event *event)  		return;  	mutex_lock(&ref->lock); +	if (ref->refc == 0) { +		/* +		 * The scenario where this is true is, when perf session is +		 * started, followed by offlining of all cpus in a given core. +		 * +		 * In the cpuhotplug offline path, ppc_core_imc_cpu_offline() +		 * function set the ref->count to zero, if the cpu which is +		 * about to offline is the last cpu in a given core and make +		 * an OPAL call to disable the engine in that core. +		 * +		 */ +		mutex_unlock(&ref->lock); +		return; +	}  	ref->refc--;  	if (ref->refc == 0) {  		rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE, @@ -763,8 +805,8 @@ static int thread_imc_mem_alloc(int cpu_id, int size)  		 * free the memory in cpu offline path.  		 */  		local_mem = page_address(alloc_pages_node(phys_id, -				  GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, -				  get_order(size))); +				  GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE | +				  __GFP_NOWARN, get_order(size)));  		if (!local_mem)  			return -ENOMEM; @@ -1076,7 +1118,7 @@ static int init_nest_pmu_ref(void)  static void cleanup_all_core_imc_memory(void)  { -	int i, nr_cores = num_present_cpus() / threads_per_core; +	int i, nr_cores = DIV_ROUND_UP(num_present_cpus(), threads_per_core);  	struct imc_mem_info *ptr = core_imc_pmu->mem_info;  	int size = core_imc_pmu->counter_mem_size; @@ -1148,7 +1190,8 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr)  	}  	/* Only free the attr_groups which are dynamically allocated  */ -	kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs); +	if (pmu_ptr->attr_groups[IMC_EVENT_ATTR]) +		kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs);  	kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]);  	kfree(pmu_ptr);  	return; @@ -1183,7 +1226,7 @@ static int imc_mem_init(struct imc_pmu *pmu_ptr, struct device_node *parent,  		if (!pmu_ptr->pmu.name)  			return -ENOMEM; -		nr_cores = num_present_cpus() / threads_per_core; +		nr_cores = DIV_ROUND_UP(num_present_cpus(), threads_per_core);  		pmu_ptr->mem_info = kcalloc(nr_cores, sizeof(struct imc_mem_info),  								GFP_KERNEL); diff --git a/arch/powerpc/perf/req-gen/_begin.h b/arch/powerpc/perf/req-gen/_begin.h index acfb17a55c16..549f8782c52d 100644 --- a/arch/powerpc/perf/req-gen/_begin.h +++ b/arch/powerpc/perf/req-gen/_begin.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  /* Include paths to be used in interface defining headers */  #ifndef POWERPC_PERF_REQ_GEN_H_  #define POWERPC_PERF_REQ_GEN_H_ diff --git a/arch/powerpc/perf/req-gen/_clear.h b/arch/powerpc/perf/req-gen/_clear.h index 422974f89573..67c3859157f3 100644 --- a/arch/powerpc/perf/req-gen/_clear.h +++ b/arch/powerpc/perf/req-gen/_clear.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #undef __field_  #undef __count_ diff --git a/arch/powerpc/perf/req-gen/_request-begin.h b/arch/powerpc/perf/req-gen/_request-begin.h index f6d98642cf1d..7c74c2ab4c0c 100644 --- a/arch/powerpc/perf/req-gen/_request-begin.h +++ b/arch/powerpc/perf/req-gen/_request-begin.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #define REQUEST(r_contents) \  	REQUEST_(REQUEST_NAME, REQUEST_NUM, REQUEST_IDX_KIND, I(r_contents)) diff --git a/arch/powerpc/perf/req-gen/_request-end.h b/arch/powerpc/perf/req-gen/_request-end.h index 5573be6c3588..7d9f4046c2ca 100644 --- a/arch/powerpc/perf/req-gen/_request-end.h +++ b/arch/powerpc/perf/req-gen/_request-end.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #undef REQUEST  #undef __field  #undef __array diff --git a/arch/powerpc/perf/req-gen/perf.h b/arch/powerpc/perf/req-gen/perf.h index 1b122469323d..871a9a1766c2 100644 --- a/arch/powerpc/perf/req-gen/perf.h +++ b/arch/powerpc/perf/req-gen/perf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */  #ifndef LINUX_POWERPC_PERF_REQ_GEN_PERF_H_  #define LINUX_POWERPC_PERF_REQ_GEN_PERF_H_ |