From 36aa31efb4564013ba5d9829161a07228a6ed45f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Tue, 15 Aug 2017 12:54:35 +0200 Subject: [PATCH] Increase udev monitor buffer size, make it configurable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The udev monitor buffer size was increased to 1MB. Also, a new configuration option 'udev_buffer_size' can be specified in /etc/tuned/tuned-main.conf to set a different buffer size. Values such as '204800', '200KB', '200 KB' (with space) or '1 MB' are recognized. If no unit is specified, the number is taken as the number of bytes. Resolves: rhbz#1442306 Signed-off-by: Ondřej Lysoněk --- tuned-main.conf | 3 +++ tuned/consts.py | 3 +++ tuned/daemon/application.py | 3 ++- tuned/hardware/inventory.py | 6 +++++- tuned/utils/commands.py | 21 +++++++++++++++++++++ tuned/utils/global_config.py | 11 +++++++++++ 6 files changed, 45 insertions(+), 2 deletions(-) diff --git a/tuned-main.conf b/tuned-main.conf index 22cd64b..f0553e2 100644 --- a/tuned-main.conf +++ b/tuned-main.conf @@ -29,3 +29,6 @@ reapply_sysctl = 1 # Default priority assigned to instances default_instance_priority = 0 + +# Udev buffer size +udev_buffer_size = 1MB diff --git a/tuned/consts.py b/tuned/consts.py index aa3f38a..7ac6094 100644 --- a/tuned/consts.py +++ b/tuned/consts.py @@ -63,6 +63,7 @@ CFG_UPDATE_INTERVAL = "update_interval" CFG_RECOMMEND_COMMAND = "recommend_command" CFG_REAPPLY_SYSCTL = "reapply_sysctl" CFG_DEFAULT_INSTANCE_PRIORITY = "default_instance_priority" +CFG_UDEV_BUFFER_SIZE = "udev_buffer_size" # no_daemon mode CFG_DEF_DAEMON = True @@ -78,6 +79,8 @@ CFG_DEF_RECOMMEND_COMMAND = True CFG_DEF_REAPPLY_SYSCTL = True # default instance priority CFG_DEF_DEFAULT_INSTANCE_PRIORITY = 0 +# default pyudev.Monitor buffer size +CFG_DEF_UDEV_BUFFER_SIZE = 1024 * 1024 PATH_CPU_DMA_LATENCY = "/dev/cpu_dma_latency" diff --git a/tuned/daemon/application.py b/tuned/daemon/application.py index cd540d0..db2ba34 100644 --- a/tuned/daemon/application.py +++ b/tuned/daemon/application.py @@ -22,7 +22,8 @@ class Application(object): storage_factory = storage.Factory(storage_provider) monitors_repository = monitors.Repository() - hardware_inventory = hardware.Inventory() + udev_buffer_size = config.get_size("udev_buffer_size", consts.CFG_DEF_UDEV_BUFFER_SIZE) + hardware_inventory = hardware.Inventory(buffer_size=udev_buffer_size) device_matcher = hardware.DeviceMatcher() device_matcher_udev = hardware.DeviceMatcherUdev() plugin_instance_factory = plugins.instance.Factory() diff --git a/tuned/hardware/inventory.py b/tuned/hardware/inventory.py index 8c5117d..2293baa 100644 --- a/tuned/hardware/inventory.py +++ b/tuned/hardware/inventory.py @@ -1,5 +1,6 @@ import pyudev import tuned.logs +from tuned import consts __all__ = ["Inventory"] @@ -11,7 +12,7 @@ class Inventory(object): about related hardware events. """ - def __init__(self, udev_context=None, udev_monitor_cls=None, monitor_observer_factory=None): + def __init__(self, udev_context=None, udev_monitor_cls=None, monitor_observer_factory=None, buffer_size=None): if udev_context is not None: self._udev_context = udev_context else: @@ -20,6 +21,9 @@ class Inventory(object): if udev_monitor_cls is None: udev_monitor_cls = pyudev.Monitor self._udev_monitor = udev_monitor_cls.from_netlink(self._udev_context) + if buffer_size is None: + buffer_size = consts.CFG_DEF_UDEV_BUFFER_SIZE + self._udev_monitor.set_receive_buffer_size(buffer_size) if monitor_observer_factory is None: monitor_observer_factory = _MonitorObserverFactory() diff --git a/tuned/utils/commands.py b/tuned/utils/commands.py index a876a86..f4379a8 100644 --- a/tuned/utils/commands.py +++ b/tuned/utils/commands.py @@ -432,3 +432,24 @@ class commands: return terminate.wait(time, False) except: return terminate.wait(time) + + def get_size(self, s): + s = str(s).strip().upper() + for unit in ["KB", "MB", "GB", ""]: + unit_ix = s.rfind(unit) + if unit_ix == -1: + continue + try: + val = int(s[:unit_ix]) + u = s[unit_ix:] + if u == "KB": + val *= 1024 + elif u == "MB": + val *= 1024 * 1024 + elif u == "GB": + val *= 1024 * 1024 * 1024 + elif u != "": + val = None + return val + except ValueError: + return None diff --git a/tuned/utils/global_config.py b/tuned/utils/global_config.py index 600d226..a72d80f 100644 --- a/tuned/utils/global_config.py +++ b/tuned/utils/global_config.py @@ -47,3 +47,14 @@ class GlobalConfig(): def set(self, key, value): self._cfg[key] = value + + def get_size(self, key, default = None): + val = self.get(key) + if val is None: + return default + ret = self._cmd.get_size(val) + if ret is None: + log.error("Error parsing value '%s', using '%s'." %(val, default)) + return default + else: + return ret