Merge pull request #16 from olysonek/instance_priority_pr
Implement instance priority
This commit is contained in:
commit
9cf6c3f45c
6 changed files with 54 additions and 41 deletions
|
|
@ -26,3 +26,6 @@ recommend_command = 1
|
|||
# If enabled these sysctls will be re-appliead after Tuned sysctls are
|
||||
# applied, i.e. Tuned sysctls will not override system sysctls.
|
||||
reapply_sysctl = 1
|
||||
|
||||
# Default priority assigned to instances
|
||||
default_instance_priority = 0
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ CFG_SLEEP_INTERVAL = "sleep_interval"
|
|||
CFG_UPDATE_INTERVAL = "update_interval"
|
||||
CFG_RECOMMEND_COMMAND = "recommend_command"
|
||||
CFG_REAPPLY_SYSCTL = "reapply_sysctl"
|
||||
CFG_DEFAULT_INSTANCE_PRIORITY = "default_instance_priority"
|
||||
|
||||
# no_daemon mode
|
||||
CFG_DEF_DAEMON = True
|
||||
|
|
@ -69,6 +70,8 @@ CFG_DEF_UPDATE_INTERVAL = 10
|
|||
CFG_DEF_RECOMMEND_COMMAND = True
|
||||
# reapply system sysctl
|
||||
CFG_DEF_REAPPLY_SYSCTL = True
|
||||
# default instance priority
|
||||
CFG_DEF_DEFAULT_INSTANCE_PRIORITY = 0
|
||||
|
||||
PATH_CPU_DMA_LATENCY = "/dev/cpu_dma_latency"
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ class Application(object):
|
|||
log.info("dynamic tuning is globally disabled")
|
||||
|
||||
plugins_repository = plugins.Repository(monitors_repository, storage_factory, hardware_inventory, device_matcher, plugin_instance_factory, self.config, self.variables)
|
||||
unit_manager = units.Manager(plugins_repository, monitors_repository)
|
||||
def_instance_priority = int(self.config.get(consts.CFG_DEFAULT_INSTANCE_PRIORITY, consts.CFG_DEF_DEFAULT_INSTANCE_PRIORITY))
|
||||
unit_manager = units.Manager(plugins_repository, monitors_repository, def_instance_priority)
|
||||
|
||||
profile_factory = profiles.Factory()
|
||||
profile_merger = profiles.Merger()
|
||||
|
|
|
|||
|
|
@ -102,11 +102,10 @@ class Plugin(object):
|
|||
self._destroy_instance(instance)
|
||||
del self._instances[instance.name]
|
||||
|
||||
def initialize_instances(self):
|
||||
"""Initialize all created instances."""
|
||||
for (instance_name, instance) in self._instances.items():
|
||||
log.debug("initializing instance %s (%s)" % (instance_name, self.name))
|
||||
self._instance_init(instance)
|
||||
def initialize_instance(self, instance):
|
||||
"""Initialize an instance."""
|
||||
log.debug("initializing instance %s (%s)" % (instance.name, self.name))
|
||||
self._instance_init(instance)
|
||||
|
||||
def destroy_instances(self):
|
||||
"""Destroy all instances."""
|
||||
|
|
@ -140,21 +139,20 @@ class Plugin(object):
|
|||
def _get_matching_devices(self, instance, devices):
|
||||
return set(self._device_matcher.match_list(instance.devices_expression, devices))
|
||||
|
||||
def assign_free_devices(self):
|
||||
def assign_free_devices(self, instance):
|
||||
if not self._devices_supported():
|
||||
return
|
||||
|
||||
log.debug("assigning devices to all instances")
|
||||
for instance_name, instance in reversed(self._instances.items()):
|
||||
to_assign = self._get_matching_devices(instance, self._free_devices)
|
||||
instance.active = len(to_assign) > 0
|
||||
if not instance.active:
|
||||
log.warn("instance %s: no matching devices available" % instance_name)
|
||||
else:
|
||||
log.info("instance %s: assigning devices %s" % (instance_name, ", ".join(to_assign)))
|
||||
instance.devices.update(to_assign) # cannot use |=
|
||||
self._assigned_devices |= to_assign
|
||||
self._free_devices -= to_assign
|
||||
log.debug("assigning devices to instance %s" % instance.name)
|
||||
to_assign = self._get_matching_devices(instance, self._free_devices)
|
||||
instance.active = len(to_assign) > 0
|
||||
if not instance.active:
|
||||
log.warn("instance %s: no matching devices available" % instance.name)
|
||||
else:
|
||||
log.info("instance %s: assigning devices %s" % (instance.name, ", ".join(to_assign)))
|
||||
instance.devices.update(to_assign) # cannot use |=
|
||||
self._assigned_devices |= to_assign
|
||||
self._free_devices -= to_assign
|
||||
|
||||
def release_devices(self, instance):
|
||||
if not self._devices_supported():
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ class Instance(object):
|
|||
|
||||
# properties
|
||||
|
||||
@property
|
||||
def plugin(self):
|
||||
return self._plugin
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import collections
|
||||
import tuned.exceptions
|
||||
import tuned.logs
|
||||
import tuned.plugins.exceptions
|
||||
|
|
@ -11,10 +12,11 @@ class Manager(object):
|
|||
Manager creates plugin instances and keeps a track of them.
|
||||
"""
|
||||
|
||||
def __init__(self, plugins_repository, monitors_repository):
|
||||
def __init__(self, plugins_repository, monitors_repository, def_instance_priority):
|
||||
super(self.__class__, self).__init__()
|
||||
self._plugins_repository = plugins_repository
|
||||
self._monitors_repository = monitors_repository
|
||||
self._def_instance_priority = def_instance_priority
|
||||
self._instances = []
|
||||
self._plugins = []
|
||||
|
||||
|
|
@ -27,22 +29,25 @@ class Manager(object):
|
|||
return self._instances
|
||||
|
||||
def create(self, instances_config):
|
||||
|
||||
# group instances by plugin
|
||||
|
||||
instances_by_plugin = {}
|
||||
instance_info_list = []
|
||||
for instance_name, instance_info in instances_config.items():
|
||||
if not instance_info.enabled:
|
||||
log.debug("skipping disabled instance '%s'" % instance_name)
|
||||
continue
|
||||
instances_by_plugin.setdefault(instance_info.type, [])
|
||||
instances_by_plugin[instance_info.type].append(instance_info)
|
||||
instance_info.options.setdefault("instance_priority", self._def_instance_priority)
|
||||
instance_info.options["instance_priority"] = int(instance_info.options["instance_priority"])
|
||||
instance_info_list.append(instance_info)
|
||||
|
||||
# create all plugin instances at once
|
||||
instance_info_list.sort(key=lambda x: x.options["instance_priority"])
|
||||
plugins_by_name = collections.OrderedDict()
|
||||
for instance_info in instance_info_list:
|
||||
instance_info.options.pop("instance_priority")
|
||||
plugins_by_name[instance_info.type] = None
|
||||
|
||||
for plugin_name, instances_info in instances_by_plugin.items():
|
||||
for plugin_name, none in plugins_by_name.items():
|
||||
try:
|
||||
plugin = self._plugins_repository.create(plugin_name)
|
||||
plugins_by_name[plugin_name] = plugin
|
||||
self._plugins.append(plugin)
|
||||
except tuned.plugins.exceptions.NotSupportedPluginException:
|
||||
log.info("skipping plugin '%s', not supported on your system" % plugin_name)
|
||||
|
|
@ -52,21 +57,20 @@ class Manager(object):
|
|||
log.exception(e)
|
||||
continue
|
||||
|
||||
created_instances = []
|
||||
for instance_info in instances_info:
|
||||
log.debug("creating '%s' (%s)" % (instance_info.name, instance_info.type))
|
||||
new_instance = plugin.create_instance(instance_info.name, instance_info.devices, instance_info.options)
|
||||
created_instances.append(new_instance)
|
||||
|
||||
plugin.assign_free_devices()
|
||||
plugin.initialize_instances()
|
||||
|
||||
self._instances.extend(created_instances)
|
||||
for instance_info in instance_info_list:
|
||||
plugin = plugins_by_name[instance_info.type]
|
||||
if plugin is None:
|
||||
continue
|
||||
log.debug("creating '%s' (%s)" % (instance_info.name, instance_info.type))
|
||||
new_instance = plugin.create_instance(instance_info.name, instance_info.devices, instance_info.options)
|
||||
plugin.assign_free_devices(new_instance)
|
||||
plugin.initialize_instance(new_instance)
|
||||
self._instances.append(new_instance)
|
||||
|
||||
def destroy_all(self):
|
||||
for plugin in self._plugins:
|
||||
log.debug("cleaning plugin '%s'" % plugin.name)
|
||||
plugin.cleanup()
|
||||
for instance in self._instances:
|
||||
log.debug("destroying instance %s" % instance.name)
|
||||
instance.plugin.destroy_instance(instance)
|
||||
|
||||
del self._plugins[:]
|
||||
del self._instances[:]
|
||||
|
|
@ -93,5 +97,5 @@ class Manager(object):
|
|||
|
||||
# profile_switch is helper telling plugins whether the stop is due to profile switch
|
||||
def stop_tuning(self, profile_switch = False):
|
||||
for instance in self._instances:
|
||||
for instance in reversed(self._instances):
|
||||
instance.unapply_tuning(profile_switch)
|
||||
|
|
|
|||
Loading…
Reference in a new issue