Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

module: add extra argument for parse_params() callback

This adds an extra argument onto parse_params() to be used
as a way to make the unused callback a bit more useful and
generic by allowing the caller to pass on a data structure
of its choice. An example use case is to allow us to easily
make module parameters for every module which we will do
next.

@ parse @
identifier name, args, params, num, level_min, level_max;
identifier unknown, param, val, doing;
type s16;
@@
extern char *parse_args(const char *name,
char *args,
const struct kernel_param *params,
unsigned num,
s16 level_min,
s16 level_max,
+ void *arg,
int (*unknown)(char *param, char *val,
const char *doing
+ , void *arg
));

@ parse_mod @
identifier name, args, params, num, level_min, level_max;
identifier unknown, param, val, doing;
type s16;
@@
char *parse_args(const char *name,
char *args,
const struct kernel_param *params,
unsigned num,
s16 level_min,
s16 level_max,
+ void *arg,
int (*unknown)(char *param, char *val,
const char *doing
+ , void *arg
))
{
...
}

@ parse_args_found @
expression R, E1, E2, E3, E4, E5, E6;
identifier func;
@@

(
R =
parse_args(E1, E2, E3, E4, E5, E6,
+ NULL,
func);
|
R =
parse_args(E1, E2, E3, E4, E5, E6,
+ NULL,
&func);
|
R =
parse_args(E1, E2, E3, E4, E5, E6,
+ NULL,
NULL);
|
parse_args(E1, E2, E3, E4, E5, E6,
+ NULL,
func);
|
parse_args(E1, E2, E3, E4, E5, E6,
+ NULL,
&func);
|
parse_args(E1, E2, E3, E4, E5, E6,
+ NULL,
NULL);
)

@ parse_args_unused depends on parse_args_found @
identifier parse_args_found.func;
@@

int func(char *param, char *val, const char *unused
+ , void *arg
)
{
...
}

@ mod_unused depends on parse_args_found @
identifier parse_args_found.func;
expression A1, A2, A3;
@@

- func(A1, A2, A3);
+ func(A1, A2, A3, NULL);

Generated-by: Coccinelle SmPL
Cc: cocci@systeme.lip6.fr
Cc: Tejun Heo <tj@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Felipe Contreras <felipe.contreras@gmail.com>
Cc: Ewan Milne <emilne@redhat.com>
Cc: Jean Delvare <jdelvare@suse.de>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: linux-kernel@vger.kernel.org
Reviewed-by: Tejun Heo <tj@kernel.org>
Acked-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Luis R. Rodriguez and committed by
Greg Kroah-Hartman
ecc86170 6570a9a1

+32 -21
+2 -2
arch/powerpc/mm/hugetlbpage.c
··· 336 336 unsigned long gpage_npages[MMU_PAGE_COUNT]; 337 337 338 338 static int __init do_gpage_early_setup(char *param, char *val, 339 - const char *unused) 339 + const char *unused, void *arg) 340 340 { 341 341 static phys_addr_t size; 342 342 unsigned long npages; ··· 385 385 386 386 strlcpy(cmdline, boot_command_line, COMMAND_LINE_SIZE); 387 387 parse_args("hugetlb gpages", cmdline, NULL, 0, 0, 0, 388 - &do_gpage_early_setup); 388 + NULL, &do_gpage_early_setup); 389 389 390 390 /* 391 391 * Walk gpage list in reverse, allocating larger page sizes first.
+2 -1
include/linux/moduleparam.h
··· 357 357 unsigned num, 358 358 s16 level_min, 359 359 s16 level_max, 360 + void *arg, 360 361 int (*unknown)(char *param, char *val, 361 - const char *doing)); 362 + const char *doing, void *arg)); 362 363 363 364 /* Called by module remove. */ 364 365 #ifdef CONFIG_SYSFS
+15 -10
init/main.c
··· 235 235 early_param("loglevel", loglevel); 236 236 237 237 /* Change NUL term back to "=", to make "param" the whole string. */ 238 - static int __init repair_env_string(char *param, char *val, const char *unused) 238 + static int __init repair_env_string(char *param, char *val, 239 + const char *unused, void *arg) 239 240 { 240 241 if (val) { 241 242 /* param=val or param="val"? */ ··· 253 252 } 254 253 255 254 /* Anything after -- gets handed straight to init. */ 256 - static int __init set_init_arg(char *param, char *val, const char *unused) 255 + static int __init set_init_arg(char *param, char *val, 256 + const char *unused, void *arg) 257 257 { 258 258 unsigned int i; 259 259 260 260 if (panic_later) 261 261 return 0; 262 262 263 - repair_env_string(param, val, unused); 263 + repair_env_string(param, val, unused, NULL); 264 264 265 265 for (i = 0; argv_init[i]; i++) { 266 266 if (i == MAX_INIT_ARGS) { ··· 278 276 * Unknown boot options get handed to init, unless they look like 279 277 * unused parameters (modprobe will find them in /proc/cmdline). 280 278 */ 281 - static int __init unknown_bootoption(char *param, char *val, const char *unused) 279 + static int __init unknown_bootoption(char *param, char *val, 280 + const char *unused, void *arg) 282 281 { 283 - repair_env_string(param, val, unused); 282 + repair_env_string(param, val, unused, NULL); 284 283 285 284 /* Handle obsolete-style parameters */ 286 285 if (obsolete_checksetup(param)) ··· 413 410 } 414 411 415 412 /* Check for early params. */ 416 - static int __init do_early_param(char *param, char *val, const char *unused) 413 + static int __init do_early_param(char *param, char *val, 414 + const char *unused, void *arg) 417 415 { 418 416 const struct obs_kernel_param *p; 419 417 ··· 433 429 434 430 void __init parse_early_options(char *cmdline) 435 431 { 436 - parse_args("early options", cmdline, NULL, 0, 0, 0, do_early_param); 432 + parse_args("early options", cmdline, NULL, 0, 0, 0, NULL, 433 + do_early_param); 437 434 } 438 435 439 436 /* Arch code calls this early on, or if not, just before other parsing. */ ··· 540 535 after_dashes = parse_args("Booting kernel", 541 536 static_command_line, __start___param, 542 537 __stop___param - __start___param, 543 - -1, -1, &unknown_bootoption); 538 + -1, -1, NULL, &unknown_bootoption); 544 539 if (!IS_ERR_OR_NULL(after_dashes)) 545 540 parse_args("Setting init args", after_dashes, NULL, 0, -1, -1, 546 - set_init_arg); 541 + NULL, set_init_arg); 547 542 548 543 jump_label_init(); 549 544 ··· 852 847 initcall_command_line, __start___param, 853 848 __stop___param - __start___param, 854 849 level, level, 855 - &repair_env_string); 850 + NULL, &repair_env_string); 856 851 857 852 for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) 858 853 do_one_initcall(*fn);
+4 -2
kernel/module.c
··· 3237 3237 return err; 3238 3238 } 3239 3239 3240 - static int unknown_module_param_cb(char *param, char *val, const char *modname) 3240 + static int unknown_module_param_cb(char *param, char *val, const char *modname, 3241 + void *arg) 3241 3242 { 3242 3243 /* Check for magic 'dyndbg' arg */ 3243 3244 int ret = ddebug_dyndbg_module_param_cb(param, val, modname); ··· 3343 3342 3344 3343 /* Module is ready to execute: parsing args may do that. */ 3345 3344 after_dashes = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, 3346 - -32768, 32767, unknown_module_param_cb); 3345 + -32768, 32767, NULL, 3346 + unknown_module_param_cb); 3347 3347 if (IS_ERR(after_dashes)) { 3348 3348 err = PTR_ERR(after_dashes); 3349 3349 goto bug_cleanup;
+7 -4
kernel/params.c
··· 100 100 unsigned num_params, 101 101 s16 min_level, 102 102 s16 max_level, 103 + void *arg, 103 104 int (*handle_unknown)(char *param, char *val, 104 - const char *doing)) 105 + const char *doing, void *arg)) 105 106 { 106 107 unsigned int i; 107 108 int err; ··· 129 128 130 129 if (handle_unknown) { 131 130 pr_debug("doing %s: %s='%s'\n", doing, param, val); 132 - return handle_unknown(param, val, doing); 131 + return handle_unknown(param, val, doing, arg); 133 132 } 134 133 135 134 pr_debug("Unknown argument '%s'\n", param); ··· 195 194 unsigned num, 196 195 s16 min_level, 197 196 s16 max_level, 198 - int (*unknown)(char *param, char *val, const char *doing)) 197 + void *arg, 198 + int (*unknown)(char *param, char *val, 199 + const char *doing, void *arg)) 199 200 { 200 201 char *param, *val; 201 202 ··· 217 214 return args; 218 215 irq_was_disabled = irqs_disabled(); 219 216 ret = parse_one(param, val, doing, params, num, 220 - min_level, max_level, unknown); 217 + min_level, max_level, arg, unknown); 221 218 if (irq_was_disabled && !irqs_disabled()) 222 219 pr_warn("%s: option '%s' enabled irq's!\n", 223 220 doing, param);
+2 -2
lib/dynamic_debug.c
··· 887 887 888 888 /* handle both dyndbg and $module.dyndbg params at boot */ 889 889 static int ddebug_dyndbg_boot_param_cb(char *param, char *val, 890 - const char *unused) 890 + const char *unused, void *arg) 891 891 { 892 892 vpr_info("%s=\"%s\"\n", param, val); 893 893 return ddebug_dyndbg_param_cb(param, val, NULL, 0); ··· 1028 1028 */ 1029 1029 cmdline = kstrdup(saved_command_line, GFP_KERNEL); 1030 1030 parse_args("dyndbg params", cmdline, NULL, 1031 - 0, 0, 0, &ddebug_dyndbg_boot_param_cb); 1031 + 0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb); 1032 1032 kfree(cmdline); 1033 1033 return 0; 1034 1034