arch/sh/kernel/perf_event.c
Source file repositories/reference/linux-study-clean/arch/sh/kernel/perf_event.c
File Facts
- System
- Linux kernel
- Corpus path
arch/sh/kernel/perf_event.c- Extension
.c- Size
- 8464 bytes
- Lines
- 364
- Domain
- Architecture Layer
- Bucket
- arch/sh
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/init.hlinux/io.hlinux/irq.hlinux/perf_event.hlinux/export.hasm/processor.h
Detected Declarations
struct cpu_hw_eventsfunction reserve_pmc_hardwarefunction release_pmc_hardwarefunction hw_perf_event_destroyfunction hw_perf_cache_eventfunction __hw_perf_event_initfunction sh_perf_event_updatefunction sh_pmu_stopfunction sh_pmu_startfunction sh_pmu_delfunction sh_pmu_addfunction sh_pmu_readfunction sh_pmu_event_initfunction sh_pmu_enablefunction sh_pmu_disablefunction sh_pmu_prepare_cpufunction register_sh_pmu
Annotated Snippet
struct cpu_hw_events {
struct perf_event *events[MAX_HWEVENTS];
unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
unsigned long active_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
};
DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
static struct sh_pmu *sh_pmu __read_mostly;
/* Number of perf_events counting hardware events */
static atomic_t num_events;
/* Used to avoid races in calling reserve/release_pmc_hardware */
static DEFINE_MUTEX(pmc_reserve_mutex);
/*
* Stub these out for now, do something more profound later.
*/
int reserve_pmc_hardware(void)
{
return 0;
}
void release_pmc_hardware(void)
{
}
static inline int sh_pmu_initialized(void)
{
return !!sh_pmu;
}
/*
* Release the PMU if this is the last perf_event.
*/
static void hw_perf_event_destroy(struct perf_event *event)
{
if (!atomic_add_unless(&num_events, -1, 1)) {
mutex_lock(&pmc_reserve_mutex);
if (atomic_dec_return(&num_events) == 0)
release_pmc_hardware();
mutex_unlock(&pmc_reserve_mutex);
}
}
static int hw_perf_cache_event(int config, int *evp)
{
unsigned long type, op, result;
int ev;
if (!sh_pmu->cache_events)
return -EINVAL;
/* unpack config */
type = config & 0xff;
op = (config >> 8) & 0xff;
result = (config >> 16) & 0xff;
if (type >= PERF_COUNT_HW_CACHE_MAX ||
op >= PERF_COUNT_HW_CACHE_OP_MAX ||
result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
return -EINVAL;
ev = (*sh_pmu->cache_events)[type][op][result];
if (ev == 0)
return -EOPNOTSUPP;
if (ev == -1)
return -EINVAL;
*evp = ev;
return 0;
}
static int __hw_perf_event_init(struct perf_event *event)
{
struct perf_event_attr *attr = &event->attr;
struct hw_perf_event *hwc = &event->hw;
int config = -1;
int err;
if (!sh_pmu_initialized())
return -ENODEV;
/*
* See if we need to reserve the counter.
*
* If no events are currently in use, then we have to take a
* mutex to ensure that we don't race with another task doing
* reserve_pmc_hardware or release_pmc_hardware.
*/
err = 0;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/init.h`, `linux/io.h`, `linux/irq.h`, `linux/perf_event.h`, `linux/export.h`, `asm/processor.h`.
- Detected declarations: `struct cpu_hw_events`, `function reserve_pmc_hardware`, `function release_pmc_hardware`, `function hw_perf_event_destroy`, `function hw_perf_cache_event`, `function __hw_perf_event_init`, `function sh_perf_event_update`, `function sh_pmu_stop`, `function sh_pmu_start`, `function sh_pmu_del`.
- Atlas domain: Architecture Layer / arch/sh.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.