cregit-Linux how code gets into the kernel

Release 4.11 block/blk-stat.c

Directory: block
/*
 * Block stat tracking code
 *
 * Copyright (C) 2016 Jens Axboe
 */
#include <linux/kernel.h>
#include <linux/blk-mq.h>

#include "blk-stat.h"
#include "blk-mq.h"


static void blk_stat_flush_batch(struct blk_rq_stat *stat) { const s32 nr_batch = READ_ONCE(stat->nr_batch); const s32 nr_samples = READ_ONCE(stat->nr_samples); if (!nr_batch) return; if (!nr_samples) stat->mean = div64_s64(stat->batch, nr_batch); else { stat->mean = div64_s64((stat->mean * nr_samples) + stat->batch, nr_batch + nr_samples); } stat->nr_samples += nr_batch; stat->nr_batch = stat->batch = 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe9898.99%150.00%
Shaohua Li11.01%150.00%
Total99100.00%2100.00%


static void blk_stat_sum(struct blk_rq_stat *dst, struct blk_rq_stat *src) { blk_stat_flush_batch(src); if (!src->nr_samples) return; dst->min = min(dst->min, src->min); dst->max = max(dst->max, src->max); if (!dst->nr_samples) dst->mean = src->mean; else { dst->mean = div64_s64((src->mean * src->nr_samples) + (dst->mean * dst->nr_samples), dst->nr_samples + src->nr_samples); } dst->nr_samples += src->nr_samples; }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe11595.83%150.00%
Omar Sandoval54.17%150.00%
Total120100.00%2100.00%


static void blk_mq_stat_get(struct request_queue *q, struct blk_rq_stat *dst) { struct blk_mq_hw_ctx *hctx; struct blk_mq_ctx *ctx; uint64_t latest = 0; int i, j, nr; blk_stat_init(&dst[BLK_STAT_READ]); blk_stat_init(&dst[BLK_STAT_WRITE]); nr = 0; do { uint64_t newest = 0; queue_for_each_hw_ctx(q, hctx, i) { hctx_for_each_ctx(hctx, ctx, j) { blk_stat_flush_batch(&ctx->stat[BLK_STAT_READ]); blk_stat_flush_batch(&ctx->stat[BLK_STAT_WRITE]); if (!ctx->stat[BLK_STAT_READ].nr_samples && !ctx->stat[BLK_STAT_WRITE].nr_samples) continue; if (ctx->stat[BLK_STAT_READ].time > newest) newest = ctx->stat[BLK_STAT_READ].time; if (ctx->stat[BLK_STAT_WRITE].time > newest) newest = ctx->stat[BLK_STAT_WRITE].time; } } /* * No samples */ if (!newest) break; if (newest > latest) latest = newest; queue_for_each_hw_ctx(q, hctx, i) { hctx_for_each_ctx(hctx, ctx, j) { if (ctx->stat[BLK_STAT_READ].time == newest) { blk_stat_sum(&dst[BLK_STAT_READ], &ctx->stat[BLK_STAT_READ]); nr++; } if (ctx->stat[BLK_STAT_WRITE].time == newest) { blk_stat_sum(&dst[BLK_STAT_WRITE], &ctx->stat[BLK_STAT_WRITE]); nr++; } } } /* * If we race on finding an entry, just loop back again. * Should be very rare. */ } while (!nr); dst[BLK_STAT_READ].time = dst[BLK_STAT_WRITE].time = latest; }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe311100.00%2100.00%
Total311100.00%2100.00%


void blk_queue_stat_get(struct request_queue *q, struct blk_rq_stat *dst) { if (q->mq_ops) blk_mq_stat_get(q, dst); else { blk_stat_flush_batch(&q->rq_stats[BLK_STAT_READ]); blk_stat_flush_batch(&q->rq_stats[BLK_STAT_WRITE]); memcpy(&dst[BLK_STAT_READ], &q->rq_stats[BLK_STAT_READ], sizeof(struct blk_rq_stat)); memcpy(&dst[BLK_STAT_WRITE], &q->rq_stats[BLK_STAT_WRITE], sizeof(struct blk_rq_stat)); } }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe99100.00%2100.00%
Total99100.00%2100.00%


void blk_hctx_stat_get(struct blk_mq_hw_ctx *hctx, struct blk_rq_stat *dst) { struct blk_mq_ctx *ctx; unsigned int i, nr; nr = 0; do { uint64_t newest = 0; hctx_for_each_ctx(hctx, ctx, i) { blk_stat_flush_batch(&ctx->stat[BLK_STAT_READ]); blk_stat_flush_batch(&ctx->stat[BLK_STAT_WRITE]); if (!ctx->stat[BLK_STAT_READ].nr_samples && !ctx->stat[BLK_STAT_WRITE].nr_samples) continue; if (ctx->stat[BLK_STAT_READ].time > newest) newest = ctx->stat[BLK_STAT_READ].time; if (ctx->stat[BLK_STAT_WRITE].time > newest) newest = ctx->stat[BLK_STAT_WRITE].time; } if (!newest) break; hctx_for_each_ctx(hctx, ctx, i) { if (ctx->stat[BLK_STAT_READ].time == newest) { blk_stat_sum(&dst[BLK_STAT_READ], &ctx->stat[BLK_STAT_READ]); nr++; } if (ctx->stat[BLK_STAT_WRITE].time == newest) { blk_stat_sum(&dst[BLK_STAT_WRITE], &ctx->stat[BLK_STAT_WRITE]); nr++; } } /* * If we race on finding an entry, just loop back again. * Should be very rare, as the window is only updated * occasionally */ } while (!nr); }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe234100.00%2100.00%
Total234100.00%2100.00%


static void __blk_stat_init(struct blk_rq_stat *stat, s64 time_now) { stat->min = -1ULL; stat->max = stat->nr_samples = stat->mean = 0; stat->batch = stat->nr_batch = 0; stat->time = time_now & BLK_STAT_NSEC_MASK; }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe53100.00%1100.00%
Total53100.00%1100.00%


void blk_stat_init(struct blk_rq_stat *stat) { __blk_stat_init(stat, ktime_to_ns(ktime_get())); }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe21100.00%1100.00%
Total21100.00%1100.00%


static bool __blk_stat_is_current(struct blk_rq_stat *stat, s64 now) { return (now & BLK_STAT_NSEC_MASK) == (stat->time & BLK_STAT_NSEC_MASK); }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe29100.00%1100.00%
Total29100.00%1100.00%


bool blk_stat_is_current(struct blk_rq_stat *stat) { return __blk_stat_is_current(stat, ktime_to_ns(ktime_get())); }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe22100.00%1100.00%
Total22100.00%1100.00%


void blk_stat_add(struct blk_rq_stat *stat, struct request *rq) { s64 now, value; now = __blk_stat_time(ktime_to_ns(ktime_get())); if (now < blk_stat_time(&rq->issue_stat)) return; if (!__blk_stat_is_current(stat, now)) __blk_stat_init(stat, now); value = now - blk_stat_time(&rq->issue_stat); if (value > stat->max) stat->max = value; if (value < stat->min) stat->min = value; if (stat->batch + value < stat->batch || stat->nr_batch + 1 == BLK_RQ_STAT_BATCH) blk_stat_flush_batch(stat); stat->batch += value; stat->nr_batch++; }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe137100.00%1100.00%
Total137100.00%1100.00%


void blk_stat_clear(struct request_queue *q) { if (q->mq_ops) { struct blk_mq_hw_ctx *hctx; struct blk_mq_ctx *ctx; int i, j; queue_for_each_hw_ctx(q, hctx, i) { hctx_for_each_ctx(hctx, ctx, j) { blk_stat_init(&ctx->stat[BLK_STAT_READ]); blk_stat_init(&ctx->stat[BLK_STAT_WRITE]); } } } else { blk_stat_init(&q->rq_stats[BLK_STAT_READ]); blk_stat_init(&q->rq_stats[BLK_STAT_WRITE]); } }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe100100.00%1100.00%
Total100100.00%1100.00%


void blk_stat_set_issue_time(struct blk_issue_stat *stat) { stat->time = (stat->time & BLK_STAT_MASK) | (ktime_to_ns(ktime_get()) & BLK_STAT_TIME_MASK); }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe32100.00%1100.00%
Total32100.00%1100.00%

/* * Enable stat tracking, return whether it was enabled */
bool blk_stat_enable(struct request_queue *q) { if (!test_bit(QUEUE_FLAG_STATS, &q->queue_flags)) { set_bit(QUEUE_FLAG_STATS, &q->queue_flags); return false; } return true; }

Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe41100.00%1100.00%
Total41100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Jens Axboe130699.54%250.00%
Omar Sandoval50.38%125.00%
Shaohua Li10.08%125.00%
Total1312100.00%4100.00%
Directory: block
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.