<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css"
        integrity="sha512-SzlrxWUlpfuzQ+pcUCosxcglQRNAq/DZjVsC0lE40xsADsfeQoEypE+enwcOiGjk/bSuGGKHEyjSoQ1zVisanQ=="
        crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
</html>
3
<e                 @   s
  d dl mZ d dlT ddlZddlZddlT ddlZddlZddl	Z	ddl
jZddlZddlmZ ddlZddlZddlZddlZy
ej W n ek
r   ddlZY nX ejj ZG dd deZG dd	 d	eZG d
d deZG dd deZG dd dejZdS )   )base)*    N)commandsc               @   s0   e Zd ZdddZedd Zejdd ZdS )SchedulerParamsNc             C   s(   || _ || _|| _|| _|| _|| _d S )N)_cmdcmdline	schedulerpriorityaffinitycgroup)selfcmdr   r	   r
   r   r    r   &/usr/lib/python3.6/plugin_scheduler.py__init__   s    zSchedulerParams.__init__c             C   s    | j d krd S | jj| j S d S )N)	_affinityr   Zbitmask2cpulist)r   r   r   r   r   &   s    
zSchedulerParams.affinityc             C   s"   |d krd | _ n| jj|| _ d S )N)r   r   Zcpulist2bitmask)r   valuer   r   r   r   -   s    )NNNNN)__name__
__module____qualname__r   propertyr   setterr   r   r   r   r      s    
r   c               @   s   e Zd Zdd ZdS )IRQAffinitiesc             C   s   i | _ d | _g | _d S )N)irqsdefaultunchangeable)r   r   r   r   r   5   s    zIRQAffinities.__init__N)r   r   r   r   r   r   r   r   r   4   s   r   c               @   sp   e Zd ZdZdddd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S )SchedulerUtilsz=
	Class encapsulating scheduler implementation in os module
	
SCHED_FIFOSCHED_BATCHSCHED_RRSCHED_OTHER
SCHED_IDLE)fbroic             C   s8   t dd | jj D | _t dd | jj D | _d S )Nc             s   s    | ]\}}|t t|fV  qd S )N)getattros).0knamer   r   r   	<genexpr>J   s    z*SchedulerUtils.__init__.<locals>.<genexpr>c             s   s   | ]}t t||fV  qd S )N)r(   r)   )r*   r,   r   r   r   r-   L   s    )dict_dict_schedcfg2schedconstitems_dict_schedcfg2numvalues_dict_num2schedconst)r   r   r   r   r   H   s    zSchedulerUtils.__init__c             C   s   | j j|S )N)r1   get)r   str_schedulerr   r   r   sched_cfg_to_numN   s    zSchedulerUtils.sched_cfg_to_numc             C   s   | j j|S )N)r3   r4   )r   r	   r   r   r   sched_num_to_constR   s    z!SchedulerUtils.sched_num_to_constc             C   s
   t j|S )N)r)   sched_getscheduler)r   pidr   r   r   get_schedulerU   s    zSchedulerUtils.get_schedulerc             C   s   t j||t j| d S )N)r)   sched_setschedulersched_param)r   r9   schedprior   r   r   set_schedulerX   s    zSchedulerUtils.set_schedulerc             C   s
   t j|S )N)r)   sched_getaffinity)r   r9   r   r   r   get_affinity[   s    zSchedulerUtils.get_affinityc             C   s   t j|| d S )N)r)   sched_setaffinity)r   r9   r   r   r   r   set_affinity^   s    zSchedulerUtils.set_affinityc             C   s   t j|jS )N)r)   sched_getparamsched_priority)r   r9   r   r   r   get_prioritya   s    zSchedulerUtils.get_priorityc             C   s
   t j|S )N)r)   sched_get_priority_min)r   r=   r   r   r   get_priority_mind   s    zSchedulerUtils.get_priority_minc             C   s
   t j|S )N)r)   sched_get_priority_max)r   r=   r   r   r   get_priority_maxg   s    zSchedulerUtils.get_priority_maxN)r   r   r   __doc__r/   r   r6   r7   r:   r?   rA   rC   rF   rH   rJ   r   r   r   r   r   ;   s    r   c               @   sP   e Zd Z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S )SchedulerUtilsSchedutilszE
	Class encapsulating scheduler implementation in schedutils module
	c             C   s8   t dd | jj D | _t dd | jj D | _d S )Nc             s   s    | ]\}}|t t|fV  qd S )N)r(   
schedutils)r*   r+   r,   r   r   r   r-   p   s    z4SchedulerUtilsSchedutils.__init__.<locals>.<genexpr>c             s   s   | ]}t t||fV  qd S )N)r(   rM   )r*   r,   r   r   r   r-   r   s    )r.   r/   r0   r1   r2   r3   )r   r   r   r   r   n   s    z!SchedulerUtilsSchedutils.__init__c             C   s
   t j|S )N)rM   r:   )r   r9   r   r   r   r:   t   s    z&SchedulerUtilsSchedutils.get_schedulerc             C   s   t j||| d S )N)rM   r?   )r   r9   r=   r>   r   r   r   r?   w   s    z&SchedulerUtilsSchedutils.set_schedulerc             C   s
   t j|S )N)rM   rA   )r   r9   r   r   r   rA   z   s    z%SchedulerUtilsSchedutils.get_affinityc             C   s   t j|| d S )N)rM   rC   )r   r9   r   r   r   r   rC   }   s    z%SchedulerUtilsSchedutils.set_affinityc             C   s
   t j|S )N)rM   rF   )r   r9   r   r   r   rF      s    z%SchedulerUtilsSchedutils.get_priorityc             C   s
   t j|S )N)rM   rH   )r   r=   r   r   r   rH      s    z)SchedulerUtilsSchedutils.get_priority_minc             C   s
   t j|S )N)rM   rJ   )r   r=   r   r   r   rJ      s    z)SchedulerUtilsSchedutils.get_priority_maxN)r   r   r   rK   r   r:   r?   rA   rC   rF   rH   rJ   r   r   r   r   rL   j   s   rL   c                   s  e Zd ZdZ fddZ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dd!d"Zd#d$ Zd%d& Zd'd( Zdd)d*Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zd9d: Z d;d< Z!d=d> Z"dd?d@Z#dAdB Z$dCdD Z% fdEdFZ&dGdH Z'dIdJ Z(dKdL Z)e*j+f fdMdN	Z,dOdP Z-dQdR Z. fdSdTZ/dUdV Z0dWdX Z1dYdZ Z2e3d[d d\d]d^ Z4e3d_d d\d`da Z5e3dbd d\dcdd Z6e3ded d\dfdg Z7e3dhd d\didj Z8e3dkd d\dldm Z9dndo Z:dpdq Z;drds Z<ddtduZ=dvdw Z>dxdy Z?dzd{ Z@d|d} ZAd~d ZBdd ZCdd ZDdd ZEdd ZFe3dd dddd ZGdd ZHdd ZIdddZJeKddd ZLeMddd ZNeKddd ZOeMddd ZPeKddd ZQeMddd ZReKddd ZSeMddd ZTeKddd ZUeMddd ZVeKddd ZWeMddd ZXeKddd ZYeMddd ZZeKddd Z[eMddd Z\eKddd Z]eMddd Z^eKddd Z_eMdddĄ Z`  ZaS )SchedulerPlugina]-  
	`scheduler`::
	
	Allows tuning of scheduling priorities, process/thread/IRQ
	affinities, and CPU isolation.
	+
	To prevent processes/threads/IRQs from using certain CPUs, use
	the [option]`isolated_cores` option. It changes process/thread
	affinities, IRQs affinities and it sets `default_smp_affinity`
	for IRQs. The CPU affinity mask is adjusted for all processes and
	threads matching [option]`ps_whitelist` option subject to success
	of the `sched_setaffinity()` system call. The default setting of
	the [option]`ps_whitelist` regular expression is `.*` to match all
	processes and thread names. To exclude certain processes and threads
	use [option]`ps_blacklist` option. The value of this option is also
	interpreted as a regular expression and process/thread names (`ps -eo
	cmd`) are matched against that expression. Profile rollback allows
	all matching processes and threads to run on all CPUs and restores
	the IRQ settings prior to the profile application.
	+
	Multiple regular expressions for [option]`ps_whitelist`
	and [option]`ps_blacklist` options are allowed and separated by
	`;`. Quoted semicolon `\;` is taken literally.
	+
	.Isolate CPUs 2-4
	====
	----
	[scheduler]
	isolated_cores=2-4
	ps_blacklist=.*pmd.*;.*PMD.*;^DPDK;.*qemu-kvm.*
	----
	Isolate CPUs 2-4 while ignoring processes and threads matching
	`ps_blacklist` regular expressions.
	====
	The [option]`irq_process` option controls whether the scheduler plugin
	applies the `isolated_cores` parameter to IRQ affinities. The default
	value is `true`, which means that the scheduler plugin will move all
	possible IRQs away from the isolated cores. When `irq_process` is set
	to `false`, the plugin will not change any IRQ affinities.
	====
	The [option]`default_irq_smp_affinity` option controls the values
	*TuneD* writes to `/proc/irq/default_smp_affinity`. The file specifies
	default affinity mask that applies to all non-active IRQs. Once an
	IRQ is allocated/activated its affinity bitmask will be set to the
	default mask.
	+
	The following values are supported:
	+
	--
	`calc`::
	Content of `/proc/irq/default_smp_affinity` will be calculated
	from the `isolated_cores` parameter. Non-isolated cores
	are calculated as an inversion of the `isolated_cores`. Then
	the intersection of the non-isolated cores and the previous
	content of `/proc/irq/default_smp_affinity` is written to
	`/proc/irq/default_smp_affinity`. If the intersection is
	an empty set, then just the non-isolated cores are written to
	`/proc/irq/default_smp_affinity`. This behavior is the default if
	the parameter `default_irq_smp_affinity` is omitted.
	`ignore`::
	*TuneD* will not touch `/proc/irq/default_smp_affinity`.
	explicit cpulist::
	The cpulist (such as 1,3-4) is unpacked and written directly to
	`/proc/irq/default_smp_affinity`.
	--
	+
	.An explicit CPU list to set the default IRQ smp affinity to CPUs 0 and 2
	====
	----
	[scheduler]
	isolated_cores=1,3
	default_irq_smp_affinity=0,2
	----
	====
	To adjust scheduling policy, priority and affinity for a group of
	processes/threads, use the following syntax.
	+
	[subs="+quotes,+macros"]
	----
	group.__groupname__=__rule_prio__:__sched__:__prio__:__affinity__:__regex__
	----
	+
	where `__rule_prio__` defines internal *TuneD* priority of the
	rule. Rules are sorted based on priority. This is needed for
	inheritence to be able to reorder previously defined rules. Equal
	`__rule_prio__` rules should be processed in the order they were
	defined. However, this is Python interpreter dependant. To disable
	an inherited rule for `__groupname__` use:
	+
	[subs="+quotes,+macros"]
	----
	group.__groupname__=
	----
	+
	`__sched__` must be one of:
	*`f`* for FIFO,
	*`b`* for batch,
	*`r`* for round robin,
	*`o`* for other,
	*`*`* do not change.
	+
	`__affinity__` is CPU affinity in hexadecimal. Use `*` for no change.
	+
	`__prio__` scheduling priority (see `chrt -m`).
	+
	`__regex__` is Python regular expression. It is matched against the output of
	+
	[subs="+quotes,+macros"]
	----
	ps -eo cmd
	----
	+
	Any given process name may match more than one group. In such a case,
	the priority and scheduling policy are taken from the last matching
	`__regex__`.
	+
	.Setting scheduling policy and priorities to kernel threads and watchdog
	====
	----
	[scheduler]
	group.kthreads=0:*:1:*:\[.*\]$
	group.watchdog=0:f:99:*:\[watchdog.*\]
	----
	====
	+
	The scheduler plug-in uses perf event loop to catch newly created
	processes. By default it listens to `perf.RECORD_COMM` and
	`perf.RECORD_EXIT` events. By setting [option]`perf_process_fork`
	option to `true`, `perf.RECORD_FORK` events will be also listened
	to. In other words, child processes created by the `fork()` system
	call will be processed. Since child processes inherit CPU affinity
	from their parents, the scheduler plug-in usually does not need to
	explicitly process these events. As processing perf events can
	pose a significant CPU overhead, the [option]`perf_process_fork`
	option parameter is set to `false` by default. Due to this, child
	processes are not processed by the scheduler plug-in.
	+
	The CPU overhead of the scheduler plugin can be mitigated by using
	the scheduler [option]`runtime` option and setting it to `0`. This
	will completely disable the dynamic scheduler functionality and the
	perf events will not be monitored and acted upon. The disadvantage
	ot this approach is the procees/thread tuning will be done only at
	profile application.
	+
	.Disabling the scheduler dynamic functionality
	====
	----
	[scheduler]
	runtime=0
	isolated_cores=1,3
	----
	====
	+
	NOTE: For perf events, memory mapped buffer is used. Under heavy load
	the buffer may overflow. In such cases the `scheduler` plug-in
	may start missing events and failing to process some newly created
	processes. Increasing the buffer size may help. The buffer size can
	be set with the [option]`perf_mmap_pages` option. The value of this
	parameter has to expressed in powers of 2. If it is not the power
	of 2, the nearest higher power of 2 value is calculated from it
	and this calculated value used. If the [option]`perf_mmap_pages`
	option is omitted, the default kernel value is used.
	+
	The scheduler plug-in supports process/thread confinement using
	cgroups v1.
	+
	[option]`cgroup_mount_point` option specifies the path to mount the
	cgroup filesystem or where *TuneD* expects it to be mounted. If unset,
	`/sys/fs/cgroup/cpuset` is expected.
	+
	If [option]`cgroup_groups_init` option is set to `1` *TuneD*
	will create (and remove) all cgroups defined with the `cgroup*`
	options. This is the default behavior. If it is set to `0` the
	cgroups need to be preset by other means.
	+
	If [option]`cgroup_mount_point_init` option is set to `1`,
	*TuneD* will create (and remove) the cgroup mountpoint. It implies
	`cgroup_groups_init = 1`. If set to `0` the cgroups mount point
	needs to be preset by other means. This is the default behavior.
	+
	The [option]`cgroup_for_isolated_cores` option is the cgroup
	name used for the [option]`isolated_cores` option functionality. For
	example, if a system has 4 CPUs, `isolated_cores=1` means that all
	processes/threads will be moved to CPUs 0,2-3.
	The scheduler plug-in will isolate the specified core by writing
	the calculated CPU affinity to the `cpuset.cpus` control file of
	the specified cgroup and move all the matching processes/threads to
	this group. If this option is unset, classic cpuset affinity using
	`sched_setaffinity()` will be used.
	+
	[option]`cgroup.__cgroup_name__` option defines affinities for
	arbitrary cgroups. Even hierarchic cgroups can be used, but the
	hieararchy needs to be specified in the correct order. Also *TuneD*
	does not do any sanity checks here, with the exception that it forces
	the cgroup to be under [option]`cgroup_mount_point`.
	+
	The syntax of the scheduler option starting with `group.` has been
	augmented to use `cgroup.__cgroup_name__` instead of the hexadecimal
	`__affinity__`. The matching processes will be moved to the cgroup
	`__cgroup_name__`. It is also possible to use cgroups which have
	not been defined by the [option]`cgroup.` option as described above,
	i.e. cgroups not managed by *TuneD*.
	+
	All cgroup names are sanitized by replacing all all dots (`.`) with
	slashes (`/`). This is to prevent the plug-in from writing outside
	[option]`cgroup_mount_point`.
	+
	.Using cgroups v1 with the scheduler plug-in
	====
	----
	[scheduler]
	cgroup_mount_point=/sys/fs/cgroup/cpuset
	cgroup_mount_point_init=1
	cgroup_groups_init=1
	cgroup_for_isolated_cores=group
	cgroup.group1=2
	cgroup.group2=0,2
	
	group.ksoftirqd=0:f:2:cgroup.group1:ksoftirqd.*
	ps_blacklist=ksoftirqd.*;rcuc.*;rcub.*;ktimersoftd.*
	isolated_cores=1
	----
	Cgroup `group1` has the affinity set to CPU 2 and the cgroup `group2`
	to CPUs 0,2. Given a 4 CPU setup, the [option]`isolated_cores=1`
	option causes all processes/threads to be moved to CPU
	cores 0,2-3. Processes/threads that are blacklisted by the
	[option]`ps_blacklist` regular expression will not be moved.
	
	The scheduler plug-in will isolate the specified core by writing the
	CPU affinity 0,2-3 to the `cpuset.cpus` control file of the `group`
	and move all the matching processes/threads to this cgroup.
	====
	Option [option]`cgroup_ps_blacklist` allows excluding processes
	which belong to the blacklisted cgroups. The regular expression specified
	by this option is matched against cgroup hierarchies from
	`/proc/PID/cgroups`. Cgroups v1 hierarchies from `/proc/PID/cgroups`
	are separated by commas ',' prior to regular expression matching. The
	following is an example of content against which the regular expression
	is matched against: `10:hugetlb:/,9:perf_event:/,8:blkio:/`
	+
	Multiple regular expressions can be separated by semicolon ';'. The
	semicolon represents a logical 'or' operator.
	+
	.Cgroup-based exclusion of processes from the scheduler
	====
	----
	[scheduler]
	isolated_cores=1
	cgroup_ps_blacklist=:/daemons\b
	----
	
	The scheduler plug-in will move all processes away from core 1 except processes which
	belong to cgroup '/daemons'. The '\b' is a regular expression
	metacharacter that matches a word boundary.
	
	----
	[scheduler]
	isolated_cores=1
	cgroup_ps_blacklist=\b8:blkio:
	----
	
	The scheduler plug-in will exclude all processes which belong to a cgroup
	with hierarchy-ID 8 and controller-list blkio.
	====
	Recent kernels moved some `sched_` and `numa_balancing_` kernel run-time
	parameters from `/proc/sys/kernel`, managed by the `sysctl` utility, to
	`debugfs`, typically mounted under `/sys/kernel/debug`.  TuneD provides an
	abstraction mechanism for the following parameters via the scheduler plug-in:
	[option]`sched_min_granularity_ns`, [option]`sched_latency_ns`,
	[option]`sched_wakeup_granularity_ns`, [option]`sched_tunable_scaling`,
	[option]`sched_migration_cost_ns`, [option]`sched_nr_migrate`,
	[option]`numa_balancing_scan_delay_ms`,
	[option]`numa_balancing_scan_period_min_ms`,
	[option]`numa_balancing_scan_period_max_ms` and
	[option]`numa_balancing_scan_size_mb`.
	Based on the kernel used, TuneD will write the specified value to the correct
	location.
	+
	.Set tasks' "cache hot" value for migration decisions.
	====
	----
	[scheduler]
	sched_migration_cost_ns=500000
	----
	On the old kernels, this is equivalent to:
	----
	[sysctl]
	kernel.sched_migration_cost_ns=500000
	----
	that is, value `500000` will be written to `/proc/sys/kernel/sched_migration_cost_ns`.
	However, on more recent kernels, the value `500000` will be written to
	`/sys/kernel/debug/sched/migration_cost_ns`.
	====
	c	       	         s   t t| j|||||||| d| _tj| _ttj| _	|d k	rh|j
tjtj| _t|jtjtj| _	t | _d | _i | _d| _d| _d| _tj | _| jdd| _d| _| jdd| _d | _yt | _W n tk
r   t  | _Y nX d S )NTz.* r	   )Zcommand_nameirq)!superrN   r   Z_has_dynamic_optionsconstsZCFG_DEF_DAEMON_daemonintZCFG_DEF_SLEEP_INTERVAL_sleep_intervalget_boolZ
CFG_DAEMONr4   ZCFG_SLEEP_INTERVALr   r   _secure_boot_hint_sched_knob_paths_cache_ps_whitelist_ps_blacklist_cgroup_ps_blacklist_reperfZcpu_map_cpusZ_storage_key_scheduler_storage_key_irq_process_irq_storage_key_evlistr   _scheduler_utilsAttributeErrorrL   )	r   Zmonitor_repositoryZstorage_factoryZhardware_inventoryZdevice_matcherZdevice_matcher_udevZplugin_instance_factoryZ
global_cfg	variables)	__class__r   r   r     s0    


zSchedulerPlugin.__init__c             C   sT   |d krd S yt |}W n tk
r,   dS X |dkr:dS t dtjtj|d S )Nr      )rT   
ValueErrormathZceillog)r   Z
mmap_pagesZmpr   r   r   _calc_mmap_pages  s    z SchedulerPlugin._calc_mmap_pagesc                s  d |_ d|_d|_d|_ jj ji  _t jdkr^t	j
d  j  i  _ jj j t  _d  _d _d  _tj fdd|jj D  _|j|_ jj|jd } j|}|dkrt	jd|  d }|d k	rt||krt	j
d	||f  x(|jD ]} jj|j| |j|< qW  jj|jjd
ddkrHd|_tj  |_! j"r |jr yt#j$ |_%t#j&t#j't#j(ddddddt#j)t#j*B d	}|j+ j,|j%d t#j- j,|j%|_ |j j.| |d kr|j j/  n|j j/|d W n   d|_Y nX d S )NFTr   z0recovering scheduling settings from previous runc                sJ   g | ]B\}}|d d dkrt |dkr j|dd   jj|fqS )N   zcgroup.)len_sanitize_cgroup_path
_variablesexpand)r*   optionr   )r   r   r   
<listcomp>  s   z2SchedulerPlugin._instance_init.<locals>.<listcomp>perf_mmap_pageszKInvalid 'perf_mmap_pages' value specified: '%s', using default kernel valuezL'perf_mmap_pages' value has to be power of two, specified: '%s', using: '%d'Zruntimer   0)	typeconfigZtaskcommmmapZfreqZwakeup_eventsZ	watermarkZsample_type)Zcpusthreads)Zpages)0ra   Z_has_dynamic_tuningZ_has_static_tuning_runtime_tuning_storager4   r^   _scheduler_originalrl   ri   info_restore_ps_affinityunsetr.   _cgroups_original_affinityr   _cgroup_affinity_initialized_cgroupcollectionsOrderedDictoptionsr0   _cgroups
_schedulerrn   ro   rj   errorstrr   rV   	threadingZEvent
_terminaterS   r\   Z
thread_mapZ_threadsevselZTYPE_SOFTWAREZCOUNT_SW_DUMMYZ
SAMPLE_TIDZ
SAMPLE_CPUopenr]   Zevlistaddrw   )r   instanceZperf_mmap_pages_rawrr   r+   r   r   )r   r   _instance_init  s^    




zSchedulerPlugin._instance_initc             C   s*   |j r&x|j j D ]}tj|j qW d S )N)ra   
get_pollfdr)   closer,   )r   r   fdr   r   r   _instance_cleanup  s    z!SchedulerPlugin._instance_cleanupc             C   s4   d t jddd d d d ddd dd d d d d d d d d d dS )NFTcalcZfalse)isolated_corescgroup_mount_pointcgroup_mount_point_initcgroup_groups_initcgroup_for_isolated_corescgroup_ps_blacklistps_whitelistps_blacklistirq_processdefault_irq_smp_affinityrr   perf_process_forksched_min_granularity_nssched_latency_nssched_wakeup_granularity_nssched_tunable_scalingsched_migration_cost_nssched_nr_migratenuma_balancing_scan_delay_ms!numa_balancing_scan_period_min_ms!numa_balancing_scan_period_max_msnuma_balancing_scan_size_mb)rR   ZDEF_CGROUP_MOUNT_POINT)clsr   r   r   _get_config_options  s,    z#SchedulerPlugin._get_config_optionsc             C   s   |d k	rt |jddS d S )N./)r   replace)r   r   r   r   r   rm   9  s    z%SchedulerPlugin._sanitize_cgroup_pathc             C   s>   t |tjs|}tj|}tj|}| j|r:d| d }|S )N[])
isinstanceprocfsprocessZprocess_cmdline_is_kthread)r   r   r9   r   r   r   r   _get_cmdline=  s    


zSchedulerPlugin._get_cmdlinec             C   s   t j }|j  i }x|j D ]}yN| j|}|d }|||< d|krnx&|d j D ]}| j|}|||< qTW W q ttfk
r } z$|jtj	ks|jtj
krwn W Y d d }~X qX qW |S )Nr9   rx   )r   pidstatsreload_threadsr2   r   keysOSErrorIOErrorerrnoENOENTESRCH)r   ps	processesprocr   r9   er   r   r   get_processesG  s$    

zSchedulerPlugin.get_processesc             C   s@   | j j|}| j j|}| j j|}tjd|||f  ||fS )Nz8Read scheduler policy '%s' and priority '%d' of PID '%d')rb   r:   r7   rF   ri   debug)r   r9   r	   	sched_strr
   r   r   r   _get_rt`  s    zSchedulerPlugin._get_rtc             C   s  | j j|}tjd|||f  yB| j j|}| j j|}||k sJ||kr`tjd||||f  W n4 ttfk
r } ztjd|  W Y d d }~X nX y| j j	||| W n` ttfk
r } z>t
|dr|jtjkrtjd|  ntjd||f  W Y d d }~X nX d S )NzBSetting scheduler policy to '%s' and priority to '%d' of PID '%d'.z9Priority for %s must be in range %d - %d. '%d' was given.z(Failed to get allowed priority range: %sr   zAFailed to set scheduling parameters of PID %d, the task vanished.z1Failed to set scheduling parameters of PID %d: %s)rb   r7   ri   r   rH   rJ   r   SystemErrorr   r?   hasattrr   r   )r   r9   r=   r>   r   Zprio_minZprio_maxr   r   r   r   _set_rth  s*    
zSchedulerPlugin._set_rtc             C   s   |d d t jj@ dkS )Nstatflagsr   )r   ZpidstatZ
PF_KTHREAD)r   r   r   r   r   r     s    zSchedulerPlugin._is_kthreadc             C   s  yjt j|}|d j rd|d d dkr8tjd|  n(| j|rRtjd|  ntjd|  dS dS W n ttfk
r } zF|j	t	j
ks|j	t	jkrtjd	|  dS tjd
||f  dS W Y d d }~X n8 ttfk
r } ztjd
||f  dS d }~X nX d S )Nr   stateZzYAffinity of zombie task with PID %d cannot be changed, the task's affinity mask is fixed.z[Affinity of kernel thread with PID %d cannot be changed, the task's affinity mask is fixed.zRAffinity of task with PID %d cannot be changed, the task's affinity mask is fixed.r   r   z6Failed to get task info for PID %d, the task vanished.z&Failed to get task info for PID %d: %srf   r   )r   r   Zis_bound_to_cpuri   r   r   warnr   r   r   r   r   r   rc   KeyError)r   r9   r   r   r   r   r   _affinity_changeable  s2    



z$SchedulerPlugin._affinity_changeablec             C   s\   y| j | }W n( tk
r6   t| j}|| j |< Y nX |jd krX|jd krX||_||_d S )N)r{   r   r   r   r	   r
   )r   r9   r	   r
   paramsr   r   r   _store_orig_process_rt  s    
z&SchedulerPlugin._store_orig_process_rtc             C   s   d}|d kr|d kr|S y:| j |\}}|d kr4|}| j||| | j||| W nt ttfk
r } zTt|dr|jtjkrtj	d|  || j
kr| j
|= d}ntjd||f  W Y d d }~X nX |S )NTr   z=Failed to read scheduler policy of PID %d, the task vanished.FzcRefusing to set scheduler and priority of PID %d, reading original scheduling parameters failed: %s)r   r   r   r   r   r   r   r   ri   r   r{   r   )r   r9   r=   r>   contZ
prev_schedZ	prev_prior   r   r   r   _tune_process_rt  s&    
z SchedulerPlugin._tune_process_rtc             C   s   t |d d dkS )Nrk   zcgroup.)r   )r   r   r   r   r   _is_cgroup_affinity  s    z#SchedulerPlugin._is_cgroup_affinityFc             C   sb   y| j | }W n( tk
r6   t| j}|| j |< Y nX |jd kr^|jd kr^|rX||_n||_d S )N)r{   r   r   r   r   r   )r   r9   r   	is_cgroupr   r   r   r   _store_orig_process_affinity  s    
z,SchedulerPlugin._store_orig_process_affinityc             C   sp   xj| j jdtjt|df ddjdD ]@}y&|jdd dd  }|dkrP|S d	S  tk
rf   Y q(X q(W d	S )
Nz%s/%s/%sr   T)no_error
z:cpuset:r   rO   r   )r   	read_filerR   ZPROCFS_MOUNT_POINTr   split
IndexError)r   r9   lr   r   r   r   _get_cgroup_affinity  s    ,
z$SchedulerPlugin._get_cgroup_affinityc             C   sB   | j |}| j}|dkr$d||f }| jjd| t|dd d S )Nr   z%s/%sz%s/tasksT)r   )rm   _cgroup_mount_pointr   write_to_filer   )r   r9   r   pathr   r   r   _set_cgroup  s
    
zSchedulerPlugin._set_cgroupc             C   s,   |dd  }t |t o"t|dk}||fS )Nrk   r   )r   listrl   )r   r   r   r   r   r   _parse_cgroup_affinity  s    z&SchedulerPlugin._parse_cgroup_affinityc       	      C   s   d}|d kr|S yd| j |\}}|r<| j|}| j|| n(| j|}|rX| j|||}| j|| | j||| W nt ttfk
r } zTt	|dr|j
t
jkrtjd|  || jkr| j|= d}ntjd||f  W Y d d }~X nX |S )NTr   z5Failed to read affinity of PID %d, the task vanished.FzLRefusing to set CPU affinity of PID %d, reading original affinity failed: %s)r   r   r   _get_affinity_get_intersect_affinity_set_affinityr   r   r   r   r   r   ri   r   r{   r   )	r   r9   r   	intersectr   r   r   prev_affinityr   r   r   r   _tune_process_affinity  s4    


z&SchedulerPlugin._tune_process_affinityc             C   sF   | j |||}|sd S | j||}| s2|| jkr6d S || j| _d S )N)r   r   r{   r   )r   r9   r   r=   r>   r   r   r   r   r   _tune_process  s    zSchedulerPlugin._tune_processc             C   sf   | j j|}|d kr.|dkr.tjd|  dS yt|}W n" tk
r\   tjd|  dS X ||fS )Nr   z>Invalid scheduler: %s. Scheduler and priority will be ignored.z=Invalid priority: %s. Scheduler and priority will be ignored.)NN)NN)rb   r6   ri   r   rT   rg   )r   r5   Zstr_priorityr	   r
   r   r   r   _convert_sched_params  s    z%SchedulerPlugin._convert_sched_paramsc             C   sD   |dkrd }n2| j |r|}n"| jj|}|s@tjd|  d }|S )Nr   z)Invalid affinity: %s. It will be ignored.)r   r   hex2cpulistri   r   )r   Zstr_affinityr   r   r   r   _convert_affinity+  s    
z!SchedulerPlugin._convert_affinityc             C   s6   |\}}}}}| j ||\}}| j|}|||||fS )N)r   r   )r   vals	rule_prior	   r
   r   regexr   r   r   _convert_sched_cfg8  s
    
z"SchedulerPlugin._convert_sched_cfgc             C   s   d| j |f }ytj|tj W n4 tk
rT } ztjd||f  W Y d d }~X nX | jj	d|df | jj
d| j df ddddstjd|  d S )Nz%s/%sz Unable to create cgroup '%s': %szcpuset.memsT)r   z3Unable to initialize 'cpuset.mems ' for cgroup '%s')r   r)   mkdirrR   DEF_CGROUP_MODEr   ri   r   r   r   r   )r   r   r   r   r   r   r   _cgroup_create_group?  s    $z$SchedulerPlugin._cgroup_create_groupc             C   s@   | j d k	r"| j | jkr"| j| j  x| jD ]}| j| q*W d S )N)r   r   r   )r   cgr   r   r   _cgroup_initialize_groupsJ  s    z)SchedulerPlugin._cgroup_initialize_groupsc             C   s   t jd ytj| jtj W n0 tk
rN } zt jd|  W Y d d }~X nX | j	j
dddddd| jg\}}|dkrt jd	| j  d S )
NzInitializing cgroups settingsz'Unable to create cgroup mount point: %sZmountz-tr   z-oZcpusetr   zUnable to mount '%s')ri   r   r)   makedirsr   rR   r   r   r   r   execute)r   r   retoutr   r   r   _cgroup_initializeP  s    
  z"SchedulerPlugin._cgroup_initializec             C   sH   yt j| W n4 tk
rB } ztjd||f  W Y d d }~X nX d S )Nz#Unable to remove directory '%s': %s)r)   rmdirr   ri   r   )r   r   r   r   r   r   _remove_dirZ  s    zSchedulerPlugin._remove_dirc             C   sX   x&t | jD ]}| jd| j|f  qW | jd k	rT| j| jkrT| jd| j| jf  d S )Nz%s/%s)reversedr   r   r   r   )r   r   r   r   r   _cgroup_finalize_groups`  s    z'SchedulerPlugin._cgroup_finalize_groupsc             C   sl   t jd | jjd| jg\}}|dkr<t jd| j  dS | j| j tjj	| j}|dkrh| j| d S )NzRemoving cgroups settingsZumountr   zUnable to umount '%s'Fr   )
ri   r   r   r   r   r   r   r)   r   dirname)r   r   r   dr   r   r   _cgroup_finalizef  s    
z SchedulerPlugin._cgroup_finalizec             C   s   |dkrt jd||f  nt jd|  d S d| j|df }|r~| jj|dddj }|dkrl|| j|< nt jd	|  d S | jj||dd
st jd||f  d S )NrO   z$Setting cgroup '%s' affinity to '%s'z.Skipping cgroup '%s', empty affinity requestedz%s/%s/%szcpuset.cpusERRT)err_retr   zIRefusing to set affinity of cgroup '%s', reading original affinity failed)r   z+Unable to set affinity '%s' for cgroup '%s')	ri   r   r   r   r   stripr   r   r   )r   r   r   backupr   Zorig_affinityr   r   r   _cgroup_set_affinity_oneq  s    z(SchedulerPlugin._cgroup_set_affinity_onec             C   s~   | j r
d S tjd | jd k	rH| jd k	rH| j| jkrH| j| j| jdd x*| jj D ]}| j|d |d dd qTW d| _ d S )NzSetting cgroups affinitiesT)r  r   r   )r   ri   r   r   r   r   r	  r0   )r   r   r   r   r   _cgroup_set_affinity  s    
 z$SchedulerPlugin._cgroup_set_affinityc             C   s6   t jd x&| jj D ]}| j|d |d  qW d S )NzRestoring cgroups affinitiesr   r   )ri   r   r   r0   r	  )r   r   r   r   r   _cgroup_restore_affinity  s    
z(SchedulerPlugin._cgroup_restore_affinityc          #      sn  j j|jd _jjj j|jd dk_jjj j|jd dk_jj j|jd _	jr|j
  jsjrj  ttj| j  yj }W n2 ttfk
r } ztjd|  d S d }~X nX dd |jj D }fd	d|D }t|d
d d}t }i |_x|D ]\\} ytjW n< tjk
r } ztjdt  w0W Y d d }~X nX fdd|j D }t fdd|D }	|j|	 tjddt g|j< q0W x4|j D ](\}
\} j|
|  qW j j!j"j# j$rj|j%rjt&j'j(|gd|_)|j)j*  d S )Nr   r   1r   r   zIerror applying tuning, cannot get information about running processes: %sc             S   s$   g | ]\}}|t |jd dfqS ):   )r   r   )r*   rp   r   r   r   r   rq     s    z:SchedulerPlugin._instance_apply_static.<locals>.<listcomp>c                s6   g | ].\}}t jd |rt|dkr| j|fqS )zgroup\.   )rematchrl   r   )r*   rp   r   )r   r   r   rq     s   c             S   s   | d d S )Nr   r   r   )Zoption_valsr   r   r   <lambda>  s    z8SchedulerPlugin._instance_apply_static.<locals>.<lambda>)keyz(error compiling regular expression: '%s'c                s(   g | ] \}}t j |d k	r||fqS )N)r  search)r*   r9   r   )r%   r   r   rq     s    c          	      s$   g | ]\}}|| ffqS r   r   )r*   r9   r   )r   rp   r
   r   r	   r   r   rq     s   z(?<!\\)\((?!\?)z(?:)targetargs)+rn   ro   r   r   r   rV   _cgroup_mount_point_init_cgroup_groups_initrm   r   r   r   rQ   rN   _instance_apply_staticr
  r   r   r   ri   r   r   r0   sortedr.   _sched_lookupr  compiler   updatesubr   rz   setr^   r{   rS   ry   r   ZThread_thread_code_threadstart)r   r   r   r   Z	sched_cfgZbufZ	sched_allr   r   r=   r9   r   )re   )r   rp   r
   r%   r   r	   r   r   r    s^    





z&SchedulerPlugin._instance_apply_staticc             C   s   y| j  }W n2 ttfk
r> } ztjd|  d S d }~X nX x| jj D ]x\}}||ksL|| |jkrlqL|jd k	r|j	d k	r| j
||j|j	 |jd k	r| j||j qL|jd k	rL| j||j qLW i | _| jj| j d S )NzKerror unapplying tuning, cannot get information about running processes: %s)r   r   r   ri   r   r{   r0   r   r	   r
   r   r   r   r   r   rz   r~   r^   )r   r   r   r9   Zorig_paramsr   r   r   r}     s&    




z$SchedulerPlugin._restore_ps_affinityc             C   s   t tj}d}xr|dkr|dkr| jjd| j|df ddd}|dkrvx.|jdD ] }| jjd	| jdf |dd
 qRW |d8 }qW |dkrtj	d|  d S )N rO   r   z%s/%s/%sZtasksT)r  r   r   z%s/%s)r   r   z(Unable to cleanup tasks from cgroup '%s')rO   r#  )
rT   rR   ZCGROUP_CLEANUP_TASKS_RETRYr   r   r   r   r   ri   r   )r   r   Zcntdatar   r   r   r   _cgroup_cleanup_tasks_one  s    

 z)SchedulerPlugin._cgroup_cleanup_tasks_onec             C   s@   | j d k	r"| j | jkr"| j| j  x| jD ]}| j| q*W d S )N)r   r   r%  )r   r   r   r   r   _cgroup_cleanup_tasks  s    z%SchedulerPlugin._cgroup_cleanup_tasksc                sp   t t| j|| | jr2|jr2|jj  |jj  | j	  | j
  | j  | jsV| jr^| j  | jrl| j  d S )N)rQ   rN   _instance_unapply_staticrS   ry   r   r  r!  joinr}   r  r&  r  r  r  r  )r   r   Zrollback)re   r   r   r'    s    

z(SchedulerPlugin._instance_unapply_staticc             C   s   t jd|  d| j|df }| jj|ddd}|dkr<dS | jj| jj|}| jj| jj|}d| }||krt jtj	||f  dS t j
tj|||f  dS d S )	NzVerifying cgroup '%s' affinityz%s/%s/%szcpuset.cpusr  T)r  r   zcgroup '%s' affinityF)ri   r   r   r   r   cpulist2stringZcpulist_packr|   rR   STR_VERIFY_PROFILE_VALUE_OKr   STR_VERIFY_PROFILE_VALUE_FAIL)r   r   r   r   current_affinityZaffinity_descriptionr   r   r   _cgroup_verify_affinity_one  s     
z+SchedulerPlugin._cgroup_verify_affinity_onec             C   sr   t jd d}| jd k	rB| jd k	rB| j| jkrB|o@| j| j| j}x*| jj D ]}|oh| j|d |d }qNW |S )NzVeryfying cgroups affinitiesTr   r   )ri   r   r   r   r   r-  r0   )r   r   r   r   r   r   _cgroup_verify_affinity  s    
 z'SchedulerPlugin._cgroup_verify_affinityc                s$   t t| j|||}| j }|o"|S )N)rQ   rN   _instance_verify_staticr.  )r   r   ignore_missingZdevicesZret1Zret2)re   r   r   r/    s    z'SchedulerPlugin._instance_verify_staticc       
      C   s   y| j |}W n^ ttfk
rl } z>|jtjks<|jtjkrLtjd|  ntjd||f  d S d }~X nX | j	j
|j||}|d k	r|| jkrtjd||t|f  |\}}}	| j|||||	 | jj| j| j d S )Nz3Failed to get cmdline of PID %d, the task vanished.z#Failed to get cmdline of PID %d: %sz-tuning new process '%s' with PID '%d' by '%s')r   r   r   r   r   r   ri   r   r   r   Z	re_lookupr  r{   r   r   rz   r  r^   )
r   r   r9   r%   r   r   vr=   r>   r   r   r   r   _add_pid$  s$    


zSchedulerPlugin._add_pidc             C   s6   || j kr2| j |= tjd|  | jj| j| j  d S )Nz)removed PID %d from the rollback database)r{   ri   r   rz   r  r^   )r   r   r9   r   r   r   _remove_pid9  s
    

zSchedulerPlugin._remove_pidc       	      C   s   | j j|j}tj }|jj }x|D ]}|j| q&W x|jj	 st
|j| jd dkr:|jj	  r:d}x|rd}xt| jD ]j}|jj|}|r~d}|jtjks| jr|jtjkr| j|t|j| q~|jtjkr~| j|t|j q~W qnW q:W d S )Ni  r   TF)r   Zre_lookup_compiler  selectpollra   r   registerr   Zis_setrl   rU   r]   Zread_on_cpurt   r\   ZRECORD_COMM_perf_process_fork_valueZRECORD_FORKr2  rT   tidZRECORD_EXITr3  )	r   r   r%   r5  Zfdsr   Zread_eventsZcpuZeventr   r   r   r   @  s&    

$zSchedulerPlugin._thread_coder   )
per_devicec             C   s:   |rd S |r6|d k	r6dj dd tjdt|D | _d S )N|c             S   s   g | ]}d | qS )z(%s)r   )r*   r1  r   r   r   rq   _  s    z8SchedulerPlugin._cgroup_ps_blacklist.<locals>.<listcomp>z(?<!\\);)r(  r  r   r   r[   )r   enablingr   verifyr0  r   r   r   _cgroup_ps_blacklistY  s    z$SchedulerPlugin._cgroup_ps_blacklistr   c             C   s:   |rd S |r6|d k	r6dj dd tjdt|D | _d S )Nr:  c             S   s   g | ]}d | qS )z(%s)r   )r*   r1  r   r   r   rq   g  s    z1SchedulerPlugin._ps_whitelist.<locals>.<listcomp>z(?<!\\);)r(  r  r   r   rY   )r   r;  r   r<  r0  r   r   r   rY   a  s    zSchedulerPlugin._ps_whitelistr   c             C   s:   |rd S |r6|d k	r6dj dd tjdt|D | _d S )Nr:  c             S   s   g | ]}d | qS )z(%s)r   )r*   r1  r   r   r   rq   o  s    z1SchedulerPlugin._ps_blacklist.<locals>.<listcomp>z(?<!\\);)r(  r  r   r   rZ   )r   r;  r   r<  r0  r   r   r   rZ   i  s    zSchedulerPlugin._ps_blacklistr   c             C   s*   |rd S |r&|d k	r&| j j|dk| _d S )Nr  )r   rV   r_   )r   r;  r   r<  r0  r   r   r   r_   q  s    zSchedulerPlugin._irq_processr   c             C   s6   |rd S |r2|d k	r2|dkr$|| _ n| jj|| _ d S )Nr   ignore)r   r>  )_default_irq_smp_affinity_valuer   cpulist_unpack)r   r;  r   r<  r0  r   r   r   _default_irq_smp_affinityy  s    z)SchedulerPlugin._default_irq_smp_affinityr   c             C   s*   |rd S |r&|d k	r&| j j|dk| _d S )Nr  )r   rV   r7  )r   r;  r   r<  r0  r   r   r   _perf_process_fork  s    z"SchedulerPlugin._perf_process_forkc             C   s"   | j j|}tjd||f  |S )NzRead affinity '%s' of PID %d)rb   rA   ri   r   )r   r9   resr   r   r   r     s    zSchedulerPlugin._get_affinityc             C   s   t jd||f  y| jj|| dS  ttfk
r } zXt|dr`|jtjkr`t jd|  n.| j	|}|dksz|d	krt j
d|||f  dS d }~X nX d S )
Nz'Setting CPU affinity of PID %d to '%s'.Tr   z4Failed to set affinity of PID %d, the task vanished.r   rf   z,Failed to set affinity of PID %d to '%s': %sFr   )ri   r   rb   rC   r   r   r   r   r   r   r   )r   r9   r   r   rC  r   r   r   r     s    

zSchedulerPlugin._set_affinityc             C   s"   t |jt |}|rt|S |S )N)r  intersectionr   )r   Z	affinity1Z	affinity2Z	affinity3Zaffr   r   r   r     s    z'SchedulerPlugin._get_intersect_affinityc       
         s>   fdd|D } j dkr. fdd|D } jdkrJ fdd|D }tdd |D }x|D ]}y j|| }W nb ttfk
r } zB|jtjks|jtjkrt	j
d|  nt	jd||f  wbW Y d d }~X nX  j||d	d
}	|	sqb| jkr
| j| _| rbd|| krb j|| d j |d	 qbW d S )Nc                s(   g | ] }t j j j|d k	r|qS )N)r  r  rY   _get_stat_comm)r*   r1  )r   r   r   rq     s    
z9SchedulerPlugin._set_all_obj_affinity.<locals>.<listcomp>rO   c                s(   g | ] }t j j j|d kr|qS )N)r  r  rZ   rE  )r*   r1  )r   r   r   rq     s    
c                s(   g | ] }t j j j|d kr|qS )N)r  r  r[   _get_stat_cgroup)r*   r1  )r   r   r   rq     s    
c             S   s   g | ]}|j |fqS r   )r9   )r*   r1  r   r   r   rq     s    z3Failed to get cmdline of PID %d, the task vanished.zARefusing to set affinity of PID %d, failed to get its cmdline: %sT)r   rx   )rZ   r[   r.   r   r   r   r   r   r   ri   r   r   r   r{   r   _set_all_obj_affinityr2   )
r   Zobjsr   rx   ZpslZpsdr9   r   r   r   r   )r   r   rG    s6    



z%SchedulerPlugin._set_all_obj_affinityc             C   s(   y|d S  t ttfk
r"   dS X d S )NZcgroupsrO   )r   r   r   )r   r&   r   r   r   rF    s    z SchedulerPlugin._get_stat_cgroupc             C   s,   y|d d S  t ttfk
r&   dS X d S )Nr   rv   rO   )r   r   r   )r   r&   r   r   r   rE    s    zSchedulerPlugin._get_stat_commc             C   s`   y&t j }|j  | j|j |d W n4 ttfk
rZ } ztjd|  W Y d d }~X nX d S )NFzIerror applying tuning, cannot get information about running processes: %s)	r   r   r   rG  r2   r   r   ri   r   )r   r   r   r   r   r   r   _set_ps_affinity  s    z SchedulerPlugin._set_ps_affinityc             C   s   yJ| j j|}tjd||f  d| }t|d}|j| W d Q R X dS  ttfk
r } zLt|dr|j	t	j
kr| rtjd|  d
S tjd|||f  dS W Y d d }~X nX d S )Nz&Setting SMP affinity of IRQ %s to '%s'z/proc/irq/%s/smp_affinitywr   r   z/Setting SMP affinity of IRQ %s is not supportedrf   z0Failed to set SMP affinity of IRQ %s to '%s': %sr   r   r   )r   cpulist2hexri   r   r   writer   r   r   r   ZEIOr   )r   rP   r   Z	restoringaffinity_hexfilenamer#   r   r   r   r   _set_irq_affinity  s"    z!SchedulerPlugin._set_irq_affinityc             C   s|   y>| j j|}tjd|  tdd}|j| W d Q R X W n8 ttfk
rv } ztjd||f  W Y d d }~X nX d S )Nz(Setting default SMP IRQ affinity to '%s'z/proc/irq/default_smp_affinityrI  z2Failed to set default SMP IRQ affinity to '%s': %s)	r   rJ  ri   r   r   rK  r   r   r   )r   r   rL  r#   r   r   r   r   _set_default_irq_affinity  s    z)SchedulerPlugin._set_default_irq_affinityc       	      C   s"  t  }tj }x|j D ]}y"|| d }tjd||f  W n tk
rT   wY nX | j|||}t|t|krvq| j	||d}|dkr||j
|< q|d	kr|jj| qW | jjd}| jj|}| jdkr| j|||}n| jdkr| j}| jdkr| j| ||_| jj| j| d S )
Nr   zRead affinity of IRQ '%s': '%s'Fr   rf   z/proc/irq/default_smp_affinityr   r>  r   )r   r   
interruptsr   ri   r   r   r   r  rN  r   r   appendr   r   r   r?  rO  r   rz   r`   )	r   r   irq_originalr   rP   r   r   rC  Zprev_affinity_hexr   r   r   _set_all_irq_affinity
  s6    


z%SchedulerPlugin._set_all_irq_affinityc             C   sn   | j j| jd }|d krd S x$|jj D ]\}}| j||d q(W | jdkr\|j}| j| | j j	| j d S )NTr>  )
rz   r4   r`   r   r0   rN  r?  r   rO  r~   )r   rR  rP   r   r   r   r   _restore_all_irq_affinity)  s    

z)SchedulerPlugin._restore_all_irq_affinityc             C   sF   t |jt |}|r,tjtj||f  ntjtj|||f  |S )N)r  issubsetri   r|   rR   r*  r   r+  )r   irq_descriptioncorrect_affinityr,  rC  r   r   r   _verify_irq_affinity4  s    
z$SchedulerPlugin._verify_irq_affinityc             C   s   | j j| jd }tj }d}x|j D ]}||jkrR|rRd| }tjt	j
|  q&y<|| d }tjd||f  d| }	| j|	||sd}W q& tk
r   w&Y q&X q&W | jjd}
| jj|
}| jdkr| jd	|| jd
kr|n| j rd}|S )NTz-IRQ %s does not support changing SMP affinityr   z#Read SMP affinity of IRQ '%s': '%s'zSMP affinity of IRQ %sFz/proc/irq/default_smp_affinityr>  zdefault IRQ SMP affinityr   )rz   r4   r`   r   rP  r   r   ri   r|   rR   Z STR_VERIFY_PROFILE_VALUE_MISSINGr   rX  r   r   r   r   r?  )r   rW  r0  rR  r   rC  rP   descriptionr,  rV  Zcurrent_affinity_hexr   r   r   _verify_all_irq_affinity@  s8    
z(SchedulerPlugin._verify_all_irq_affinityr   
   )r9  r
   c       
      C   s   d }d | _ |d k	rrt| jj|}t| j}|j|rRt|| }| jj|| _ n | jj| j}tj	d||f  |sz|r|d krd S |r| j
r| j||S dS |r| jr| j  d| j }	n|}	| j|	 | j
r| j| n| j
r| j  d S )NzJInvalid isolated_cores specified, '%s' does not match available cores '%s'Tz	cgroup.%s)r   r  r   r@  r]   rU  r   r)  ri   r   r_   rZ  r   r
  rH  rS  rT  )
r   r;  r   r<  r0  r   isolatedZpresentZstr_cpusZps_affinityr   r   r   _isolated_cores_  s6    


zSchedulerPlugin._isolated_coresc             C   s   d|||f }| j j|}|r"|S d||f }tjj|sv|dkrPd||f }nd|||f }d| }| jd krvd| _|| j |< |S )Nz%s_%s_%sz/proc/sys/kernel/%s_%srO   z%s/%sz%s/%s/%sz/sys/kernel/debug/%sT)rX   r4   r)   r   existsrW   )r   prefix	namespaceknobr  r   r   r   r   _get_sched_knob_path  s    

z$SchedulerPlugin._get_sched_knob_pathc             C   sJ   | j j| j|||d d}|d krFtjd|  | jrFtjd d| _|S )N)r  zError reading '%s'zUThis may not work with Secure Boot or kernel_lockdown (this hint is logged only once)F)r   r   rb  ri   r   rW   )r   r_  r`  ra  r$  r   r   r   _get_sched_knob  s    
zSchedulerPlugin._get_sched_knobc             C   sN   |d krd S |sJ| j j| j|||||r0tjgnddsJtjd||f  |S )NF)r   z Error writing value '%s' to '%s')r   r   rb  r   r   ri   r   )r   r_  r`  ra  r   simremover   r   r   _set_sched_knob  s    zSchedulerPlugin._set_sched_knobr   c             C   s   | j dddS )NrO   r=   min_granularity_ns)rc  )r   r   r   r   _get_sched_min_granularity_ns  s    z-SchedulerPlugin._get_sched_min_granularity_nsc             C   s   | j ddd|||S )NrO   r=   rg  )rf  )r   r   rd  re  r   r   r   _set_sched_min_granularity_ns  s    z-SchedulerPlugin._set_sched_min_granularity_nsr   c             C   s   | j dddS )NrO   r=   
latency_ns)rc  )r   r   r   r   _get_sched_latency_ns  s    z%SchedulerPlugin._get_sched_latency_nsc             C   s   | j ddd|||S )NrO   r=   rj  )rf  )r   r   rd  re  r   r   r   _set_sched_latency_ns  s    z%SchedulerPlugin._set_sched_latency_nsr   c             C   s   | j dddS )NrO   r=   wakeup_granularity_ns)rc  )r   r   r   r    _get_sched_wakeup_granularity_ns  s    z0SchedulerPlugin._get_sched_wakeup_granularity_nsc             C   s   | j ddd|||S )NrO   r=   rm  )rf  )r   r   rd  re  r   r   r    _set_sched_wakeup_granularity_ns  s    z0SchedulerPlugin._set_sched_wakeup_granularity_nsr   c             C   s   | j dddS )NrO   r=   tunable_scaling)rc  )r   r   r   r   _get_sched_tunable_scaling  s    z*SchedulerPlugin._get_sched_tunable_scalingc             C   s   | j ddd|||S )NrO   r=   rp  )rf  )r   r   rd  re  r   r   r   _set_sched_tunable_scaling  s    z*SchedulerPlugin._set_sched_tunable_scalingr   c             C   s   | j dddS )NrO   r=   migration_cost_ns)rc  )r   r   r   r   _get_sched_migration_cost_ns  s    z,SchedulerPlugin._get_sched_migration_cost_nsc             C   s   | j ddd|||S )NrO   r=   rs  )rf  )r   r   rd  re  r   r   r   _set_sched_migration_cost_ns  s    z,SchedulerPlugin._set_sched_migration_cost_nsr   c             C   s   | j dddS )NrO   r=   
nr_migrate)rc  )r   r   r   r   _get_sched_nr_migrate  s    z%SchedulerPlugin._get_sched_nr_migratec             C   s   | j ddd|||S )NrO   r=   rv  )rf  )r   r   rd  re  r   r   r   _set_sched_nr_migrate  s    z%SchedulerPlugin._set_sched_nr_migrater   c             C   s   | j dddS )Nr=   numa_balancingscan_delay_ms)rc  )r   r   r   r   !_get_numa_balancing_scan_delay_ms  s    z1SchedulerPlugin._get_numa_balancing_scan_delay_msc             C   s   | j ddd|||S )Nr=   ry  rz  )rf  )r   r   rd  re  r   r   r   !_set_numa_balancing_scan_delay_ms  s    z1SchedulerPlugin._set_numa_balancing_scan_delay_msr   c             C   s   | j dddS )Nr=   ry  scan_period_min_ms)rc  )r   r   r   r   &_get_numa_balancing_scan_period_min_ms  s    z6SchedulerPlugin._get_numa_balancing_scan_period_min_msc             C   s   | j ddd|||S )Nr=   ry  r}  )rf  )r   r   rd  re  r   r   r   &_set_numa_balancing_scan_period_min_ms  s    z6SchedulerPlugin._set_numa_balancing_scan_period_min_msr   c             C   s   | j dddS )Nr=   ry  scan_period_max_ms)rc  )r   r   r   r   &_get_numa_balancing_scan_period_max_ms  s    z6SchedulerPlugin._get_numa_balancing_scan_period_max_msc             C   s   | j ddd|||S )Nr=   ry  r  )rf  )r   r   rd  re  r   r   r   &_set_numa_balancing_scan_period_max_ms  s    z6SchedulerPlugin._set_numa_balancing_scan_period_max_msr   c             C   s   | j dddS )Nr=   ry  scan_size_mb)rc  )r   r   r   r    _get_numa_balancing_scan_size_mb  s    z0SchedulerPlugin._get_numa_balancing_scan_size_mbc             C   s   | j ddd|||S )Nr=   ry  r  )rf  )r   r   rd  re  r   r   r    _set_numa_balancing_scan_size_mb  s    z0SchedulerPlugin._set_numa_balancing_scan_size_mb)F)F)F)F)F)br   r   r   rK   r   rj   r   r   classmethodr   rm   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r	  r
  r  r  r}   r%  r&  rR   ZROLLBACK_SOFTr'  r-  r.  r/  r2  r3  r   Zcommand_customr=  rY   rZ   r_   rA  rB  r   r   r   rG  rF  rE  rH  rN  rO  rS  rT  rX  rZ  r]  rb  rc  rf  Zcommand_getrh  Zcommand_setri  rk  rl  rn  ro  rq  rr  rt  ru  rw  rx  r{  r|  r~  r  r  r  r  r  __classcell__r   r   )re   r   rN      s     (?



	


<	
"$	
	rN   ) rO   r   Z
decoratorsZ
tuned.logsZtunedr  
subprocessr   r\   r4  Ztuned.constsrR   r   Ztuned.utils.commandsr   r   r)   r   rh   r   rc   rM   Zlogsr4   ri   objectr   r   r   rL   ZPluginrN   r   r   r   r   <module>   s0   


/