Commit 25af86b2 authored by Anju T Sudhakar's avatar Anju T Sudhakar Committed by Michael Ellerman
Browse files

powerpc/perf: Unregister thread-imc if core-imc not supported



Since thread-imc internally use the core-imc hardware infrastructure
and is depended on it, having thread-imc in the kernel in the
absence of core-imc is trivial. Patch disables thread-imc, if
core-imc is not registered.

Signed-off-by: default avatarAnju T Sudhakar <anju@linux.vnet.ibm.com>
Reviewed-by: default avatarMadhavan Srinivasan <maddy@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent e7a8ac43
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -128,4 +128,5 @@ extern int init_imc_pmu(struct device_node *parent,
				struct imc_pmu *pmu_ptr, int pmu_id);
extern void thread_imc_disable(void);
extern int get_max_nest_dev(void);
extern void unregister_thread_imc(void);
#endif /* __ASM_POWERPC_IMC_PMU_H */
+12 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ static struct imc_pmu *core_imc_pmu;
/* Thread IMC data structures and variables */

static DEFINE_PER_CPU(u64 *, thread_imc_mem);
static struct imc_pmu *thread_imc_pmu;
static int thread_imc_mem_size;

struct imc_pmu *imc_event_to_pmu(struct perf_event *event)
@@ -1228,6 +1229,16 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr)
	}
}

/*
 * Function to unregister thread-imc if core-imc
 * is not registered.
 */
void unregister_thread_imc(void)
{
	imc_common_cpuhp_mem_free(thread_imc_pmu);
	imc_common_mem_free(thread_imc_pmu);
	perf_pmu_unregister(&thread_imc_pmu->pmu);
}

/*
 * imc_mem_init : Function to support memory allocation for core imc.
@@ -1296,6 +1307,7 @@ static int imc_mem_init(struct imc_pmu *pmu_ptr, struct device_node *parent,
			}
		}

		thread_imc_pmu = pmu_ptr;
		break;
	default:
		return -EINVAL;
+9 −0
Original line number Diff line number Diff line
@@ -255,6 +255,7 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
{
	struct device_node *imc_dev = pdev->dev.of_node;
	int pmu_count = 0, domain;
	bool core_imc_reg = false, thread_imc_reg = false;
	u32 type;

	/*
@@ -292,6 +293,10 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
		if (!imc_pmu_create(imc_dev, pmu_count, domain)) {
			if (domain == IMC_DOMAIN_NEST)
				pmu_count++;
			if (domain == IMC_DOMAIN_CORE)
				core_imc_reg = true;
			if (domain == IMC_DOMAIN_THREAD)
				thread_imc_reg = true;
		}
	}

@@ -299,6 +304,10 @@ static int opal_imc_counters_probe(struct platform_device *pdev)
	if (pmu_count == 0)
		debugfs_remove_recursive(imc_debugfs_parent);

	/* If core imc is not registered, unregister thread-imc */
	if (!core_imc_reg && thread_imc_reg)
		unregister_thread_imc();

	return 0;
}