From 268214897d0d5e56506175bcdaf8392db8af155c Mon Sep 17 00:00:00 2001 From: Sha Fanghao Date: Tue, 7 Dec 2021 17:25:55 +0800 Subject: [PATCH 1/3] opencas.conf supports promotion-nhit, cleaning-alru and cleaning-acp parameters. Signed-off-by: Sha Fanghao --- utils/opencas.conf.5 | 2 +- utils/opencas.py | 162 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 1 deletion(-) diff --git a/utils/opencas.conf.5 b/utils/opencas.conf.5 index c70091ede..0c887b3b6 100644 --- a/utils/opencas.conf.5 +++ b/utils/opencas.conf.5 @@ -24,7 +24,7 @@ Cache device .br Cache mode {wt|wb|wa|pt|wo} .br -Extra fields (optional) ioclass_file=,cleaning_policy=,promotion_policy= +Extra fields (optional) ioclass_file=,cleaning_policy=,cleaning_acp_wake_up=<0-10000>,cleaning_acp_flush_max_buffers=<1-10000>,cleaning_alru_wake_up=<0-3600>,cleaning_alru_flush_max_buffers=<1-10000>,cleaning_alru_staleness_time=<1-3600>,cleaning_alru_activity_threshold=<0-1000000>,promotion_policy=,promotion_nhit_threshold=<2-1000>,promotion_trigger=<0-100> .RE .TP \fB[cores]\fR Cores configuration. Following columns are required: diff --git a/utils/opencas.py b/utils/opencas.py index a2c6f555a..666c23f52 100644 --- a/utils/opencas.py +++ b/utils/opencas.py @@ -244,8 +244,24 @@ def validate_parameter(self, param_name, param_value): raise ValueError('Invalid path to io_class file') elif param_name == 'cleaning_policy': self.check_cleaning_policy_valid(param_value) + elif param_name == 'cleaning_acp_wake_up': + self.check_cleaning_acp_wake_up_valid(int(param_value)) + elif param_name == 'cleaning_acp_flush_max_buffers': + self.check_cleaning_acp_flush_max_buffers_valid(int(param_value)) + elif param_name == 'cleaning_alru_wake_up': + self.check_cleaning_alru_wake_up_valid(int(param_value)) + elif param_name == 'cleaning_alru_flush_max_buffers': + self.check_cleaning_alru_flush_max_buffers_valid(int(param_value)) + elif param_name == 'cleaning_alru_staleness_time': + self.check_cleaning_alru_staleness_time_valid(int(param_value)) + elif param_name == 'cleaning_alru_activity_threshold': + self.check_cleaning_alru_activity_threshold_valid(int(param_value)) elif param_name == 'promotion_policy': self.check_promotion_policy_valid(param_value) + elif param_name == 'promotion_nhit_threshold': + self.check_promotion_nhit_threshold_valid(int(param_value)) + elif param_name == 'promotion_nhit_trigger': + self.check_promotion_nhit_trigger_valid(int(param_value)) elif param_name == 'cache_line_size': self.check_cache_line_size_valid(param_value) elif param_name == "lazy_startup": @@ -280,6 +296,78 @@ def check_cleaning_policy_valid(self, cleaning_policy): if cleaning_policy.lower() not in ['acp', 'alru', 'nop']: raise ValueError(f'{cleaning_policy} is invalid cleaning policy name') + def check_cleaning_acp_wake_up_valid(self, number): + cleaning_policy = self.params.get('cleaning_policy') + if cleaning_policy != 'acp': + raise ValueError( + f'cleaning_acp_wake_up is invalid param for cleaning_policy {cleaning_policy}' + ) + + if not 0 <= number <= 10000: + raise ValueError( + f'{number} is invalid wake-up number for cleaning-acp' + ) + + def check_cleaning_acp_flush_max_buffers_valid(self, number): + cleaning_policy = self.params.get('cleaning_policy') + if cleaning_policy != 'acp': + raise ValueError( + f'cleaning_acp_flush_max_buffers is invalid param for cleaning_policy {cleaning_policy}' + ) + + if not 1 <= number <= 10000: + raise ValueError( + f'{number} is invalid flush-max-buffers number for cleaning-acp' + ) + + def check_cleaning_alru_wake_up_valid(self, number): + cleaning_policy = self.params.get('cleaning_policy') + if cleaning_policy != 'alru': + raise ValueError( + f'cleaning_alru_wake_up is invalid param for cleaning_policy {cleaning_policy}' + ) + + if not 0 <= number <= 3600: + raise ValueError( + f'{number} is invalid wake-up number for cleaning-alru' + ) + + def check_cleaning_alru_flush_max_buffers_valid(self, number): + cleaning_policy = self.params.get('cleaning_policy') + if cleaning_policy != 'alru': + raise ValueError( + f'cleaning_alru_flush_max_buffers is invalid param for cleaning_policy {cleaning_policy}' + ) + + if not 1 <= number <= 10000: + raise ValueError( + f'{number} is invalid flush-max-buffers number for cleaning-alru' + ) + + def check_cleaning_alru_staleness_time_valid(self, number): + cleaning_policy = self.params.get('cleaning_policy') + if cleaning_policy != 'alru': + raise ValueError( + f'cleaning_alru_staleness_time is invalid param for cleaning_policy {cleaning_policy}' + ) + + if not 1 <= number <= 3600: + raise ValueError( + f'{number} is invalid staleness-time number for cleaning-alru' + ) + + def check_cleaning_alru_activity_threshold_valid(self, number): + cleaning_policy = self.params.get('cleaning_policy') + if cleaning_policy != 'alru': + raise ValueError( + f'cleaning_alru_activity_threshold is invalid param for cleaning_policy {cleaning_policy}' + ) + + if not 0 <= number <= 1000000: + raise ValueError( + f'{number} is invalid activity-threshold number for cleaning-alru' + ) + def check_lazy_startup_valid(self, lazy_startup): if lazy_startup.lower() not in ["true", "false"]: raise ValueError('{0} is invalid lazy_startup value'.format(lazy_startup)) @@ -288,6 +376,30 @@ def check_promotion_policy_valid(self, promotion_policy): if promotion_policy.lower() not in ['always', 'nhit']: raise ValueError(f'{promotion_policy} is invalid promotion policy name') + def check_promotion_nhit_threshold_valid(self, number): + promotion_policy = self.params.get('promotion_policy') + if promotion_policy != 'nhit': + raise ValueError( + f'promotion_nhit_threshold is invalid param for promotion_policy {promotion_policy}' + ) + + if not 2 <= number <= 1000: + raise ValueError( + f'{number} is invalid threshold number for promotion-nhit' + ) + + def check_promotion_nhit_trigger_valid(self, number): + promotion_policy = self.params.get('promotion_policy') + if promotion_policy != 'nhit': + raise ValueError( + f'promotion_nhit_trigger is invalid param for promotion_policy {promotion_policy}' + ) + + if not 0 <= number <= 100: + raise ValueError( + f'{number} is invalid trigger number for promotion-nhit' + ) + def check_cache_line_size_valid(self, cache_line_size): if cache_line_size not in ['4', '8', '16', '32', '64']: raise ValueError(f'{cache_line_size} is invalid cache line size') @@ -559,10 +671,60 @@ def configure_cache(cache): casadm.set_param( "cleaning", cache_id=cache.cache_id, policy=cache.params["cleaning_policy"] ) + + if "cleaning_acp_wake_up" in cache.params: + casadm.set_param( + "cleaning-acp", cache_id=cache.cache_id, + wake_up=cache.params["cleaning_acp_wake_up"] + ) + + if "cleaning_acp_flush_max_buffers" in cache.params: + casadm.set_param( + "cleaning-acp", cache_id=cache.cache_id, + flush_max_buffers=cache.params["cleaning_acp_flush_max_buffers"] + ) + + if "cleaning_alru_wake_up" in cache.params: + casadm.set_param( + "cleaning-alru", cache_id=cache.cache_id, + wake_up=cache.params["cleaning_alru_wake_up"] + ) + + if "cleaning_alru_flush_max_buffers" in cache.params: + casadm.set_param( + "cleaning-alru", cache_id=cache.cache_id, + flush_max_buffers=cache.params["cleaning_alru_flush_max_buffers"] + ) + + if "cleaning_alru_staleness_time" in cache.params: + casadm.set_param( + "cleaning-alru", cache_id=cache.cache_id, + staleness_time=cache.params["cleaning_alru_staleness_time"] + ) + + if "cleaning_alru_activity_threshold" in cache.params: + casadm.set_param( + "cleaning-alru", cache_id=cache.cache_id, + activity_threshold=cache.params["cleaning_alru_activity_threshold"] + ) if "promotion_policy" in cache.params: casadm.set_param( "promotion", cache_id=cache.cache_id, policy=cache.params["promotion_policy"] ) + + if "promotion_nhit_threshold" in cache.params: + casadm.set_param( + "promotion-nhit", + cache_id=cache.cache_id, + threshold=cache.params["promotion_nhit_threshold"] + ) + + if "promotion_nhit_trigger" in cache.params: + casadm.set_param( + "promotion-nhit", + cache_id=cache.cache_id, + trigger=cache.params["promotion_nhit_trigger"] + ) if "ioclass_file" in cache.params: casadm.io_class_load_config( cache_id=cache.cache_id, ioclass_file=cache.params["ioclass_file"] From 20447c2a02d335b997da3a54a85c905cb81e8460 Mon Sep 17 00:00:00 2001 From: Sha Fanghao Date: Tue, 7 Dec 2021 19:16:25 +0800 Subject: [PATCH 2/3] opencas.conf supports seq-cutoff policy and threshold params. Signed-off-by: Sha Fanghao --- utils/casctl | 6 ++++++ utils/opencas.conf.5 | 2 +- utils/opencas.py | 42 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/utils/casctl b/utils/casctl index 9c74bd2df..e308ba726 100755 --- a/utils/casctl +++ b/utils/casctl @@ -64,6 +64,12 @@ def add_core_recursive(core, config): eprint('Unable to add core {0} to cache {1}. Reason:\n{2}' .format(core.device, core.cache_id, e.result.stderr)) with_error = True + try: + opencas.configure_core(core) + except opencas.casadm.CasadmError as e: + eprint('Unable to configure core {0} ({1}). Reason:\n{2}' + .format(core.device, core.cache_id, e.result.stderr)) + with_error = True return with_error def init(force): diff --git a/utils/opencas.conf.5 b/utils/opencas.conf.5 index 0c887b3b6..66b251ec9 100644 --- a/utils/opencas.conf.5 +++ b/utils/opencas.conf.5 @@ -36,7 +36,7 @@ Core ID <0-4095> .br Core device .br -Extra fields (optional) lazy_startup= +Extra fields (optional) lazy_startup=,seq_cutoff_policy=,seq_cutoff_threshold=<1-4194181> .RE .TP \fBNOTES\fR diff --git a/utils/opencas.py b/utils/opencas.py index 666c23f52..5ee6ff939 100644 --- a/utils/opencas.py +++ b/utils/opencas.py @@ -123,6 +123,18 @@ def set_param(cls, namespace, cache_id, **kwargs): return cls.run_cmd(cmd) + @classmethod + def set_core_param(cls, namespace, cache_id, core_id, **kwargs): + cmd = [cls.casadm_path, + '--set-param', '--name', namespace, + '--cache-id', str(cache_id), + '--core-id', str(core_id)] + + for param, value in kwargs.items(): + cmd += ['--'+param.replace('_', '-'), str(value)] + + return cls.run_cmd(cmd) + @classmethod def get_params(cls, namespace, cache_id, **kwargs): cmd = [cls.casadm_path, @@ -485,6 +497,10 @@ def validate_parameter(self, param_name, param_value): raise ValueError( f"{param_value} is invalid value for '{param_name}' core param" ) + elif param_name == "seq_cutoff_policy": + self.check_seq_cutoff_policy_valid(param_value) + elif param_name == "seq_cutoff_threshold": + self.check_seq_cutoff_threshold_valid(int(param_value)) else: raise ValueError(f"'{param_name}' is invalid core param name") @@ -502,6 +518,18 @@ def check_recursive(self): if int(device_cache_id) == self.cache_id: raise ValueError('Recursive configuration detected') + def check_seq_cutoff_policy_valid(self, seq_cutoff_policy): + if seq_cutoff_policy not in ['always', 'full', 'never']: + raise ValueError( + f'{seq_cutoff_policy} is invalid seq-cutoff policy name' + ) + + def check_seq_cutoff_threshold_valid(self, number): + if not 1 <= number <= 4194181: + raise ValueError( + f'{number} is invalid threshold number for seq-cutoff' + ) + def to_line(self): ret = f"{self.cache_id}\t{self.core_id}\t{self.device}" for i, (param, value) in enumerate(self.params.items()): @@ -730,7 +758,6 @@ def configure_cache(cache): cache_id=cache.cache_id, ioclass_file=cache.params["ioclass_file"] ) - def add_core(core, attach): casadm.add_core( device=core.device, @@ -738,6 +765,19 @@ def add_core(core, attach): core_id=core.core_id, try_add=attach) +def configure_core(core): + params = dict() + if "seq_cutoff_policy" in core.params: + params['policy'] = core.params["seq_cutoff_policy"] + + if "seq_cutoff_threshold" in core.params: + params['threshold'] = core.params["seq_cutoff_threshold"] + + if params: + casadm.set_core_param( + "seq-cutoff", cache_id=core.cache_id, core_id=core.core_id, **params + ) + # Another helper functions From b5c6e7a2862a6693f15dc0a55d975c515055dedd Mon Sep 17 00:00:00 2001 From: Sha Fanghao Date: Mon, 27 Dec 2021 21:19:12 +0800 Subject: [PATCH 3/3] PEP8 format. --- utils/opencas.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/utils/opencas.py b/utils/opencas.py index 5ee6ff939..d30497a6e 100644 --- a/utils/opencas.py +++ b/utils/opencas.py @@ -131,7 +131,7 @@ def set_core_param(cls, namespace, cache_id, core_id, **kwargs): '--core-id', str(core_id)] for param, value in kwargs.items(): - cmd += ['--'+param.replace('_', '-'), str(value)] + cmd += ['--' + param.replace('_', '-'), str(value)] return cls.run_cmd(cmd) @@ -324,7 +324,8 @@ def check_cleaning_acp_flush_max_buffers_valid(self, number): cleaning_policy = self.params.get('cleaning_policy') if cleaning_policy != 'acp': raise ValueError( - f'cleaning_acp_flush_max_buffers is invalid param for cleaning_policy {cleaning_policy}' + f'cleaning_acp_flush_max_buffers is invalid param for' + ' cleaning_policy {cleaning_policy}' ) if not 1 <= number <= 10000: @@ -348,7 +349,8 @@ def check_cleaning_alru_flush_max_buffers_valid(self, number): cleaning_policy = self.params.get('cleaning_policy') if cleaning_policy != 'alru': raise ValueError( - f'cleaning_alru_flush_max_buffers is invalid param for cleaning_policy {cleaning_policy}' + f'cleaning_alru_flush_max_buffers is invalid param for' + ' cleaning_policy {cleaning_policy}' ) if not 1 <= number <= 10000: @@ -360,7 +362,8 @@ def check_cleaning_alru_staleness_time_valid(self, number): cleaning_policy = self.params.get('cleaning_policy') if cleaning_policy != 'alru': raise ValueError( - f'cleaning_alru_staleness_time is invalid param for cleaning_policy {cleaning_policy}' + f'cleaning_alru_staleness_time is invalid param for' + ' cleaning_policy {cleaning_policy}' ) if not 1 <= number <= 3600: @@ -372,7 +375,8 @@ def check_cleaning_alru_activity_threshold_valid(self, number): cleaning_policy = self.params.get('cleaning_policy') if cleaning_policy != 'alru': raise ValueError( - f'cleaning_alru_activity_threshold is invalid param for cleaning_policy {cleaning_policy}' + f'cleaning_alru_activity_threshold is invalid param for' + ' cleaning_policy {cleaning_policy}' ) if not 0 <= number <= 1000000: @@ -392,7 +396,8 @@ def check_promotion_nhit_threshold_valid(self, number): promotion_policy = self.params.get('promotion_policy') if promotion_policy != 'nhit': raise ValueError( - f'promotion_nhit_threshold is invalid param for promotion_policy {promotion_policy}' + f'promotion_nhit_threshold is invalid param for' + ' promotion_policy {promotion_policy}' ) if not 2 <= number <= 1000: @@ -404,7 +409,8 @@ def check_promotion_nhit_trigger_valid(self, number): promotion_policy = self.params.get('promotion_policy') if promotion_policy != 'nhit': raise ValueError( - f'promotion_nhit_trigger is invalid param for promotion_policy {promotion_policy}' + f'promotion_nhit_trigger is invalid param for' + ' promotion_policy {promotion_policy}' ) if not 0 <= number <= 100: @@ -758,6 +764,7 @@ def configure_cache(cache): cache_id=cache.cache_id, ioclass_file=cache.params["ioclass_file"] ) + def add_core(core, attach): casadm.add_core( device=core.device, @@ -765,6 +772,7 @@ def add_core(core, attach): core_id=core.core_id, try_add=attach) + def configure_core(core): params = dict() if "seq_cutoff_policy" in core.params: @@ -778,6 +786,7 @@ def configure_core(core): "seq-cutoff", cache_id=core.cache_id, core_id=core.core_id, **params ) + # Another helper functions