Stats builder for ioclass statistics.
Signed-off-by: Michal Mielewczyk <michal.mielewczyk@intel.com>
This commit is contained in:
parent
2450d3da4b
commit
f9da89263b
@ -62,15 +62,6 @@ struct ocf_stats_block {
|
||||
* Statistics appropriate for given 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 */
|
||||
uint64_t free_clines;
|
||||
|
||||
@ -79,6 +70,21 @@ struct ocf_stats_io_class {
|
||||
|
||||
/** Number of dirty cache lines assigned to specific partition */
|
||||
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
|
||||
|
@ -172,7 +172,7 @@ int ocf_stats_collect_cache(ocf_cache_t cache,
|
||||
/**
|
||||
* @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 req Request 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_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__ */
|
||||
|
@ -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_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;
|
||||
}
|
||||
|
@ -94,6 +94,39 @@ static void _fill_req(struct ocf_stats_requests *req, struct ocf_stats_core *s)
|
||||
_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,
|
||||
struct ocf_stats_core *s)
|
||||
{
|
||||
@ -124,6 +157,36 @@ static void _fill_blocks(struct ocf_stats_blocks *blocks,
|
||||
_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,
|
||||
struct ocf_stats_core *s)
|
||||
{
|
||||
@ -149,6 +212,152 @@ static void _fill_errors(struct ocf_stats_errors *errors,
|
||||
_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,
|
||||
struct ocf_stats_usage *usage,
|
||||
struct ocf_stats_requests *req,
|
||||
@ -206,29 +415,6 @@ int ocf_stats_collect_core(ocf_core_t core,
|
||||
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)
|
||||
{
|
||||
struct ocf_stats_core stats, *total = cntx;
|
||||
|
Loading…
Reference in New Issue
Block a user