Skip to content

Commit 0d92382

Browse files
anjutsudhakarmpe
authored andcommitted
powerpc/perf: Fix for core/nest imc call trace on cpuhotplug
Nest/core pmu units are enabled only when it is used. A reference count is maintained for the events which uses the nest/core pmu units. Currently in *_imc_counters_release function a WARN() is used for notification of any underflow of ref count. The case where event ref count hit a negative value is, when perf session is started, followed by offlining of all cpus in a given core. i.e. in cpuhotplug offline path ppc_core_imc_cpu_offline() function set the ref->count to zero, if the current 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. And on perf session termination, perf->destroy (core_imc_counters_release) will first decrement the ref->count for this core and based on the ref->count value an opal call is made to disable the core-imc engine. Now, since cpuhotplug path already clears the ref->count for core and disabled the engine, perf->destroy() decrementing again at event termination make it negative which in turn fires the WARN_ON. The same happens for nest units. Add a check to see if the reference count is alreday zero, before decrementing the count, so that the ref count will not hit a negative value. Signed-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com> Reviewed-by: Santosh Sivaraj <santosh@fossix.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent 6b2c08f commit 0d92382

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

arch/powerpc/perf/imc-pmu.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,20 @@ static void nest_imc_counters_release(struct perf_event *event)
399399

400400
/* Take the mutex lock for this node and then decrement the reference count */
401401
mutex_lock(&ref->lock);
402+
if (ref->refc == 0) {
403+
/*
404+
* The scenario where this is true is, when perf session is
405+
* started, followed by offlining of all cpus in a given node.
406+
*
407+
* In the cpuhotplug offline path, ppc_nest_imc_cpu_offline()
408+
* function set the ref->count to zero, if the cpu which is
409+
* about to offline is the last cpu in a given node and make
410+
* an OPAL call to disable the engine in that node.
411+
*
412+
*/
413+
mutex_unlock(&ref->lock);
414+
return;
415+
}
402416
ref->refc--;
403417
if (ref->refc == 0) {
404418
rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST,
@@ -646,6 +660,20 @@ static void core_imc_counters_release(struct perf_event *event)
646660
return;
647661

648662
mutex_lock(&ref->lock);
663+
if (ref->refc == 0) {
664+
/*
665+
* The scenario where this is true is, when perf session is
666+
* started, followed by offlining of all cpus in a given core.
667+
*
668+
* In the cpuhotplug offline path, ppc_core_imc_cpu_offline()
669+
* function set the ref->count to zero, if the cpu which is
670+
* about to offline is the last cpu in a given core and make
671+
* an OPAL call to disable the engine in that core.
672+
*
673+
*/
674+
mutex_unlock(&ref->lock);
675+
return;
676+
}
649677
ref->refc--;
650678
if (ref->refc == 0) {
651679
rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE,

0 commit comments

Comments
 (0)