2 * Copyright(c) 2012-2018 Intel Corporation
3 * SPDX-License-Identifier: BSD-3-Clause-Clear
8 #include "metadata/metadata.h"
9 #include "engine/cache_engine.h"
10 #include "utils/utils_part.h"
11 #include "utils/utils_cache_line.h"
13 #ifdef OCF_DEBUG_STATS
14 static void ocf_stats_debug_init(struct ocf_counters_debug
*stats
)
18 for (i
= 0; i
< IO_PACKET_NO
; i
++) {
19 env_atomic64_set(&stats
->read_size
[i
], 0);
20 env_atomic64_set(&stats
->write_size
[i
], 0);
23 for (i
= 0; i
< IO_ALIGN_NO
; i
++) {
24 env_atomic64_set(&stats
->read_align
[i
], 0);
25 env_atomic64_set(&stats
->write_align
[i
], 0);
30 static void ocf_stats_req_init(struct ocf_counters_req
*stats
)
32 env_atomic64_set(&stats
->full_miss
, 0);
33 env_atomic64_set(&stats
->partial_miss
, 0);
34 env_atomic64_set(&stats
->total
, 0);
35 env_atomic64_set(&stats
->pass_through
, 0);
38 static void ocf_stats_block_init(struct ocf_counters_block
*stats
)
40 env_atomic64_set(&stats
->read_bytes
, 0);
41 env_atomic64_set(&stats
->write_bytes
, 0);
44 static void ocf_stats_part_init(struct ocf_counters_part
*stats
)
46 ocf_stats_req_init(&stats
->read_reqs
);
47 ocf_stats_req_init(&stats
->write_reqs
);
49 ocf_stats_block_init(&stats
->blocks
);
50 ocf_stats_block_init(&stats
->core_blocks
);
51 ocf_stats_block_init(&stats
->cache_blocks
);
54 static void ocf_stats_error_init(struct ocf_counters_error
*stats
)
56 env_atomic_set(&stats
->read
, 0);
57 env_atomic_set(&stats
->write
, 0);
60 static void _ocf_stats_block_update(struct ocf_counters_block
*counters
, int dir
,
65 env_atomic64_add(bytes
, &counters
->read_bytes
);
68 env_atomic64_add(bytes
, &counters
->write_bytes
);
75 void ocf_core_stats_vol_block_update(ocf_core_t core
, ocf_part_id_t part_id
,
76 int dir
, uint64_t bytes
)
78 struct ocf_counters_block
*counters
=
79 &core
->counters
->part_counters
[part_id
].blocks
;
81 _ocf_stats_block_update(counters
, dir
, bytes
);
84 void ocf_core_stats_cache_block_update(ocf_core_t core
, ocf_part_id_t part_id
,
85 int dir
, uint64_t bytes
)
87 struct ocf_counters_block
*counters
=
88 &core
->counters
->part_counters
[part_id
].cache_blocks
;
90 _ocf_stats_block_update(counters
, dir
, bytes
);
93 void ocf_core_stats_core_block_update(ocf_core_t core
, ocf_part_id_t part_id
,
94 int dir
, uint64_t bytes
)
96 struct ocf_counters_block
*counters
=
97 &core
->counters
->part_counters
[part_id
].core_blocks
;
99 _ocf_stats_block_update(counters
, dir
, bytes
);
102 void ocf_core_stats_request_update(ocf_core_t core
, ocf_part_id_t part_id
,
103 uint8_t dir
, uint64_t hit_no
, uint64_t core_line_count
)
105 struct ocf_counters_req
*counters
;
109 counters
= &core
->counters
->part_counters
[part_id
].read_reqs
;
112 counters
= &core
->counters
->part_counters
[part_id
].write_reqs
;
118 env_atomic64_inc(&counters
->total
);
121 env_atomic64_inc(&counters
->full_miss
);
122 else if (hit_no
< core_line_count
)
123 env_atomic64_inc(&counters
->partial_miss
);
126 void ocf_core_stats_request_pt_update(ocf_core_t core
, ocf_part_id_t part_id
,
127 uint8_t dir
, uint64_t hit_no
, uint64_t core_line_count
)
129 struct ocf_counters_req
*counters
;
133 counters
= &core
->counters
->part_counters
[part_id
].read_reqs
;
136 counters
= &core
->counters
->part_counters
[part_id
].write_reqs
;
142 env_atomic64_inc(&counters
->pass_through
);
145 static void _ocf_core_stats_error_update(struct ocf_counters_error
*counters
,
150 env_atomic_inc(&counters
->read
);
153 env_atomic_inc(&counters
->write
);
160 void ocf_core_stats_core_error_update(ocf_core_t core
, uint8_t dir
)
162 struct ocf_counters_error
*counters
= &core
->counters
->core_errors
;
164 _ocf_core_stats_error_update(counters
, dir
);
167 void ocf_core_stats_cache_error_update(ocf_core_t core
, uint8_t dir
)
169 struct ocf_counters_error
*counters
= &core
->counters
->cache_errors
;
171 _ocf_core_stats_error_update(counters
, dir
);
174 /********************************************************************
175 * Function that resets stats, debug and breakdown counters.
176 * If reset is set the following stats won't be reset:
179 * - debug_counters_read_reqs_issued_seq_hits
180 * - debug_counters_read_reqs_issued_not_seq_hits
181 * - debug_counters_read_reqs_issued_read_miss_schedule
182 * - debug_counters_write_reqs_thread
183 * - debug_counters_write_reqs_issued_only_hdd
184 * - debug_counters_write_reqs_issued_both_devs
185 *********************************************************************/
186 void ocf_core_stats_initialize(ocf_core_t core
)
188 struct ocf_counters_core
*exp_obj_stats
;
191 OCF_CHECK_NULL(core
);
193 exp_obj_stats
= core
->counters
;
195 ocf_stats_error_init(&exp_obj_stats
->cache_errors
);
196 ocf_stats_error_init(&exp_obj_stats
->core_errors
);
198 for (i
= 0; i
!= OCF_IO_CLASS_MAX
; i
++)
199 ocf_stats_part_init(&exp_obj_stats
->part_counters
[i
]);
201 #ifdef OCF_DEBUG_STATS
202 ocf_stats_debug_init(&exp_obj_stats
->debug_stats
);
206 void ocf_core_stats_initialize_all(ocf_cache_t cache
)
210 for (id
= 0; id
< OCF_CORE_MAX
; id
++) {
211 if (!env_bit_test(id
, cache
->conf_meta
->valid_core_bitmap
))
214 ocf_core_stats_initialize(&cache
->core
[id
]);
218 static void copy_req_stats(struct ocf_stats_req
*dest
,
219 const struct ocf_counters_req
*from
)
221 dest
->partial_miss
= env_atomic64_read(&from
->partial_miss
);
222 dest
->full_miss
= env_atomic64_read(&from
->full_miss
);
223 dest
->total
= env_atomic64_read(&from
->total
);
224 dest
->pass_through
= env_atomic64_read(&from
->pass_through
);
227 static void accum_req_stats(struct ocf_stats_req
*dest
,
228 const struct ocf_counters_req
*from
)
230 dest
->partial_miss
+= env_atomic64_read(&from
->partial_miss
);
231 dest
->full_miss
+= env_atomic64_read(&from
->full_miss
);
232 dest
->total
+= env_atomic64_read(&from
->total
);
233 dest
->pass_through
+= env_atomic64_read(&from
->pass_through
);
236 static void copy_block_stats(struct ocf_stats_block
*dest
,
237 const struct ocf_counters_block
*from
)
239 dest
->read
= env_atomic64_read(&from
->read_bytes
);
240 dest
->write
= env_atomic64_read(&from
->write_bytes
);
243 static void accum_block_stats(struct ocf_stats_block
*dest
,
244 const struct ocf_counters_block
*from
)
246 dest
->read
+= env_atomic64_read(&from
->read_bytes
);
247 dest
->write
+= env_atomic64_read(&from
->write_bytes
);
250 static void copy_error_stats(struct ocf_stats_error
*dest
,
251 const struct ocf_counters_error
*from
)
253 dest
->read
= env_atomic_read(&from
->read
);
254 dest
->write
= env_atomic_read(&from
->write
);
257 #ifdef OCF_DEBUG_STATS
258 static void copy_debug_stats(struct ocf_stats_core_debug
*dest
,
259 const struct ocf_counters_debug
*from
)
263 for (i
= 0; i
< IO_PACKET_NO
; i
++) {
264 dest
->read_size
[i
] = env_atomic64_read(&from
->read_size
[i
]);
265 dest
->write_size
[i
] = env_atomic64_read(&from
->write_size
[i
]);
268 for (i
= 0; i
< IO_ALIGN_NO
; i
++) {
269 dest
->read_align
[i
] = env_atomic64_read(&from
->read_align
[i
]);
270 dest
->write_align
[i
] = env_atomic64_read(&from
->write_align
[i
]);
275 int ocf_core_io_class_get_stats(ocf_core_t core
, ocf_part_id_t part_id
,
276 struct ocf_stats_io_class
*stats
)
279 uint32_t cache_occupancy_total
= 0;
280 struct ocf_counters_part
*part_stat
;
282 ocf_core_id_t i_core_id
;
284 OCF_CHECK_NULL(core
);
285 OCF_CHECK_NULL(stats
);
287 if (part_id
> OCF_IO_CLASS_ID_MAX
)
288 return -OCF_ERR_INVAL
;
290 cache
= ocf_core_get_cache(core
);
292 if (!ocf_part_is_valid(&cache
->user_parts
[part_id
]))
293 return -OCF_ERR_IO_CLASS_NOT_EXIST
;
295 for_each_core(cache
, i_core
, i_core_id
) {
296 cache_occupancy_total
+= env_atomic_read(
297 &i_core
->runtime_meta
->cached_clines
);
300 part_stat
= &core
->counters
->part_counters
[part_id
];
302 stats
->occupancy_clines
= env_atomic_read(&core
->runtime_meta
->
303 part_counters
[part_id
].cached_clines
);
304 stats
->dirty_clines
= env_atomic_read(&core
->runtime_meta
->
305 part_counters
[part_id
].dirty_clines
);
307 stats
->free_clines
= cache
->conf_meta
->cachelines
-
308 cache_occupancy_total
;
310 copy_req_stats(&stats
->read_reqs
, &part_stat
->read_reqs
);
311 copy_req_stats(&stats
->write_reqs
, &part_stat
->write_reqs
);
313 copy_block_stats(&stats
->blocks
, &part_stat
->blocks
);
314 copy_block_stats(&stats
->cache_blocks
, &part_stat
->cache_blocks
);
315 copy_block_stats(&stats
->core_blocks
, &part_stat
->core_blocks
);
320 int ocf_core_get_stats(ocf_core_t core
, struct ocf_stats_core
*stats
)
323 struct ocf_counters_core
*core_stats
= NULL
;
324 struct ocf_counters_part
*curr
= NULL
;
326 OCF_CHECK_NULL(core
);
329 return -OCF_ERR_INVAL
;
331 core_stats
= core
->counters
;
333 ENV_BUG_ON(env_memset(stats
, sizeof(*stats
), 0));
335 copy_error_stats(&stats
->core_errors
,
336 &core_stats
->core_errors
);
337 copy_error_stats(&stats
->cache_errors
,
338 &core_stats
->cache_errors
);
340 #ifdef OCF_DEBUG_STATS
341 copy_debug_stats(&stats
->debug_stat
,
342 &core_stats
->debug_stats
);
345 for (i
= 0; i
!= OCF_IO_CLASS_MAX
; i
++) {
346 curr
= &core_stats
->part_counters
[i
];
348 accum_req_stats(&stats
->read_reqs
,
350 accum_req_stats(&stats
->write_reqs
,
353 accum_block_stats(&stats
->core
, &curr
->blocks
);
354 accum_block_stats(&stats
->core_volume
, &curr
->core_blocks
);
355 accum_block_stats(&stats
->cache_volume
, &curr
->cache_blocks
);
357 stats
->cache_occupancy
+= env_atomic_read(&core
->runtime_meta
->
358 part_counters
[i
].cached_clines
);
359 stats
->dirty
+= env_atomic_read(&core
->runtime_meta
->
360 part_counters
[i
].dirty_clines
);
366 #ifdef OCF_DEBUG_STATS
368 #define IO_ALIGNMENT_SIZE (IO_ALIGN_NO)
369 #define IO_PACKET_SIZE ((IO_PACKET_NO) - 1)
371 static uint32_t io_alignment
[IO_ALIGNMENT_SIZE
] = {
372 512, 1 * KiB
, 2 * KiB
, 4 * KiB
375 static int to_align_idx(uint64_t off
)
379 for (i
= IO_ALIGNMENT_SIZE
- 1; i
>= 0; i
--) {
380 if (off
% io_alignment
[i
] == 0)
384 return IO_ALIGNMENT_SIZE
;
387 static uint32_t io_packet_size
[IO_PACKET_SIZE
] = {
388 512, 1 * KiB
, 2 * KiB
, 4 * KiB
, 8 * KiB
,
389 16 * KiB
, 32 * KiB
, 64 * KiB
, 128 * KiB
,
394 static int to_packet_idx(uint32_t len
)
398 for (i
= 0; i
< IO_PACKET_SIZE
; i
++) {
399 if (len
== io_packet_size
[i
])
403 return IO_PACKET_SIZE
;
406 void ocf_core_update_stats(ocf_core_t core
, struct ocf_io
*io
)
408 struct ocf_counters_debug
*stats
;
411 OCF_CHECK_NULL(core
);
414 core_id
= ocf_core_get_id(core
);
415 cache
= ocf_core_get_cache(core
);
417 stats
= &core
->counters
->debug_stats
;
419 idx
= to_packet_idx(io
->bytes
);
420 if (io
->dir
== OCF_WRITE
)
421 env_atomic64_inc(&stats
->write_size
[idx
]);
423 env_atomic64_inc(&stats
->read_size
[idx
]);
425 idx
= to_align_idx(io
->addr
);
426 if (io
->dir
== OCF_WRITE
)
427 env_atomic64_inc(&stats
->write_align
[idx
]);
429 env_atomic64_inc(&stats
->read_align
[idx
]);
434 void ocf_core_update_stats(ocf_core_t core
, struct ocf_io
*io
) {}