arch/powerpc/perf/imc-pmu.c
Source file repositories/reference/linux-study-clean/arch/powerpc/perf/imc-pmu.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/perf/imc-pmu.c- Extension
.c- Size
- 47431 bytes
- Lines
- 1872
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/of.hlinux/perf_event.hlinux/slab.hasm/opal.hasm/imc-pmu.hasm/cputhreads.hasm/smp.hlinux/string.hlinux/spinlock.h
Detected Declarations
function imc_pmu_cpumask_get_attrfunction imc_parse_eventfunction imc_free_eventsfunction update_events_in_groupfunction nest_change_cpu_contextfunction ppc_nest_imc_cpu_offlinefunction ppc_nest_imc_cpu_onlinefunction nest_pmu_cpumask_initfunction nest_imc_counters_releasefunction nest_imc_event_initfunction alloc_pages_nodefunction is_core_imc_mem_initedfunction ppc_core_imc_cpu_onlinefunction ppc_core_imc_cpu_offlinefunction core_imc_pmu_cpumask_initfunction reset_global_refcfunction domainfunction core_imc_counters_releasefunction core_imc_event_initfunction thread_imc_mem_allocfunction ppc_thread_imc_cpu_onlinefunction ppc_thread_imc_cpu_offlinefunction thread_imc_cpu_initfunction thread_imc_event_initfunction is_thread_imc_pmufunction thread_imc_pmu_start_txnfunction thread_imc_pmu_cancel_txnfunction thread_imc_pmu_commit_txnfunction imc_read_counterfunction imc_event_updatefunction imc_event_startfunction imc_event_stopfunction imc_event_addfunction thread_imc_event_addfunction thread_imc_event_delfunction trace_imc_mem_allocfunction ppc_trace_imc_cpu_onlinefunction ppc_trace_imc_cpu_offlinefunction trace_imc_cpu_initfunction get_trace_imc_event_base_addrfunction trace_imc_prepare_samplefunction dump_trace_imc_datafunction trace_imc_event_addfunction trace_imc_event_readfunction trace_imc_event_stopfunction trace_imc_event_startfunction trace_imc_event_delfunction trace_imc_event_init
Annotated Snippet
if (pmu->events[i].scale) {
ev_scale_str = kasprintf(GFP_KERNEL, "%s.scale", pmu->events[i].name);
if (!ev_scale_str)
continue;
dev_str = device_str_attr_create(ev_scale_str, pmu->events[i].scale);
if (!dev_str)
continue;
attrs[j++] = dev_str;
}
if (pmu->events[i].unit) {
ev_unit_str = kasprintf(GFP_KERNEL, "%s.unit", pmu->events[i].name);
if (!ev_unit_str)
continue;
dev_str = device_str_attr_create(ev_unit_str, pmu->events[i].unit);
if (!dev_str)
continue;
attrs[j++] = dev_str;
}
} while (++i < ct);
/* Save the event attribute */
pmu->attr_groups[IMC_EVENT_ATTR] = attr_group;
return 0;
}
/* get_nest_pmu_ref: Return the imc_pmu_ref struct for the given node */
static struct imc_pmu_ref *get_nest_pmu_ref(int cpu)
{
return per_cpu(local_nest_imc_refc, cpu);
}
static void nest_change_cpu_context(int old_cpu, int new_cpu)
{
struct imc_pmu **pn = per_nest_pmu_arr;
if (old_cpu < 0 || new_cpu < 0)
return;
while (*pn) {
perf_pmu_migrate_context(&(*pn)->pmu, old_cpu, new_cpu);
pn++;
}
}
static int ppc_nest_imc_cpu_offline(unsigned int cpu)
{
int nid, target = -1;
const struct cpumask *l_cpumask;
struct imc_pmu_ref *ref;
/*
* Check in the designated list for this cpu. Dont bother
* if not one of them.
*/
if (!cpumask_test_and_clear_cpu(cpu, &nest_imc_cpumask))
return 0;
/*
* Check whether nest_imc is registered. We could end up here if the
* cpuhotplug callback registration fails. i.e, callback invokes the
* offline path for all successfully registered nodes. At this stage,
* nest_imc pmu will not be registered and we should return here.
*
* We return with a zero since this is not an offline failure. And
* cpuhp_setup_state() returns the actual failure reason to the caller,
* which in turn will call the cleanup routine.
*/
if (!nest_pmus)
return 0;
/*
* Now that this cpu is one of the designated,
* find a next cpu a) which is online and b) in same chip.
*/
nid = cpu_to_node(cpu);
l_cpumask = cpumask_of_node(nid);
target = cpumask_last(l_cpumask);
/*
* If this(target) is the last cpu in the cpumask for this chip,
* check for any possible online cpu in the chip.
*/
if (unlikely(target == cpu))
target = cpumask_any_but(l_cpumask, cpu);
/*
Annotation
- Immediate include surface: `linux/of.h`, `linux/perf_event.h`, `linux/slab.h`, `asm/opal.h`, `asm/imc-pmu.h`, `asm/cputhreads.h`, `asm/smp.h`, `linux/string.h`.
- Detected declarations: `function imc_pmu_cpumask_get_attr`, `function imc_parse_event`, `function imc_free_events`, `function update_events_in_group`, `function nest_change_cpu_context`, `function ppc_nest_imc_cpu_offline`, `function ppc_nest_imc_cpu_online`, `function nest_pmu_cpumask_init`, `function nest_imc_counters_release`, `function nest_imc_event_init`.
- Atlas domain: Architecture Layer / arch/powerpc.
- 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.