diff --git a/ocaml/xcp-rrdd/bin/read-blktap-stats/read_blktap_stats.ml b/ocaml/xcp-rrdd/bin/read-blktap-stats/read_blktap_stats.ml index c10f276064b..ad4258f0087 100644 --- a/ocaml/xcp-rrdd/bin/read-blktap-stats/read_blktap_stats.ml +++ b/ocaml/xcp-rrdd/bin/read-blktap-stats/read_blktap_stats.ml @@ -36,6 +36,13 @@ let () = Printf.printf "write_sectors = %Ld\n" (get_stats_write_sectors s) ; Printf.printf "write_total_ticks = %Ld\n" (get_stats_write_total_ticks s) ; Printf.printf "io_errors = %Ld\n" (get_stats_io_errors s) ; - Printf.printf "flags = %Ld\n" (get_stats_flags s) + Printf.printf "flags = %Ld\n" (get_stats_flags s) ; + Printf.printf "discard_reqs_submitted = %Ld\n" + (get_stats_discard_reqs_submitted s) ; + Printf.printf "discard_reqs_completed = %Ld\n" + (get_stats_discard_reqs_completed s) ; + Printf.printf "discard_sectors = %Ld\n" (get_stats_discard_sectors s) ; + Printf.printf "discard_total_ticks = %Ld\n" + (get_stats_discard_total_ticks s) | _ -> usage () diff --git a/ocaml/xcp-rrdd/bin/rrdp-iostat/rrdp_iostat.ml b/ocaml/xcp-rrdd/bin/rrdp-iostat/rrdp_iostat.ml index 0f547015304..1a010e99e68 100644 --- a/ocaml/xcp-rrdd/bin/rrdp-iostat/rrdp_iostat.ml +++ b/ocaml/xcp-rrdd/bin/rrdp-iostat/rrdp_iostat.ml @@ -590,12 +590,16 @@ module Stats_value = struct type t = { rd_bytes: int64 ; wr_bytes: int64 + ; ds_bytes: int64 ; rd_avg_usecs: int64 ; wr_avg_usecs: int64 + ; ds_avg_usecs: int64 ; io_throughput_read_mb: float ; io_throughput_write_mb: float + ; io_throughput_discard_mb: float ; iops_read: int64 ; iops_write: int64 + ; iops_discard: int64 ; iowait: float ; inflight: int64 } @@ -604,12 +608,16 @@ module Stats_value = struct { rd_bytes= 0L ; wr_bytes= 0L + ; ds_bytes= 0L ; rd_avg_usecs= 0L ; wr_avg_usecs= 0L + ; ds_avg_usecs= 0L ; io_throughput_read_mb= 0. ; io_throughput_write_mb= 0. + ; io_throughput_discard_mb= 0. ; iops_read= 0L ; iops_write= 0L + ; iops_discard= 0L ; iowait= 0. ; inflight= 0L } @@ -632,6 +640,7 @@ module Stats_value = struct { rd_bytes= stats_diff_get 13 ; wr_bytes= stats_diff_get 14 + ; ds_bytes= 0L ; rd_avg_usecs= ( if stats_diff_get 0 > 0L then Int64.div (stats_diff_get 3) (stats_diff_get 0) @@ -644,10 +653,13 @@ module Stats_value = struct else 0L ) + ; ds_avg_usecs= 0L ; io_throughput_read_mb= to_float (stats_diff_get 13) /. 1048576. ; io_throughput_write_mb= to_float (stats_diff_get 14) /. 1048576. + ; io_throughput_discard_mb= 0. ; iops_read= stats_diff_get 0 ; iops_write= stats_diff_get 4 + ; iops_discard= 0L ; iowait= to_float (stats_diff_get 10) /. 1000. ; inflight= stats_get 8 } @@ -686,12 +698,16 @@ module Stats_value = struct { rd_bytes= Int64.mul (get_stats_read_sectors s3) 512L ; wr_bytes= Int64.mul (get_stats_write_sectors s3) 512L + ; ds_bytes= Int64.mul (get_stats_discard_sectors s3) 512L ; rd_avg_usecs= avg_reqs_completed_last_five_secs get_stats_read_reqs_completed get_stats_read_total_ticks ; wr_avg_usecs= avg_reqs_completed_last_five_secs get_stats_write_reqs_completed get_stats_write_total_ticks + ; ds_avg_usecs= + avg_reqs_completed_last_five_secs get_stats_discard_reqs_completed + get_stats_discard_total_ticks ; io_throughput_read_mb= to_float (get_stats_read_sectors s3 -- opt get_stats_read_sectors last_s3) @@ -702,12 +718,22 @@ module Stats_value = struct (get_stats_write_sectors s3 -- opt get_stats_write_sectors last_s3) *. 512. /. 1048576. + ; io_throughput_discard_mb= + to_float + (get_stats_discard_sectors s3 + -- opt get_stats_discard_sectors last_s3 + ) + *. 512. + /. 1048576. ; iops_read= get_stats_read_reqs_completed s3 -- opt get_stats_read_reqs_completed last_s3 ; iops_write= get_stats_write_reqs_completed s3 -- opt get_stats_write_reqs_completed last_s3 + ; iops_discard= + get_stats_discard_reqs_completed s3 + -- opt get_stats_discard_reqs_completed last_s3 ; iowait= to_float (get_stats_read_total_ticks s3 @@ -736,12 +762,17 @@ module Stats_value = struct ; rd_avg_usecs= acc.rd_avg_usecs ++ v.rd_avg_usecs ; wr_bytes= acc.wr_bytes ++ v.wr_bytes ; wr_avg_usecs= acc.wr_avg_usecs ++ v.wr_avg_usecs + ; ds_bytes= acc.ds_bytes ++ v.ds_bytes + ; ds_avg_usecs= acc.ds_avg_usecs ++ v.ds_avg_usecs ; io_throughput_read_mb= acc.io_throughput_read_mb +. v.io_throughput_read_mb ; io_throughput_write_mb= acc.io_throughput_write_mb +. v.io_throughput_write_mb + ; io_throughput_discard_mb= + acc.io_throughput_discard_mb +. v.io_throughput_discard_mb ; iops_read= acc.iops_read ++ v.iops_read ; iops_write= acc.iops_write ++ v.iops_write + ; iops_discard= acc.iops_discard ++ v.iops_discard ; iowait= acc.iowait +. v.iowait ; inflight= acc.inflight ++ v.inflight } @@ -763,6 +794,12 @@ module Stats_value = struct ~value:(Rrd.VT_Int64 value.wr_bytes) ~ty:Rrd.Derive ~units:"B/s" ~min:0.0 () ) + ; ( owner + , ds_make ~name:(key_format "discard") + ~description:("Discards from device " ^ name ^ ", in B/s") + ~value:(Rrd.VT_Int64 value.ds_bytes) ~ty:Rrd.Derive ~units:"B/s" + ~min:0.0 () + ) ; ( owner , ds_make ~name:(key_format "read_latency") @@ -778,6 +815,14 @@ module Stats_value = struct ~value:(Rrd.VT_Int64 value.wr_avg_usecs) ~ty:Rrd.Gauge ~units:"μs" ~min:0.0 () ) + ; ( owner + , ds_make + ~name:(key_format "discard_latency") + ~description: + ("Discard latency from device " ^ name ^ ", in microseconds") + ~value:(Rrd.VT_Int64 value.ds_avg_usecs) ~ty:Rrd.Gauge ~units:"μs" + ~min:0.0 () + ) ; ( owner , ds_make ~name:(key_format "io_throughput_read") @@ -792,6 +837,13 @@ module Stats_value = struct ~value:(Rrd.VT_Float value.io_throughput_write_mb) ~ty:Rrd.Absolute ~units:"MiB/s" ~min:0. () ) + ; ( owner + , ds_make + ~name:(key_format "io_throughput_discard") + ~description:("Data discard to the " ^ name ^ ", in MiB/s") + ~value:(Rrd.VT_Float value.io_throughput_discard_mb) ~ty:Rrd.Absolute + ~units:"MiB/s" ~min:0. () + ) ; ( owner , ds_make ~name:(key_format "io_throughput_total") @@ -814,10 +866,22 @@ module Stats_value = struct ~value:(Rrd.VT_Int64 value.iops_write) ~ty:Rrd.Absolute ~units:"requests/s" ~min:0. () ) + ; ( owner + , ds_make + ~name:(key_format "iops_discard") + ~description:"Discard requests per second" + ~value:(Rrd.VT_Int64 value.iops_discard) ~ty:Rrd.Absolute + ~units:"requests/s" ~min:0. () + ) ; ( owner , ds_make ~name:(key_format "iops_total") ~description:"I/O Requests per second" - ~value:(Rrd.VT_Int64 (Int64.add value.iops_read value.iops_write)) + ~value: + (Rrd.VT_Int64 + (Int64.add value.iops_read + (Int64.add value.iops_write value.iops_discard) + ) + ) ~ty:Rrd.Absolute ~units:"requests/s" ~min:0. () ) ; ( owner @@ -855,15 +919,19 @@ module Iostats_value = struct let s3_usecs = get_stats_read_total_ticks s3 ++ get_stats_write_total_ticks s3 + ++ get_stats_discard_total_ticks s3 -- (opt get_stats_read_total_ticks last_s3 ++ opt get_stats_write_total_ticks last_s3 + ++ opt get_stats_discard_total_ticks last_s3 ) in let s3_count = get_stats_read_reqs_completed s3 ++ get_stats_write_reqs_completed s3 + ++ get_stats_discard_reqs_completed s3 -- (opt get_stats_read_reqs_completed last_s3 ++ opt get_stats_write_reqs_completed last_s3 + ++ opt get_stats_discard_reqs_completed last_s3 ) in let s3_latency_average = @@ -874,8 +942,10 @@ module Iostats_value = struct to_float (get_stats_read_total_ticks s3 ++ get_stats_write_total_ticks s3 + ++ get_stats_discard_total_ticks s3 -- (opt get_stats_read_total_ticks last_s3 ++ opt get_stats_write_total_ticks last_s3 + ++ opt get_stats_discard_total_ticks last_s3 ) ) /. 1000_000.0 diff --git a/ocaml/xcp-rrdd/lib/blktap/lib/blktap3_stats.ml b/ocaml/xcp-rrdd/lib/blktap/lib/blktap3_stats.ml index 9844acde174..6155c921a3c 100644 --- a/ocaml/xcp-rrdd/lib/blktap/lib/blktap3_stats.ml +++ b/ocaml/xcp-rrdd/lib/blktap/lib/blktap3_stats.ml @@ -42,6 +42,28 @@ type stats = { } [@@little_endian]] +[%%cstruct +type stats_v2 = { + _v1_version: uint32_t + ; _v1_pad: uint32_t + ; _v1_oo_reqs: uint64_t + ; _v1_read_reqs_submitted: uint64_t + ; _v1_read_reqs_completed: uint64_t + ; _v1_read_sectors: uint64_t + ; _v1_read_total_ticks: uint64_t + ; _v1_write_reqs_submitted: uint64_t + ; _v1_write_reqs_completed: uint64_t + ; _v1_write_sectors: uint64_t + ; _v1_write_total_ticks: uint64_t + ; _v1_io_errors: uint64_t + ; _v1_flags: uint64_t + ; discard_reqs_submitted: uint64_t + ; discard_reqs_completed: uint64_t + ; discard_sectors: uint64_t + ; discard_total_ticks: uint64_t +} +[@@little_endian]] + let of_file f = let fd = Unix.(openfile f [O_RDONLY] 0o000) in try @@ -51,6 +73,39 @@ let of_file f = let copy : t -> t = fun t -> - let t' = Cstruct.create_unsafe sizeof_stats in - Cstruct.blit t 0 t' 0 sizeof_stats ; - t' + let size = + if get_stats_version t >= 2l then + sizeof_stats_v2 + else + sizeof_stats + in + let t' = Cstruct.create_unsafe size in + Cstruct.blit t 0 t' 0 size ; t' + +let get_stats_discard_reqs_submitted : t -> Cstruct.uint64 = + fun t -> + if get_stats_version t >= 2l then + get_stats_v2_discard_reqs_submitted t + else + 0L + +let get_stats_discard_reqs_completed : t -> Cstruct.uint64 = + fun t -> + if get_stats_version t >= 2l then + get_stats_v2_discard_reqs_completed t + else + 0L + +let get_stats_discard_sectors : t -> Cstruct.uint64 = + fun t -> + if get_stats_version t >= 2l then + get_stats_v2_discard_sectors t + else + 0L + +let get_stats_discard_total_ticks : t -> Cstruct.uint64 = + fun t -> + if get_stats_version t >= 2l then + get_stats_v2_discard_total_ticks t + else + 0L diff --git a/ocaml/xcp-rrdd/lib/blktap/lib/blktap3_stats.mli b/ocaml/xcp-rrdd/lib/blktap/lib/blktap3_stats.mli index c9731bc410e..64699d49949 100644 --- a/ocaml/xcp-rrdd/lib/blktap/lib/blktap3_stats.mli +++ b/ocaml/xcp-rrdd/lib/blktap/lib/blktap3_stats.mli @@ -44,6 +44,14 @@ val get_stats_io_errors : t -> Cstruct.uint64 val get_stats_flags : t -> Cstruct.uint64 +val get_stats_discard_reqs_submitted : t -> Cstruct.uint64 + +val get_stats_discard_reqs_completed : t -> Cstruct.uint64 + +val get_stats_discard_sectors : t -> Cstruct.uint64 + +val get_stats_discard_total_ticks : t -> Cstruct.uint64 + val of_file : string -> t val copy : t -> t