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.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/cpumask.hlinux/interrupt.hlinux/smp.hlinux/kernel.hlinux/perf_event.hlinux/uaccess.hlinux/sched/task_stack.hasm/irq.hasm/irq_regs.hasm/stacktrace.hasm/unwind.h
Detected Declarations
struct cpu_hw_eventsstruct loongarch_perf_eventstruct loongarch_pmufunction Copyrightfunction perf_callchain_userfunction perf_callchain_kernelfunction loongarch_pmu_read_counterfunction loongarch_pmu_write_counterfunction loongarch_pmu_read_controlfunction loongarch_pmu_write_controlfunction loongarch_pmu_alloc_counterfunction loongarch_pmu_enable_eventfunction loongarch_pmu_disable_eventfunction loongarch_pmu_event_set_periodfunction loongarch_pmu_event_updatefunction loongarch_pmu_startfunction loongarch_pmu_stopfunction loongarch_pmu_addfunction loongarch_pmu_delfunction loongarch_pmu_readfunction loongarch_pmu_enablefunction loongarch_pmu_disablefunction hw_perf_event_destroyfunction handle_associated_eventfunction pmu_handle_irqfunction loongarch_pmu_event_initfunction loongarch_pmu_perf_event_encodefunction loongarch_pmu_event_requires_counterfunction validate_groupfunction for_each_sibling_eventfunction reset_countersfunction __hw_perf_event_initfunction pause_local_countersfunction resume_local_countersfunction init_hw_perf_events
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
- Immediate include surface: `linux/cpumask.h`, `linux/interrupt.h`, `linux/smp.h`, `linux/kernel.h`, `linux/perf_event.h`, `linux/uaccess.h`, `linux/sched/task_stack.h`, `asm/irq.h`.
- Detected declarations: `struct cpu_hw_events`, `struct loongarch_perf_event`, `struct loongarch_pmu`, `function Copyright`, `function perf_callchain_user`, `function perf_callchain_kernel`, `function loongarch_pmu_read_counter`, `function loongarch_pmu_write_counter`, `function loongarch_pmu_read_control`, `function loongarch_pmu_write_control`.
- Atlas domain: Architecture Layer / arch/loongarch.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.