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
|
* 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
|
||||||
|
@ -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__ */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user