diff --git a/lisa/_cli_tools/lisa_load_kmod.py b/lisa/_cli_tools/lisa_load_kmod.py index eade26171bcbfda9a979861813a302391d43a0ab..563b75bd4d3028a882066421eeb8bf85c4b3bd9b 100755 --- a/lisa/_cli_tools/lisa_load_kmod.py +++ b/lisa/_cli_tools/lisa_load_kmod.py @@ -37,6 +37,12 @@ def main(): action='append', help='Enable a specific module feature. Can be repeated. By default, the module will try to enable all features and will log in dmesg the ones that failed to enable' ), + 'feature-param': dict( + action='append', + metavar=('FEATURE_NAME', 'PARAM_NAME', 'PARAM_VALUE'), + nargs=3, + help='Set a feature parameter value.' + ), 'cmd': dict( nargs=argparse.REMAINDER, help='Load the module, run the given command then unload the module. If not command is provided, just load the module and exit.' @@ -65,23 +71,26 @@ def main(): def _main(args, target): logger = logging.getLogger('lisa-load-kmod') - - features = args.feature + features = args.feature or [] + features_params = args.feature_param or {} keep_loaded = not bool(args.cmd) cmd = args.cmd or [] if cmd and cmd[0] == '--': cmd = cmd[1:] - kmod_params = {} - if features is not None: - kmod_params['features'] = list(features) + features = { + feature: {} + for feature in features + } + for feature, param_name, param_value in features_params: + features.setdefault(feature, {})[param_name] = param_value kmod = target.get_kmod(LISADynamicKmod) pretty_events = ', '.join(kmod.defined_events) logger.info(f'Kernel module provides the following ftrace events: {pretty_events}') - _kmod_cm = kmod.run(kmod_params=kmod_params) + _kmod_cm = kmod.run(features=features) if keep_loaded: @contextlib.contextmanager diff --git a/lisa/_kmod.py b/lisa/_kmod.py index 00afd4d8f9ac774940d1f378af9926a4b750f9d2..a863629f7b143b331332689e3378ffb86c8bfa96 100644 --- a/lisa/_kmod.py +++ b/lisa/_kmod.py @@ -3463,4 +3463,26 @@ class LISADynamicKmod(FtraceDynamicKmod): else: return preinstalled_unsuitable() + + def install(self, features=None, **kwargs): + """ + Install and load the module on the target. + + :param features: Features to enable and associated parameters. + Top-level in the dict is feature names, nested dict is for parameters. + :type features: dict(str, dict(str, object)) or None + """ + features = features or {} + params = dict( + features=sorted(features.keys()), + **{ + f'{feature}___{name}': value + for feature, params in features.items() + for name, value in (params or {}).items() + } + ) + + return super().install(kmod_params=params, **kwargs) + + # vim :set tabstop=4 shiftwidth=4 expandtab textwidth=80 diff --git a/lisa/trace.py b/lisa/trace.py index 678e93fc4d1bf261292de3b5788913c15037ef15..e4d8d54d2c0554f6e4ba622f93d9140fbadf4499 100644 --- a/lisa/trace.py +++ b/lisa/trace.py @@ -7667,8 +7667,9 @@ class FtraceCollector(CollectorBase, Configurable): needed, functools.partial( kmod.run, - kmod_params={ - 'features': sorted(kmod._event_features(needed)) + features={ + feature: {} + for feature in sorted(kmod._event_features(needed)) } ) )