Stats builder for ioclass statistics.

Signed-off-by: Michal Mielewczyk <michal.mielewczyk@intel.com>
This commit is contained in:
Michal Mielewczyk 2019-08-26 07:23:05 -04:00
parent 2450d3da4b
commit f9da89263b
4 changed files with 259 additions and 33 deletions

View File

@ -62,15 +62,6 @@ struct ocf_stats_block {
* Statistics appropriate for given IO class * Statistics appropriate for given IO class
*/ */
struct ocf_stats_io_class { struct ocf_stats_io_class {
/** Read requests statistics */
struct ocf_stats_req read_reqs;
/** Writes requests statistics */
struct ocf_stats_req write_reqs;
/** Block requests statistics */
struct ocf_stats_block blocks;
/** Number of cache lines available for given partition */ /** Number of cache lines available for given partition */
uint64_t free_clines; uint64_t free_clines;
@ -79,6 +70,21 @@ struct ocf_stats_io_class {
/** Number of dirty cache lines assigned to specific partition */ /** Number of dirty cache lines assigned to specific partition */
uint64_t dirty_clines; uint64_t dirty_clines;
/** Read requests statistics */
struct ocf_stats_req read_reqs;
/** Writes requests statistics */
struct ocf_stats_req write_reqs;
/** Block requests submitted by user to this core */
struct ocf_stats_block blocks;
/** Block requests for cache volume statistics */
struct ocf_stats_block cache_blocks;
/** Block requests for core volume statistics */
struct ocf_stats_block core_blocks;
}; };
#define IO_PACKET_NO 12 #define IO_PACKET_NO 12

View File

@ -172,7 +172,7 @@ int ocf_stats_collect_cache(ocf_cache_t cache,
/** /**
* @param Collect statistics for given core * @param Collect statistics for given core
* *
* @param cache Core for each statistics will be collected * @param core Core for which statistics will be collected
* @param usage Usage statistics * @param usage Usage statistics
* @param req Request statistics * @param req Request statistics
* @param blocks Blocks statistics * @param blocks Blocks statistics
@ -187,4 +187,36 @@ int ocf_stats_collect_core(ocf_core_t core,
struct ocf_stats_blocks *blocks, struct ocf_stats_blocks *blocks,
struct ocf_stats_errors *errors); struct ocf_stats_errors *errors);
/**
* @param Collect statistics for given ioclass
*
* @param core Core handle for which statistics will be collected
* @param part_id Ioclass id for which statistics will be collected
* @param usage Usage statistics
* @param req Request statistics
* @param blocks Blocks statistics
*
* @retval 0 Success
* @retval Non-zero Error
*/
int ocf_stats_collect_part_core(ocf_core_t core, ocf_part_id_t part_id,
struct ocf_stats_usage *usage, struct ocf_stats_requests *req,
struct ocf_stats_blocks *blocks);
/**
* @param Collect statistics for given ioclass
*
* @param cache Cache instance for which statistics will be collected
* @param part_id Ioclass id for which statistics will be collected
* @param usage Usage statistics
* @param req Request statistics
* @param blocks Blocks statistics
*
* @retval 0 Success
* @retval Non-zero Error
*/
int ocf_stats_collect_part_cache(ocf_cache_t cache, ocf_part_id_t part_id,
struct ocf_stats_usage *usage, struct ocf_stats_requests *req,
struct ocf_stats_blocks *blocks);
#endif /* __OCF_STATS_BUILDER_H__ */ #endif /* __OCF_STATS_BUILDER_H__ */

View File

@ -198,6 +198,8 @@ int ocf_core_io_class_get_stats(ocf_core_t core, ocf_part_id_t part_id,
copy_req_stats(&stats->write_reqs, &part_stat->write_reqs); copy_req_stats(&stats->write_reqs, &part_stat->write_reqs);
copy_block_stats(&stats->blocks, &part_stat->blocks); copy_block_stats(&stats->blocks, &part_stat->blocks);
copy_block_stats(&stats->cache_blocks, &part_stat->cache_blocks);
copy_block_stats(&stats->core_blocks, &part_stat->core_blocks);
return 0; return 0;
} }

View File

@ -94,6 +94,39 @@ static void _fill_req(struct ocf_stats_requests *req, struct ocf_stats_core *s)
_set(&req->total, total, total); _set(&req->total, total, total);
} }
static void _fill_req_part(struct ocf_stats_requests *req,
struct ocf_stats_io_class *s)
{
uint64_t serviced = s->read_reqs.total + s->write_reqs.total;
uint64_t total = serviced + s->read_reqs.pass_through +
s->write_reqs.pass_through;
uint64_t hit;
/* Reads Section */
hit = s->read_reqs.total - (s->read_reqs.full_miss +
s->read_reqs.partial_miss);
_set(&req->rd_hits, hit, total);
_set(&req->rd_partial_misses, s->read_reqs.partial_miss, total);
_set(&req->rd_full_misses, s->read_reqs.full_miss, total);
_set(&req->rd_total, s->read_reqs.total, total);
/* Write Section */
hit = s->write_reqs.total - (s->write_reqs.full_miss +
s->write_reqs.partial_miss);
_set(&req->wr_hits, hit, total);
_set(&req->wr_partial_misses, s->write_reqs.partial_miss, total);
_set(&req->wr_full_misses, s->write_reqs.full_miss, total);
_set(&req->wr_total, s->write_reqs.total, total);
/* Pass-Through section */
_set(&req->rd_pt, s->read_reqs.pass_through, total);
_set(&req->wr_pt, s->write_reqs.pass_through, total);
/* Summary */
_set(&req->serviced, serviced, total);
_set(&req->total, total, total);
}
static void _fill_blocks(struct ocf_stats_blocks *blocks, static void _fill_blocks(struct ocf_stats_blocks *blocks,
struct ocf_stats_core *s) struct ocf_stats_core *s)
{ {
@ -124,6 +157,36 @@ static void _fill_blocks(struct ocf_stats_blocks *blocks,
_set(&blocks->volume_total, total, total); _set(&blocks->volume_total, total, total);
} }
static void _fill_blocks_part(struct ocf_stats_blocks *blocks,
struct ocf_stats_io_class *s)
{
uint64_t rd, wr, total;
/* Core volume */
rd = _bytes4k(s->core_blocks.read);
wr = _bytes4k(s->core_blocks.write);
total = rd + wr;
_set(&blocks->core_volume_rd, rd, total);
_set(&blocks->core_volume_wr, wr, total);
_set(&blocks->core_volume_total, total, total);
/* Cache volume */
rd = _bytes4k(s->cache_blocks.read);
wr = _bytes4k(s->cache_blocks.write);
total = rd + wr;
_set(&blocks->cache_volume_rd, rd, total);
_set(&blocks->cache_volume_wr, wr, total);
_set(&blocks->cache_volume_total, total, total);
/* Core (cache volume) */
rd = _bytes4k(s->blocks.read);
wr = _bytes4k(s->blocks.write);
total = rd + wr;
_set(&blocks->volume_rd, rd, total);
_set(&blocks->volume_wr, wr, total);
_set(&blocks->volume_total, total, total);
}
static void _fill_errors(struct ocf_stats_errors *errors, static void _fill_errors(struct ocf_stats_errors *errors,
struct ocf_stats_core *s) struct ocf_stats_core *s)
{ {
@ -149,6 +212,152 @@ static void _fill_errors(struct ocf_stats_errors *errors,
_set(&errors->total, total, total); _set(&errors->total, total, total);
} }
static void _accumulate_block(struct ocf_stats_block *to,
const struct ocf_stats_block *from)
{
to->read += from->read;
to->write += from->write;
}
static void _accumulate_reqs(struct ocf_stats_req *to,
const struct ocf_stats_req *from)
{
to->full_miss += from->full_miss;
to->partial_miss += from->partial_miss;
to->total += from->total;
to->pass_through += from->pass_through;
}
static void _accumulate_errors(struct ocf_stats_error *to,
const struct ocf_stats_error *from)
{
to->read += from->read;
to->write += from->write;
}
struct io_class_stats_context {
struct ocf_stats_io_class *stats;
ocf_part_id_t part_id;
};
static int _accumulate_io_class_stats(ocf_core_t core, void *cntx)
{
int result;
struct ocf_stats_io_class stats;
struct ocf_stats_io_class *total =
((struct io_class_stats_context*)cntx)->stats;
ocf_part_id_t part_id = ((struct io_class_stats_context*)cntx)->part_id;
result = ocf_core_io_class_get_stats(core, part_id, &stats);
if (result)
return result;
total->occupancy_clines += stats.occupancy_clines;
total->dirty_clines += stats.dirty_clines;
total->free_clines = stats.free_clines;
_accumulate_block(&total->cache_blocks, &stats.cache_blocks);
_accumulate_block(&total->core_blocks, &stats.core_blocks);
_accumulate_block(&total->blocks, &stats.blocks);
_accumulate_reqs(&total->read_reqs, &stats.read_reqs);
_accumulate_reqs(&total->write_reqs, &stats.write_reqs);
return 0;
}
static void _ocf_stats_part_fill(ocf_cache_t cache, ocf_part_id_t part_id,
struct ocf_stats_io_class *stats , struct ocf_stats_usage *usage,
struct ocf_stats_requests *req, struct ocf_stats_blocks *blocks)
{
uint64_t cache_size, cache_line_size;
cache_line_size = ocf_cache_get_line_size(cache);
cache_size = cache->conf_meta->cachelines;
if (usage) {
_set(&usage->occupancy,
_lines4k(stats->occupancy_clines, cache_line_size),
_lines4k(cache_size, cache_line_size));
if (part_id == PARTITION_DEFAULT) {
_set(&usage->free,
_lines4k(stats->free_clines, cache_line_size),
_lines4k(cache_size, cache_line_size));
} else {
_set(&usage->free,
_lines4k(0, cache_line_size),
_lines4k(0, cache_line_size));
}
_set(&usage->clean,
_lines4k(stats->occupancy_clines - stats->dirty_clines,
cache_line_size),
_lines4k(stats->occupancy_clines, cache_line_size));
_set(&usage->dirty,
_lines4k(stats->dirty_clines, cache_line_size),
_lines4k(stats->occupancy_clines, cache_line_size));
}
if (req)
_fill_req_part(req, stats);
if (blocks)
_fill_blocks_part(blocks, stats);
}
int ocf_stats_collect_part_core(ocf_core_t core, ocf_part_id_t part_id,
struct ocf_stats_usage *usage, struct ocf_stats_requests *req,
struct ocf_stats_blocks *blocks)
{
struct ocf_stats_io_class s;
ocf_cache_t cache;
int result = 0;
OCF_CHECK_NULL(core);
cache = ocf_core_get_cache(core);
_ocf_stats_zero(usage);
_ocf_stats_zero(req);
_ocf_stats_zero(blocks);
result = ocf_core_io_class_get_stats(core, part_id, &s);
if (result)
return result;
_ocf_stats_part_fill(cache, part_id, &s, usage, req, blocks);
return result;
}
int ocf_stats_collect_part_cache(ocf_cache_t cache, ocf_part_id_t part_id,
struct ocf_stats_usage *usage, struct ocf_stats_requests *req,
struct ocf_stats_blocks *blocks)
{
struct io_class_stats_context ctx;
struct ocf_stats_io_class s;
int result = 0;
OCF_CHECK_NULL(cache);
_ocf_stats_zero(usage);
_ocf_stats_zero(req);
_ocf_stats_zero(blocks);
ctx.part_id = part_id;
ctx.stats = &s;
result = ocf_core_visit(cache, _accumulate_io_class_stats, &ctx, true);
if (result)
return result;
_ocf_stats_part_fill(cache, part_id, &s, usage, req, blocks);
return result;
}
int ocf_stats_collect_core(ocf_core_t core, int ocf_stats_collect_core(ocf_core_t core,
struct ocf_stats_usage *usage, struct ocf_stats_usage *usage,
struct ocf_stats_requests *req, struct ocf_stats_requests *req,
@ -206,29 +415,6 @@ int ocf_stats_collect_core(ocf_core_t core,
return 0; return 0;
} }
static void _accumulate_block(struct ocf_stats_block *to,
const struct ocf_stats_block *from)
{
to->read += from->read;
to->write += from->write;
}
static void _accumulate_reqs(struct ocf_stats_req *to,
const struct ocf_stats_req *from)
{
to->full_miss += from->full_miss;
to->partial_miss += from->partial_miss;
to->total += from->total;
to->pass_through += from->pass_through;
}
static void _accumulate_errors(struct ocf_stats_error *to,
const struct ocf_stats_error *from)
{
to->read += from->read;
to->write += from->write;
}
static int _accumulate_stats(ocf_core_t core, void *cntx) static int _accumulate_stats(ocf_core_t core, void *cntx)
{ {
struct ocf_stats_core stats, *total = cntx; struct ocf_stats_core stats, *total = cntx;