aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2010-08-12 01:04:17 -0400
committerRusty Russell <rusty@rustcorp.com.au>2010-08-11 09:34:18 -0400
commite6df34a4429b77fdffb6e05adf263468a3dcda33 (patch)
tree0858a2cd08fffad89c05ab4a0d14ae832777f42b
parent6a841528d288ac420052f5c98fd426b0fcdc5b52 (diff)
param: add a free hook to kernel_param_ops.
This allows us to generalize the KPARAM_KMALLOCED flag, by calling a function on every parameter when a module is unloaded. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Reviewed-by: Takashi Iwai <tiwai@suse.de> Tested-by: Phil Carmody <ext-phil.2.carmody@nokia.com>
-rw-r--r--include/linux/moduleparam.h2
-rw-r--r--kernel/params.c17
2 files changed, 18 insertions, 1 deletions
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index 02e5090ce32f..9f51568f51c8 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -36,6 +36,8 @@ struct kernel_param_ops {
36 int (*set)(const char *val, const struct kernel_param *kp); 36 int (*set)(const char *val, const struct kernel_param *kp);
37 /* Returns length written or -errno. Buffer is 4k (ie. be short!) */ 37 /* Returns length written or -errno. Buffer is 4k (ie. be short!) */
38 int (*get)(char *buffer, const struct kernel_param *kp); 38 int (*get)(char *buffer, const struct kernel_param *kp);
39 /* Optional function to free kp->arg when module unloaded. */
40 void (*free)(void *arg);
39}; 41};
40 42
41/* Flag bits for kernel_param.flags */ 43/* Flag bits for kernel_param.flags */
diff --git a/kernel/params.c b/kernel/params.c
index a550698ae02d..458a09b886c4 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -399,9 +399,20 @@ static int param_array_get(char *buffer, const struct kernel_param *kp)
399 return off; 399 return off;
400} 400}
401 401
402static void param_array_free(void *arg)
403{
404 unsigned int i;
405 const struct kparam_array *arr = arg;
406
407 if (arr->ops->free)
408 for (i = 0; i < (arr->num ? *arr->num : arr->max); i++)
409 arr->ops->free(arr->elem + arr->elemsize * i);
410}
411
402struct kernel_param_ops param_array_ops = { 412struct kernel_param_ops param_array_ops = {
403 .set = param_array_set, 413 .set = param_array_set,
404 .get = param_array_get, 414 .get = param_array_get,
415 .free = param_array_free,
405}; 416};
406EXPORT_SYMBOL(param_array_ops); 417EXPORT_SYMBOL(param_array_ops);
407 418
@@ -634,7 +645,11 @@ void module_param_sysfs_remove(struct module *mod)
634 645
635void destroy_params(const struct kernel_param *params, unsigned num) 646void destroy_params(const struct kernel_param *params, unsigned num)
636{ 647{
637 /* FIXME: This should free kmalloced charp parameters. It doesn't. */ 648 unsigned int i;
649
650 for (i = 0; i < num; i++)
651 if (params[i].ops->free)
652 params[i].ops->free(params[i].arg);
638} 653}
639 654
640static void __init kernel_add_sysfs_param(const char *name, 655static void __init kernel_add_sysfs_param(const char *name,