drivers/gpu/drm/msm/msm_perfcntr.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/msm/msm_perfcntr.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/msm/msm_perfcntr.c- Extension
.c- Size
- 18557 bytes
- Lines
- 671
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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
drm/drm_file.hdrm/msm_drm.hlinux/anon_inodes.hlinux/gfp_types.hlinux/poll.hlinux/slab.hmsm_drv.hmsm_gpu.hmsm_perfcntr.hadreno/adreno_gpu.h
Detected Declarations
function Copyrightfunction msm_perfcntr_resumefunction msm_perfcntr_suspend_lockedfunction msm_perfcntr_suspendfunction msm_perfcntrs_stream_releasefunction scoped_guardfunction msm_perfcntrs_stream_pollfunction msm_perfcntrs_stream_readfunction sel_workerfunction scoped_guardfunction sample_writefunction sample_write_u32function sample_write_u64function sample_workerfunction sample_timerfunction get_group_idxfunction get_available_countersfunction list_for_each_entryfunction msm_ioctl_perfcntr_configfunction tablesfunction msm_perfcntr_counter_basefunction __msm_perfcntr_cleanupfunction msm_perfcntr_cleanupfunction msm_perfcntr_init
Annotated Snippet
static const struct file_operations stream_fops = {
.owner = THIS_MODULE,
.release = msm_perfcntrs_stream_release,
.poll = msm_perfcntrs_stream_poll,
.read = msm_perfcntrs_stream_read,
};
static void
sel_worker(struct work_struct *w)
{
struct msm_perfcntr_stream *stream =
container_of(w, typeof(*stream), sel_work);
struct msm_gpu *gpu = stream->gpu;
/* Reprogram SEL regs on highest priority rb: */
struct msm_ringbuffer *ring = stream->gpu->rb[0];
/*
* If in the process of resuming, wait for that. Otherwise sel_worker
* which is enqueued in the resume path can be scheduled before the
* resume completes.
*/
pm_runtime_barrier(&gpu->pdev->dev);
/*
* sel_work could end up scheduled before suspend, but running
* after. See msm_perfcntr_suspend_locked()
*
* So if we end up running sel_work after the GPU is already
* suspended, just bail. It will be scheduled again after
* the GPU is resumed.
*/
if (!pm_runtime_get_if_active(&gpu->pdev->dev))
return;
scoped_guard (mutex, &gpu->lock) {
guard(mutex)(&gpu->perfcntr_lock);
if (stream == gpu->perfcntrs->stream) {
msm_gpu_hw_init(gpu);
gpu->funcs->perfcntr_configure(gpu, ring, stream);
}
}
pm_runtime_put_autosuspend(&gpu->pdev->dev);
}
static void
sample_write(struct msm_perfcntr_stream *stream, int *head, const void *buf, size_t sz)
{
/*
* FIFO size is power-of-two, and guaranteed to have enough space to
* fit what we are writing. So we should not hit the wrap-around
* point writing things that are power-of-two sized
*/
WARN_ON(CIRC_SPACE_TO_END(*head, stream->fifo.tail, stream->fifo_size) < sz);
memcpy(&stream->fifo.buf[*head], buf, sz);
/* Advance head, wrapping around if necessary: */
*head = (*head + sz) & (stream->fifo_size - 1);
}
static void
sample_write_u32(struct msm_perfcntr_stream *stream, int *head, uint32_t val)
{
sample_write(stream, head, &val, sizeof(val));
}
static void
sample_write_u64(struct msm_perfcntr_stream *stream, int *head, uint64_t val)
{
sample_write(stream, head, &val, sizeof(val));
}
static void
sample_worker(struct kthread_work *work)
{
struct msm_perfcntr_stream *stream =
container_of(work, typeof(*stream), sample_work);
struct msm_gpu *gpu = stream->gpu;
struct msm_rbmemptrs *memptrs = gpu->rb[0]->memptrs;
if (memptrs->perfcntr_fence != stream->sel_fence)
return;
/*
* Ensure we have enough space to capture a sample period's
* worth of data:
*/
if (stream->period_size > fifo_space(stream)) {
Annotation
- Immediate include surface: `drm/drm_file.h`, `drm/msm_drm.h`, `linux/anon_inodes.h`, `linux/gfp_types.h`, `linux/poll.h`, `linux/slab.h`, `msm_drv.h`, `msm_gpu.h`.
- Detected declarations: `function Copyright`, `function msm_perfcntr_resume`, `function msm_perfcntr_suspend_locked`, `function msm_perfcntr_suspend`, `function msm_perfcntrs_stream_release`, `function scoped_guard`, `function msm_perfcntrs_stream_poll`, `function msm_perfcntrs_stream_read`, `function sel_worker`, `function scoped_guard`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
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.