param: add a free hook to kernel_param_ops.
Rusty Russell [Thu, 12 Aug 2010 05:04:17 +0000 (23:04 -0600)]
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>

include/linux/moduleparam.h
kernel/params.c

index 02e5090..9f51568 100644 (file)
@@ -36,6 +36,8 @@ struct kernel_param_ops {
        int (*set)(const char *val, const struct kernel_param *kp);
        /* Returns length written or -errno.  Buffer is 4k (ie. be short!) */
        int (*get)(char *buffer, const struct kernel_param *kp);
+       /* Optional function to free kp->arg when module unloaded. */
+       void (*free)(void *arg);
 };
 
 /* Flag bits for kernel_param.flags */
index a550698..458a09b 100644 (file)
@@ -399,9 +399,20 @@ static int param_array_get(char *buffer, const struct kernel_param *kp)
        return off;
 }
 
+static void param_array_free(void *arg)
+{
+       unsigned int i;
+       const struct kparam_array *arr = arg;
+
+       if (arr->ops->free)
+               for (i = 0; i < (arr->num ? *arr->num : arr->max); i++)
+                       arr->ops->free(arr->elem + arr->elemsize * i);
+}
+
 struct kernel_param_ops param_array_ops = {
        .set = param_array_set,
        .get = param_array_get,
+       .free = param_array_free,
 };
 EXPORT_SYMBOL(param_array_ops);
 
@@ -634,7 +645,11 @@ void module_param_sysfs_remove(struct module *mod)
 
 void destroy_params(const struct kernel_param *params, unsigned num)
 {
-       /* FIXME: This should free kmalloced charp parameters.  It doesn't. */
+       unsigned int i;
+
+       for (i = 0; i < num; i++)
+               if (params[i].ops->free)
+                       params[i].ops->free(params[i].arg);
 }
 
 static void __init kernel_add_sysfs_param(const char *name,