block/blk-stat.c
Source file repositories/reference/linux-study-clean/block/blk-stat.c
File Facts
- System
- Linux kernel
- Corpus path
block/blk-stat.c- Extension
.c- Size
- 5186 bytes
- Lines
- 229
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/kernel.hlinux/rculist.hblk-stat.hblk-mq.hblk.h
Detected Declarations
struct blk_queue_statsfunction blk_rq_stat_initfunction blk_rq_stat_sumfunction blk_rq_stat_addfunction blk_stat_addfunction blk_stat_timer_fnfunction for_each_online_cpufunction blk_stat_alloc_callbackfunction blk_stat_add_callbackfunction for_each_possible_cpufunction blk_stat_remove_callbackfunction blk_stat_free_callback_rcufunction blk_stat_free_callbackfunction blk_stat_disable_accountingfunction blk_stat_enable_accountingfunction blk_free_queue_statsexport blk_stat_disable_accountingexport blk_stat_enable_accounting
Annotated Snippet
struct blk_queue_stats {
struct list_head callbacks;
spinlock_t lock;
int accounting;
};
void blk_rq_stat_init(struct blk_rq_stat *stat)
{
stat->min = -1ULL;
stat->max = stat->nr_samples = stat->mean = 0;
stat->batch = 0;
}
/* src is a per-cpu stat, mean isn't initialized */
void blk_rq_stat_sum(struct blk_rq_stat *dst, struct blk_rq_stat *src)
{
if (dst->nr_samples + src->nr_samples <= dst->nr_samples)
return;
dst->min = min(dst->min, src->min);
dst->max = max(dst->max, src->max);
dst->mean = div_u64(src->batch + dst->mean * dst->nr_samples,
dst->nr_samples + src->nr_samples);
dst->nr_samples += src->nr_samples;
}
void blk_rq_stat_add(struct blk_rq_stat *stat, u64 value)
{
stat->min = min(stat->min, value);
stat->max = max(stat->max, value);
stat->batch += value;
stat->nr_samples++;
}
void blk_stat_add(struct request *rq, u64 now)
{
struct request_queue *q = rq->q;
struct blk_stat_callback *cb;
struct blk_rq_stat *stat;
int bucket, cpu;
u64 value;
value = (now >= rq->io_start_time_ns) ? now - rq->io_start_time_ns : 0;
rcu_read_lock();
cpu = get_cpu();
list_for_each_entry_rcu(cb, &q->stats->callbacks, list) {
if (!blk_stat_is_active(cb))
continue;
bucket = cb->bucket_fn(rq);
if (bucket < 0)
continue;
stat = &per_cpu_ptr(cb->cpu_stat, cpu)[bucket];
blk_rq_stat_add(stat, value);
}
put_cpu();
rcu_read_unlock();
}
static void blk_stat_timer_fn(struct timer_list *t)
{
struct blk_stat_callback *cb = timer_container_of(cb, t, timer);
unsigned int bucket;
int cpu;
for (bucket = 0; bucket < cb->buckets; bucket++)
blk_rq_stat_init(&cb->stat[bucket]);
for_each_online_cpu(cpu) {
struct blk_rq_stat *cpu_stat;
cpu_stat = per_cpu_ptr(cb->cpu_stat, cpu);
for (bucket = 0; bucket < cb->buckets; bucket++) {
blk_rq_stat_sum(&cb->stat[bucket], &cpu_stat[bucket]);
blk_rq_stat_init(&cpu_stat[bucket]);
}
}
cb->timer_fn(cb);
}
struct blk_stat_callback *
blk_stat_alloc_callback(void (*timer_fn)(struct blk_stat_callback *),
int (*bucket_fn)(const struct request *),
unsigned int buckets, void *data)
{
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/rculist.h`, `blk-stat.h`, `blk-mq.h`, `blk.h`.
- Detected declarations: `struct blk_queue_stats`, `function blk_rq_stat_init`, `function blk_rq_stat_sum`, `function blk_rq_stat_add`, `function blk_stat_add`, `function blk_stat_timer_fn`, `function for_each_online_cpu`, `function blk_stat_alloc_callback`, `function blk_stat_add_callback`, `function for_each_possible_cpu`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: integration 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.