Skip to content

Commit

Permalink
param: fix module param locks when !CONFIG_SYSFS.
Browse files Browse the repository at this point in the history
As Dan Streetman points out, the entire point of locking for is to
stop sysfs accesses, so they're elided entirely in the !SYSFS case.

Reported-by: Stephen Rothwell <[email protected]>
Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Jun 28, 2015
1 parent 38183b9 commit cf2fde7
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 5 deletions.
2 changes: 2 additions & 0 deletions include/linux/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,9 @@ struct module {
unsigned int num_syms;

/* Kernel parameters. */
#ifdef CONFIG_SYSFS
struct mutex param_lock;
#endif
struct kernel_param *kp;
unsigned int num_kp;

Expand Down
9 changes: 8 additions & 1 deletion kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -1820,6 +1820,10 @@ static void mod_sysfs_fini(struct module *mod)
mod_kobject_put(mod);
}

static void init_param_lock(struct module *mod)
{
mutex_init(&mod->param_lock);
}
#else /* !CONFIG_SYSFS */

static int mod_sysfs_setup(struct module *mod,
Expand All @@ -1842,6 +1846,9 @@ static void del_usage_links(struct module *mod)
{
}

static void init_param_lock(struct module *mod)
{
}
#endif /* CONFIG_SYSFS */

static void mod_sysfs_teardown(struct module *mod)
Expand Down Expand Up @@ -3442,7 +3449,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
if (err)
goto unlink_mod;

mutex_init(&mod->param_lock);
init_param_lock(mod);

/* Now we've got everything in the final locations, we can
* find optional sections. */
Expand Down
18 changes: 14 additions & 4 deletions kernel/params.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,22 @@
#include <linux/slab.h>
#include <linux/ctype.h>

#ifdef CONFIG_SYSFS
/* Protects all built-in parameters, modules use their own param_lock */
static DEFINE_MUTEX(param_lock);

/* Use the module's mutex, or if built-in use the built-in mutex */
#define KPARAM_MUTEX(mod) ((mod) ? &(mod)->param_lock : &param_lock)
#define KPARAM_IS_LOCKED(mod) mutex_is_locked(KPARAM_MUTEX(mod))

static inline void check_kparam_locked(struct module *mod)
{
BUG_ON(!mutex_is_locked(KPARAM_MUTEX(mod)));
}
#else
static inline void check_kparam_locked(struct module *mod)
{
}
#endif /* !CONFIG_SYSFS */

/* This just allows us to keep track of which parameters are kmalloced. */
struct kmalloced_param {
Expand Down Expand Up @@ -459,7 +469,7 @@ static int param_array(struct module *mod,
/* nul-terminate and parse */
save = val[len];
((char *)val)[len] = '\0';
BUG_ON(!KPARAM_IS_LOCKED(mod));
check_kparam_locked(mod);
ret = set(val, &kp);

if (ret != 0)
Expand Down Expand Up @@ -496,7 +506,7 @@ static int param_array_get(char *buffer, const struct kernel_param *kp)
if (i)
buffer[off++] = ',';
p.arg = arr->elem + arr->elemsize * i;
BUG_ON(!KPARAM_IS_LOCKED(p.mod));
check_kparam_locked(p.mod);
ret = arr->ops->get(buffer + off, &p);
if (ret < 0)
return ret;
Expand Down Expand Up @@ -616,6 +626,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
#define __modinit __init
#endif

#ifdef CONFIG_SYSFS
void kernel_param_lock(struct module *mod)
{
mutex_lock(KPARAM_MUTEX(mod));
Expand All @@ -626,7 +637,6 @@ void kernel_param_unlock(struct module *mod)
mutex_unlock(KPARAM_MUTEX(mod));
}

#ifdef CONFIG_SYSFS
EXPORT_SYMBOL(kernel_param_lock);
EXPORT_SYMBOL(kernel_param_unlock);

Expand Down

0 comments on commit cf2fde7

Please sign in to comment.