o
    P3Þgô@  ã                   @   s€   d dl mZ d dlT ddlZddlmZ ddlmZ ddl	Z	ddl
Z
ddlZddlZddlZej ¡ ZdZG dd„ dejƒZdS )	é   )Úbase)Ú*é    N)Úcommandsz$/sys/devices/system/cpu/cpu0/cpuidlec                       s   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zedd	„ ƒZd
d„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Z‡ fd d!„ZdW‡ fd#d$„	Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ Zd-d.„ ZdWd/d0„ZdWd1d2„Zd3d4„ Zd5d6„ Zd7d8„ Ze d9d:d;d<d=„ ƒZ!e"d9ƒdWd>d?„ƒZ#dXdAdB„Z$e dCd:dDdEdFdG„ ƒZ%e"dCƒdWdHdI„ƒZ&dJdK„ Z'e dLd:d;dMdN„ ƒZ(dOdP„ Z)dQdR„ Z*dSdT„ Z+e"dLƒdWdUdV„ƒZ,‡  Z-S )YÚCPULatencyPluginzP
	Plugin for tuning CPU options. Powersaving, governor, required latency, etc.
	c                    sd   t t| ƒj|i |¤Ž d| _d| _d| _d| _d| _d| _d| _	d | _
d | _d | _i | _tƒ | _d S )NTÚx86_64F)Úsuperr   Ú__init__Ú_has_pm_qosÚ_archÚ_is_x86Ú	_is_intelÚ_is_amdÚ_has_energy_perf_biasÚ_has_intel_pstateÚ_min_perf_pct_saveÚ_max_perf_pct_saveÚ_no_turbo_saveÚ_governors_mapr   Ú_cmd)ÚselfÚargsÚkwargs©Ú	__class__© ú:/usr/lib/python3/dist-packages/tuned/plugins/plugin_cpu.pyr	      s   zCPULatencyPlugin.__init__c                 C   s:   d| _ tƒ | _| j d¡D ]	}| j |j¡ qtƒ | _d S )NTÚcpu)Ú_devices_supportedÚsetÚ_free_devicesÚ_hardware_inventoryÚget_devicesÚaddÚsys_nameÚ_assigned_devices©r   Údevicer   r   r   Ú_init_devices'   s
   zCPULatencyPlugin._init_devicesc                    s   ‡ fdd„|D ƒS )Nc                    s   g | ]	}ˆ j  d |¡‘qS )r   )r!   Ú
get_device)Ú.0Úx©r   r   r   Ú
<listcomp>1   s    z8CPULatencyPlugin._get_device_objects.<locals>.<listcomp>r   )r   Údevicesr   r,   r   Ú_get_device_objects0   s   z$CPULatencyPlugin._get_device_objectsc                 C   s   dddd d d d d d d dœ
S )Ngš™™™™™É?éd   iè  )
Úload_thresholdÚlatency_lowÚlatency_highÚforce_latencyÚgovernorÚsampling_down_factorÚenergy_perf_biasÚmin_perf_pctÚmax_perf_pctÚno_turbor   r,   r   r   r   Ú_get_config_options3   s   öz$CPULatencyPlugin._get_config_optionsc                 C   s    g d¢}t  ¡ | _| j|v r7t ¡ }|j d¡}|dkr d| _n|dks(|dkr,d| _nd| _t	 
d| ¡ nt	 
d| j ¡ | jdu rN|  ¡  |  ¡  d S d S )	N)r   Úi686Úi585Úi486Úi386Ú	vendor_idÚGenuineIntelTÚAuthenticAMDÚHygonGenuinez$We are running on an x86 %s platformzWe are running on %s (non x86))ÚplatformÚmachiner   ÚprocfsÚcpuinfoÚtagsÚgetr   r   ÚlogÚinfoÚ_check_energy_perf_biasÚ_check_intel_pstate)r   Úintel_archsr   Úvendorr   r   r   Ú_check_archB   s    


üzCPULatencyPlugin._check_archc                 C   sf   d| _ d}| jjddgtj|gd\}}|dkr!|dkr!d| _ d S |dk r,t d	¡ d S t d
¡ d S )NFr   Úx86_energy_perf_policyú-r)Ú	no_errorsr   Ú Tzgunable to run x86_energy_perf_policy tool, ignoring CPU energy performance bias, is the tool installed?zXyour CPU doesn't support MSR_IA32_ENERGY_PERF_BIAS, ignoring CPU energy performance bias)r   r   ÚexecuteÚerrnoÚENOENTrJ   Úwarning)r   Úretcode_unsupportedÚretcodeÚoutr   r   r   rL   ]   s   
z(CPULatencyPlugin._check_energy_perf_biasc                 C   s&   t j d¡| _| jrt d¡ d S d S )Nz$/sys/devices/system/cpu/intel_pstatezintel_pstate detected)ÚosÚpathÚexistsr   rJ   rK   r,   r   r   r   rM   k   s   ÿz$CPULatencyPlugin._check_intel_pstatec                 C   s    t |ƒ}| j t |ƒ dd¡¡S )Nr   rT   )Ústrr   Úis_cpu_onlineÚreplace)r   r'   Úsdr   r   r   Ú_is_cpu_onlinep   s   zCPULatencyPlugin._is_cpu_onlinec                 C   s   t j d| ¡S )Nú3/sys/devices/system/cpu/%s/cpufreq/scaling_governor)r\   r]   r^   r&   r   r   r   Ú_cpu_has_scaling_governort   ó   z*CPULatencyPlugin._cpu_has_scaling_governorc                 C   s<   |   |¡st d| ¡ dS |  |¡st d| ¡ dS dS )Nz'%s' is not online, skippingFz.there is no scaling governor fo '%s', skippingT)rc   rJ   Údebugre   r&   r   r   r   Ú_check_cpu_can_change_governorw   s   

z/CPULatencyPlugin._check_cpu_can_change_governorc                 C   sì   d|_ d|_t| j ¡ ƒd |krRd|_zt tj	tj
¡| _W n ty3   t dtj	 ¡ d| _Y nw d | _|jd d u rJ| j dd ¡|_d|_nd |_|  ¡  nd|_t d|j ¡ zt|jƒd |_W d S  tyu   d |_Y d S w )NTFr   z-Unable to open '%s', disabling PM_QoS controlr4   ÚloadzILatency settings from non-first CPU plugin instance '%s' will be ignored.)Ú_has_static_tuningÚ_has_dynamic_tuningÚlistÚ
_instancesÚvaluesÚ_first_instancer\   ÚopenÚconstsÚPATH_CPU_DMA_LATENCYÚO_WRONLYÚ_cpu_latency_fdÚOSErrorrJ   Úerrorr
   Ú_latencyÚoptionsÚ_monitors_repositoryÚcreateÚ_load_monitorrP   rK   ÚnameÚassigned_devicesÚ_first_deviceÚ
IndexError©r   Úinstancer   r   r   Ú_instance_init€   s.   
þ
ÿzCPULatencyPlugin._instance_initc                 C   s<   |j r| jrt | j¡ |jd ur| j |j¡ d S d S d S ©N)ro   r
   r\   Úclosert   r{   ry   Údeleter€   r   r   r   Ú_instance_cleanupž   s   
üz"CPULatencyPlugin._instance_cleanupc                 C   s   | j  d| d ¡ ¡ S ©Nz'/sys/devices/system/cpu/intel_pstate/%s)r   Ú	read_fileÚstrip)r   Úattrr   r   r   Ú_get_intel_pstate_attr¥   s   z'CPULatencyPlugin._get_intel_pstate_attrc                 C   s"   |d ur| j  d| |¡ d S d S r‡   )r   Úwrite_to_file)r   rŠ   Úvalr   r   r   Ú_set_intel_pstate_attr¨   s   ÿz'CPULatencyPlugin._set_intel_pstate_attrc                 C   s&   |d u rd S |   |¡}|  ||¡ |S rƒ   )r‹   rŽ   )r   rŠ   ÚvalueÚvr   r   r   Ú_getset_intel_pstate_attr¬   s
   
z*CPULatencyPlugin._getset_intel_pstate_attrc                    s¬   t t| ƒ |¡ |jsd S | j |jd ¡}|d ur|  |¡ | jrT| j |jd ¡}|  	d|¡| _
| j |jd ¡}|  	d|¡| _| j |jd ¡}|  	d|¡| _d S d S )Nr4   r8   r9   r:   )r   r   Ú_instance_apply_staticro   Ú
_variablesÚexpandrx   Ú_set_latencyr   r‘   r   r   r   )r   r   Úforce_latency_valueÚ	new_valuer   r   r   r’   ³   s8   ÿ
ÿÿÿÿÿ
ÿõz'CPULatencyPlugin._instance_apply_staticFc                    sT   t t| ƒ ||¡ |jr&| jr(|  d| j¡ |  d| j¡ |  d| j¡ d S d S d S )Nr8   r9   r:   )	r   r   Ú_instance_unapply_staticro   r   rŽ   r   r   r   )r   r   Úfull_rollbackr   r   r   r˜   Ë   s   ýz)CPULatencyPlugin._instance_unapply_staticc                 C   s   |   ||¡ d S rƒ   )Ú_instance_update_dynamic©r   r   r'   r   r   r   Ú_instance_apply_dynamicÓ   rf   z(CPULatencyPlugin._instance_apply_dynamicc                 C   s\   |j sJ ‚||jkrd S |j ¡ d }||jd k r$|  |jd ¡ d S |  |jd ¡ d S )NÚsystemr1   r3   r2   )ro   r~   r{   Úget_loadrx   r•   )r   r   r'   ri   r   r   r   rš   Ö   s   

z)CPULatencyPlugin._instance_update_dynamicc                 C   s   d S rƒ   r   r›   r   r   r   Ú_instance_unapply_dynamicá   s   z*CPULatencyPlugin._instance_unapply_dynamicc              	   C   s$   zt |ƒW S  ttfy   Y d S w rƒ   )ÚintÚ
ValueErrorÚ	TypeError©r   Úsr   r   r   Ú_str2intä   s
   
ÿzCPULatencyPlugin._str2intc                 C   s‚   i | _ t t¡D ]6}td|  }| jj|d d dd}| jj|d d dd}|d ur>|d ur>|  |¡}|d ur>|| j | ¡ < qd S )Nz/%s/r|   T©Úerr_retÚno_errorÚlatency)Úcstates_latencyr\   ÚlistdirÚcpuidle_states_pathr   rˆ   r¥   r‰   )r   ÚdÚcstate_pathr|   r©   r   r   r   Ú_read_cstates_latencyê   s   
€ùz&CPULatencyPlugin._read_cstates_latencyc                 C   sh   t  d| ¡ | jd u rt  d¡ |  ¡  | j |d ¡}|r)|dkr)t  d¡ d S t  dt|ƒ ¡ |S )Nz)getting latency for cstate with name '%s'zreading cstates latency tabler   ú"skipping latency 0 as set by paramz!cstate name mapped to latency: %s)rJ   rg   rª   r¯   rI   r_   )r   r|   Úno_zeror©   r   r   r   Ú_get_latency_by_cstate_nameõ   s   


z,CPULatencyPlugin._get_latency_by_cstate_namec                 C   sŠ   t  dt|ƒ ¡ |  |¡}|d u rt  d¡ d S tdd|   }|  | jj|d dd¡}|r:|dkr:t  d¡ d S t  d	t|ƒ ¡ |S )
Nz'getting latency for cstate with ID '%s'zcstate ID is invalidz/%s/latencyzstate%dTr¦   r   r°   zcstate ID mapped to latency: %s)rJ   rg   r_   r¥   r¬   r   rˆ   )r   Úlidr±   Úlatency_pathr©   r   r   r   Ú_get_latency_by_cstate_id  s   


z*CPULatencyPlugin._get_latency_by_cstate_idc              	   C   s8  d | _ t|ƒ d¡}t d¡ |D ]†}zt|ƒ}t d| ¡ W nm ty   |dd… dkr;| j|dd … dd}nP|dd	… d
krM|  |d	d … ¡}n>|dd… dkra| j|dd … dd}n*|dd… dkrs|  |dd … ¡}n|dv r€t d¡ Y  dS d }t dt|ƒ ¡ Y nw |d ur— |dfS q|dfS )Nú|zparsing latencyz+parsed directly specified latency value: %dr   é   zcstate.id_no_zero:T)r±   é
   z
cstate.id:é   zcstate.name_no_zero:é   zcstate.name:)ÚnoneÚNonezlatency 'none' specified)NTzinvalid latency specified: '%s'F)	rª   r_   ÚsplitrJ   rg   r    r¡   rµ   r²   )r   r©   Ú	latenciesr   r   r   Ú_parse_latency  s8   

€òþzCPULatencyPlugin._parse_latencyc                 C   s|   |   |¡\}}|s8| jr:|d u rt d¡ d| _d S | j|kr<t d| ¡ t d|¡}t 	| j
|¡ || _d S d S d S d S )Nztunable to evaluate latency value (probably wrong settings in the 'cpu' section of current profile), disabling PM QoSFzsetting new cpu latency %dÚi)r¿   r
   rJ   rv   rw   rK   ÚstructÚpackr\   Úwritert   )r   r©   ÚskipÚlatency_binr   r   r   r•   +  s   




øzCPULatencyPlugin._set_latencyc                 C   s   | j  d| ¡ ¡  ¡ S )Nz>/sys/devices/system/cpu/%s/cpufreq/scaling_available_governors)r   rˆ   r‰   r½   r&   r   r   r   Ú_get_available_governors7  s   z)CPULatencyPlugin._get_available_governorsr5   T)Ú
per_devicec                 C   sÐ   |   |¡sd S t|ƒ}| d¡}dd„ |D ƒ}|D ]}t|ƒdkr)t d¡  d S q|  |¡}|D ](}||v rN|sKt d||f ¡ | j 	d| |¡  |S |sYt 
d||f ¡ q1t d	d
 |¡ ¡ d }|S )Nr¶   c                 S   s   g | ]}|  ¡ ‘qS r   )r‰   )r*   r5   r   r   r   r-   @  s    z2CPULatencyPlugin._set_governor.<locals>.<listcomp>r   z.The 'governor' option contains an empty value.z!setting governor '%s' on cpu '%s'rd   z7Ignoring governor '%s' on cpu '%s', it is not supportedz.None of the scaling governors is supported: %sz, )rh   r_   r½   ÚlenrJ   rv   rÆ   rK   r   rŒ   rg   ÚwarnÚjoin)r   Ú	governorsr'   Úsimr5   Úavailable_governorsr   r   r   Ú_set_governor:  sD   


þ
ÿÿÿùÿ€ÿzCPULatencyPlugin._set_governorc                 C   sT   d }|   |¡s	d S | jjd| |d ¡ }t|ƒdkr|}|d u r(t d| ¡ |S )Nrd   )r¨   r   z*could not get current governor on cpu '%s')rh   r   rˆ   r‰   rÈ   rJ   rv   )r   r'   Úignore_missingr5   Údatar   r   r   Ú_get_governorW  s   
zCPULatencyPlugin._get_governorÚondemandc                 C   s   d| S )Nz7/sys/devices/system/cpu/cpufreq/%s/sampling_down_factorr   )r   r5   r   r   r   Ú_sampling_down_factor_pathe  s   z+CPULatencyPlugin._sampling_down_factor_pathr6   r¸   )rÇ   Úpriorityc                 C   s¾   d }|| j v r| j  ¡  d | j |< |  |¡}|d u r#t d| ¡ d S |t| j  ¡ ƒvr]|| j |< |  |¡}tj	 
|¡sGt d||f ¡ d S t|ƒ}|s]t d||f ¡ | j ||¡ |S )NzIignoring sampling_down_factor setting for CPU '%s', cannot match governorzTignoring sampling_down_factor setting for CPU '%s', governor '%s' doesn't support itz6setting sampling_down_factor to '%s' for governor '%s')r   ÚclearrÑ   rJ   rg   rl   rn   rÓ   r\   r]   r^   r_   rK   r   rŒ   )r   r6   r'   rÌ   r   r5   r]   r   r   r   Ú_set_sampling_down_factorh  s&   





z*CPULatencyPlugin._set_sampling_down_factorc                 C   sD   | j ||d}|d u rd S |  |¡}tj |¡sd S | j |¡ ¡ S )N)rÏ   )rÑ   rÓ   r\   r]   r^   r   rˆ   r‰   )r   r'   rÏ   r5   r]   r   r   r   Ú_get_sampling_down_factorƒ  s   
z*CPULatencyPlugin._get_sampling_down_factorc                 C   s*   | j jdd|t|ƒgdd\}}}||fS )NrQ   ú-cT)Ú
return_err)r   rU   r_   )r   Úcpu_idr   rZ   r[   Úerr_msgr   r   r   Ú_try_set_energy_perf_bias  s   þûz*CPULatencyPlugin._try_set_energy_perf_biasr7   c           	      C   sÞ   |   |¡st d| ¡ d S | jrm|si| d¡}| d¡}|D ]B}| ¡ }t d||f ¡ |  ||¡\}}|dkrHt d||f ¡  t
|ƒS |dk rXt 	d| ¡  t
|ƒS t d||f ¡ qt 	d	| ¡ t
|ƒS d S )
Nú%s is not online, skippingr   r¶   z2Trying to set energy_perf_bias to '%s' on cpu '%s'r   z5energy_perf_bias successfully set to '%s' on cpu '%s'z"Failed to set energy_perf_bias: %szHCould not set energy_perf_bias to '%s' on cpu '%s', trying another valuezPFailed to set energy_perf_bias on cpu '%s'. Is the value in the profile correct?)rc   rJ   rg   r   Úlstripr½   r‰   rÜ   rK   rv   r_   )	r   r7   r'   rÌ   rÚ   Úvalsr   rZ   rÛ   r   r   r   Ú_set_energy_perf_bias–  sF   


ÿÿÿöÿûÿÿz&CPULatencyPlugin._set_energy_perf_biasc                 C   s|   zt |ƒ}W |S  ty= } z*zt |dƒ}W n ty* } z|}W Y d }~nd }~ww W Y d }~|S W Y d }~|S d }~ww )Né   )r    r¡   )r   r¤   r   Úer   r   r   Ú_try_parse_num·  s    
û€ÿ
ÿ
ÿ€ûzCPULatencyPlugin._try_parse_numc                 C   s   ddddœ  |  |¡|¡S )NÚperformanceÚnormalÚ	powersave)r   é   é   ©rI   rã   r£   r   r   r   Ú_energy_perf_policy_to_humanÂ  s   z-CPULatencyPlugin._energy_perf_policy_to_humanc                 C   s   ddddddœ  |  |¡|¡S )Nrä   zbalance-performancerå   zbalance-powerÚpower)r   é   rç   é   rè   ré   r£   r   r   r   Ú_energy_perf_policy_to_human_v2Æ  s   üûz0CPULatencyPlugin._energy_perf_policy_to_human_v2c           	      C   sª   d }|   |¡st d| ¡ d S | jrS| d¡}| j dd|dg¡\}}|dkrS| ¡ D ]&}| ¡ }t	|ƒdkrB|  
|d ¡} |S t	|ƒd	krR|  |d ¡} |S q,|S )
NrÝ   r   rQ   rØ   rR   r   é   r   é   )rc   rJ   rg   r   rÞ   r   rU   Ú
splitlinesr½   rÈ   rê   rî   )	r   r'   rÏ   r7   rÚ   rZ   ÚlinesÚlineÚlr   r   r   Ú_get_energy_perf_biasÎ  s(   

üüz&CPULatencyPlugin._get_energy_perf_bias)F)rÒ   ).Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   r(   r/   Úclassmethodr;   rP   rL   rM   rc   re   rh   r‚   r†   r‹   rŽ   r‘   r’   r˜   rœ   rš   rŸ   r¥   r¯   r²   rµ   r¿   r•   rÆ   Úcommand_setrÎ   Úcommand_getrÑ   rÓ   rÖ   r×   rÜ   rà   rã   rê   rî   rõ   Ú__classcell__r   r   r   r   r      s^    	
	





	
	
 r   )rT   r   Ú
decoratorsÚ
tuned.logsÚtunedÚtuned.utils.commandsr   Útuned.constsrq   r\   rÁ   rV   rD   rF   ÚlogsrI   rJ   r¬   ÚPluginr   r   r   r   r   Ú<module>   s    
