[libvirt] [PATCHv4] add-vcpu-usage

Hu Tao hutao at cn.fujitsu.com
Thu May 31 10:54:47 UTC 2012


Hi Rich,

The libvirt counterpart have been already in, do you have time to look
at the ocaml-libvirt and virt-top patches?

On Wed, May 09, 2012 at 04:48:29PM +0800, Hu Tao wrote:
> show `vcpu usages' by `virt-top -1'
> 
> Before this patch, `virt-top -1' shows total cpu usages
> which euqal to `vcpu usages' + `hypervisor usages'. This
> patch adds another column for domains showing `vcpu
> usages'. An example is:
> 
> PHYCPU %CPU example_domain
>    0   10.4 10.4  0.8
>    1    1.6  1.6  1.4
>    2    2.6  2.6  2.6
>    3    0.0  0.0  0.1
> ---
>  virt-top/virt_top.ml |   72 ++++++++++++++++++++++++++++++++++++-------------
>  1 files changed, 53 insertions(+), 19 deletions(-)
> 
> diff --git a/virt-top/virt_top.ml b/virt-top/virt_top.ml
> index e2fe554..0dcb170 100644
> --- a/virt-top/virt_top.ml
> +++ b/virt-top/virt_top.ml
> @@ -448,6 +448,7 @@ let collect, clear_pcpu_display_data =
>  
>    (* Save pcpu_usages structures across redraws too (only for pCPU display). *)
>    let last_pcpu_usages = Hashtbl.create 13 in
> +  let last_vcpu_usages = Hashtbl.create 13 in
>  
>    let clear_pcpu_display_data () =
>      (* Clear out pcpu_usages used by PCPUDisplay display_mode
> @@ -652,12 +653,17 @@ let collect, clear_pcpu_display_data =
>  	      (try
>  		 let domid = rd.rd_domid in
>  		 let maplen = C.cpumaplen nr_pcpus in
> -		 let cpu_stats = D.get_cpu_stats rd.rd_dom nr_pcpus in
> -		 let rec find_usages_from_stats = function
> +		 let cpu_stats = D.get_cpu_stats rd.rd_dom false in
> +		 let rec find_cpu_usages = function
>  		   | ("cpu_time", D.TypedFieldUInt64 usages) :: _ -> usages
> -		   | _ :: params -> find_usages_from_stats params
> +		   | _ :: params -> find_cpu_usages params
>  		   | [] -> 0L in
> -		 let pcpu_usages = Array.map find_usages_from_stats cpu_stats in
> +		 let rec find_vcpu_usages = function
> +		   | ("vcpu_time", D.TypedFieldUInt64 usages) :: _ -> usages
> +		   | _ :: params -> find_vcpu_usages params
> +		   | [] -> 0L in
> +
> +		 let pcpu_usages = Array.map find_cpu_usages cpu_stats in
>  		 let maxinfo = rd.rd_info.D.nr_virt_cpu in
>  		 let nr_vcpus, vcpu_infos, cpumaps =
>  		   D.get_vcpus rd.rd_dom maxinfo maplen in
> @@ -669,11 +675,19 @@ let collect, clear_pcpu_display_data =
>  		 (* Update last_pcpu_usages. *)
>  		 Hashtbl.replace last_pcpu_usages domid pcpu_usages;
>  
> -		 (match prev_pcpu_usages with
> -		  | Some prev_pcpu_usages
> +                 (* vcpu usages *)
> +		 let vcpu_usages = Array.map find_vcpu_usages cpu_stats in
> +                 let prev_vcpu_usages =
> +                   try Some (Hashtbl.find last_vcpu_usages domid)
> +                   with Not_found -> None in
> +		 Hashtbl.replace last_vcpu_usages domid vcpu_usages;
> +
> +		 (match prev_pcpu_usages, prev_vcpu_usages with
> +		  | Some prev_pcpu_usages, Some prev_vcpu_usages
>  		      when Array.length prev_pcpu_usages = Array.length pcpu_usages ->
> -		      Some (domid, name, nr_vcpus, vcpu_infos, pcpu_usages,
> -			    prev_pcpu_usages, cpumaps, maplen)
> +                      Some (domid, name, nr_vcpus, vcpu_infos, pcpu_usages,
> +                      prev_pcpu_usages, vcpu_usages, prev_vcpu_usages,
> +                      cpumaps, maplen)
>  		  | _ -> None (* ignore missing / unequal length prev_vcpu_infos *)
>  		 );
>  	       with
> @@ -691,13 +705,24 @@ let collect, clear_pcpu_display_data =
>  
>  	List.iteri (
>  	  fun di (domid, name, nr_vcpus, vcpu_infos, pcpu_usages,
> -		  prev_pcpu_usages, cpumaps, maplen) ->
> +		  prev_pcpu_usages, vcpu_usages, prev_vcpu_usages,
> +                  cpumaps, maplen) ->
>  	    (* Which pCPUs can this dom run on? *)
>  	    for p = 0 to Array.length pcpu_usages - 1 do
>  	      pcpus.(p).(di) <- pcpu_usages.(p) -^ prev_pcpu_usages.(p)
> -	    done
> +            done
>  	) doms;
>  
> +        let vcpus = Array.make_matrix nr_pcpus nr_doms 0L in
> +        List.iteri (
> +	  fun di (domid, name, nr_vcpus, vcpu_infos, pcpu_usages,
> +		  prev_pcpu_usages, vcpu_usages, prev_vcpu_usages,
> +                  cpumaps, maplen) ->
> +	    for p = 0 to Array.length vcpu_usages - 1 do
> +	      vcpus.(p).(di) <- vcpu_usages.(p) -^ prev_vcpu_usages.(p)
> +            done
> +        ) doms;
> +
>  	(* Sum the CPU time used by each pCPU, for the %CPU column. *)
>  	let pcpus_cpu_time = Array.map (
>  	  fun row ->
> @@ -709,7 +734,7 @@ let collect, clear_pcpu_display_data =
>  	    Int64.to_float !cpu_time
>  	) pcpus in
>  
> -	Some (doms, pcpus, pcpus_cpu_time)
> +	Some (doms, pcpus, vcpus, pcpus_cpu_time)
>        ) else
>  	None in
>  
> @@ -913,7 +938,7 @@ let redraw =
>  	 loop domains_lineno doms
>  
>       | PCPUDisplay -> (*---------- Showing physical CPUs ----------*)
> -	 let doms, pcpus, pcpus_cpu_time =
> +	 let doms, pcpus, vcpus, pcpus_cpu_time =
>  	   match pcpu_display with
>  	   | Some p -> p
>  	   | None -> failwith "internal error: no pcpu_display data" in
> @@ -922,9 +947,9 @@ let redraw =
>  	 let dom_names =
>  	   String.concat "" (
>  	     List.map (
> -	       fun (_, name, _, _, _, _, _, _) ->
> +	       fun (_, name, _, _, _, _, _, _, _, _) ->
>  		 let len = String.length name in
> -		 let width = max (len+1) 7 in
> +		 let width = max (len+1) 12 in
>  		 pad width name
>  	     ) doms
>  	   ) in
> @@ -941,18 +966,27 @@ let redraw =
>  	     addch ' ';
>  
>  	     List.iteri (
> -	       fun di (domid, name, _, _, _, _, _, _) ->
> +	       fun di (domid, name, _, _, _, _, _, _, _, _) ->
>  		 let t = pcpus.(p).(di) in
> +                 let tv = vcpus.(p).(di) in
>  		 let len = String.length name in
> -		 let width = max (len+1) 7 in
> -		 let str =
> +		 let width = max (len+1) 12 in
> +		 let str_pcpu =
>  		   if t <= 0L then ""
>  		   else (
>  		     let t = Int64.to_float t in
>  		     let percent = 100. *. t /. total_cpu_per_pcpu in
> -		     sprintf "%s " (Show.percent percent)
> +		     sprintf "%s" (Show.percent percent)
>  		   ) in
> -		 addstr (pad width str);
> +                 let str_vcpu =
> +                    if tv <= 0L then ""
> +                    else (
> +                      let tv = Int64.to_float tv in
> +                      let percent = 100. *. tv /. total_cpu_per_pcpu in
> +                      sprintf "%s" (Show.percent percent)
> +                    ) in
> +                 let str = sprintf "%s %s" str_pcpu str_vcpu in
> +                 addstr (pad width str);
>  		 ()
>  	     ) doms
>  	 ) pcpus;
> -- 
> 1.7.1
> 
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list

-- 
Thanks,
Hu Tao




More information about the libvir-list mailing list