arch/loongarch/kernel/perf_event.c

Source file repositories/reference/linux-study-clean/arch/loongarch/kernel/perf_event.c

File Facts

System
Linux kernel
Corpus path
arch/loongarch/kernel/perf_event.c
Extension
.c
Size
21921 bytes
Lines
893
Domain
Architecture Layer
Bucket
arch/loongarch
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct cpu_hw_events {
	/* Array of events on this cpu. */
	struct perf_event	*events[LOONGARCH_MAX_HWEVENTS];

	/*
	 * Set the bit (indexed by the counter number) when the counter
	 * is used for an event.
	 */
	unsigned long		used_mask[BITS_TO_LONGS(LOONGARCH_MAX_HWEVENTS)];

	/*
	 * Software copy of the control register for each performance counter.
	 */
	unsigned int		saved_ctrl[LOONGARCH_MAX_HWEVENTS];
};
static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
	.saved_ctrl = {0},
};

/* The description of LoongArch performance events. */
struct loongarch_perf_event {
	unsigned int event_id;
};

static struct loongarch_perf_event raw_event;
static DEFINE_MUTEX(raw_event_mutex);

#define C(x) PERF_COUNT_HW_CACHE_##x
#define HW_OP_UNSUPPORTED		0xffffffff
#define CACHE_OP_UNSUPPORTED		0xffffffff

#define PERF_MAP_ALL_UNSUPPORTED					\
	[0 ... PERF_COUNT_HW_MAX - 1] = {HW_OP_UNSUPPORTED}

#define PERF_CACHE_MAP_ALL_UNSUPPORTED					\
[0 ... C(MAX) - 1] = {							\
	[0 ... C(OP_MAX) - 1] = {					\
		[0 ... C(RESULT_MAX) - 1] = {CACHE_OP_UNSUPPORTED},	\
	},								\
}

struct loongarch_pmu {
	u64		max_period;
	u64		valid_count;
	u64		overflow;
	const char	*name;
	unsigned int	num_counters;
	u64		(*read_counter)(unsigned int idx);
	void		(*write_counter)(unsigned int idx, u64 val);
	const struct loongarch_perf_event *(*map_raw_event)(u64 config);
	const struct loongarch_perf_event (*general_event_map)[PERF_COUNT_HW_MAX];
	const struct loongarch_perf_event (*cache_event_map)
				[PERF_COUNT_HW_CACHE_MAX]
				[PERF_COUNT_HW_CACHE_OP_MAX]
				[PERF_COUNT_HW_CACHE_RESULT_MAX];
};

static struct loongarch_pmu loongarch_pmu;

#define M_PERFCTL_EVENT(event)	(event & CSR_PERFCTRL_EVENT)

#define M_PERFCTL_COUNT_EVENT_WHENEVER	(CSR_PERFCTRL_PLV0 |	\
					CSR_PERFCTRL_PLV1 |	\
					CSR_PERFCTRL_PLV2 |	\
					CSR_PERFCTRL_PLV3 |	\
					CSR_PERFCTRL_IE)

#define M_PERFCTL_CONFIG_MASK		0x1f0000

static void pause_local_counters(void);
static void resume_local_counters(void);

static u64 loongarch_pmu_read_counter(unsigned int idx)
{
	u64 val = -1;

	switch (idx) {
	case 0:
		val = read_csr_perfcntr0();
		break;
	case 1:
		val = read_csr_perfcntr1();
		break;
	case 2:
		val = read_csr_perfcntr2();
		break;
	case 3:
		val = read_csr_perfcntr3();
		break;
	default:

Annotation

Implementation Notes