Skip to content

Commit

Permalink
Merge git://github.com/rustyrussell/linux
Browse files Browse the repository at this point in the history
Pull module and param updates from Rusty Russell:
 "I'm getting married next week, and then honeymoon until 6th May.  I'll
  be offline from next week, except to post the compulsory pictures if
  Alex shaves her head..."

I'm sure Rusty can take time off from his honeymoon if something comes
up. And here's the explanation about head shaving:

	http://baldalex.org/

in case you wondered and wanted to support another insane caper or
Rusty's involving shaving.

What *is* it with Rusty and shaving, anyway?

* git://github.com/rustyrussell/linux:
  module: Remove module size limit
  module: move __module_get and try_module_get() out of line.
  params: <level>_initcall-like kernel parameters
  module_param: remove support for bool parameters which are really int.
  module: add kernel param to force disable module load
  • Loading branch information
Linus Torvalds committed Mar 28, 2012
2 parents 683c5e8 + f946eeb commit d25413e
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 99 deletions.
2 changes: 2 additions & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1869,6 +1869,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
shutdown the other cpus. Instead use the REBOOT_VECTOR
irq.

nomodule Disable module load

nopat [X86] Disable PAT (page attribute table extension of
pagetables) support.

Expand Down
3 changes: 2 additions & 1 deletion arch/powerpc/mm/hugetlbpage.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ void __init reserve_hugetlb_gpages(void)
int i;

strlcpy(cmdline, boot_command_line, COMMAND_LINE_SIZE);
parse_args("hugetlb gpages", cmdline, NULL, 0, &do_gpage_early_setup);
parse_args("hugetlb gpages", cmdline, NULL, 0, 0, 0,
&do_gpage_early_setup);

/*
* Walk gpage list in reverse, allocating larger page sizes first.
Expand Down
35 changes: 14 additions & 21 deletions include/asm-generic/vmlinux.lds.h
Original file line number Diff line number Diff line change
Expand Up @@ -616,30 +616,23 @@
*(.init.setup) \
VMLINUX_SYMBOL(__setup_end) = .;

#define INITCALLS \
*(.initcallearly.init) \
VMLINUX_SYMBOL(__early_initcall_end) = .; \
*(.initcall0.init) \
*(.initcall0s.init) \
*(.initcall1.init) \
*(.initcall1s.init) \
*(.initcall2.init) \
*(.initcall2s.init) \
*(.initcall3.init) \
*(.initcall3s.init) \
*(.initcall4.init) \
*(.initcall4s.init) \
*(.initcall5.init) \
*(.initcall5s.init) \
*(.initcallrootfs.init) \
*(.initcall6.init) \
*(.initcall6s.init) \
*(.initcall7.init) \
*(.initcall7s.init)
#define INIT_CALLS_LEVEL(level) \
VMLINUX_SYMBOL(__initcall##level##_start) = .; \
*(.initcall##level##.init) \
*(.initcall##level##s.init) \

#define INIT_CALLS \
VMLINUX_SYMBOL(__initcall_start) = .; \
INITCALLS \
*(.initcallearly.init) \
INIT_CALLS_LEVEL(0) \
INIT_CALLS_LEVEL(1) \
INIT_CALLS_LEVEL(2) \
INIT_CALLS_LEVEL(3) \
INIT_CALLS_LEVEL(4) \
INIT_CALLS_LEVEL(5) \
INIT_CALLS_LEVEL(rootfs) \
INIT_CALLS_LEVEL(6) \
INIT_CALLS_LEVEL(7) \
VMLINUX_SYMBOL(__initcall_end) = .;

#define CON_INITCALL \
Expand Down
32 changes: 4 additions & 28 deletions include/linux/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
#include <linux/percpu.h>
#include <asm/module.h>

#include <trace/events/module.h>

/* Not Yet Implemented */
#define MODULE_SUPPORTED_DEVICE(name)

Expand Down Expand Up @@ -452,33 +450,11 @@ void symbol_put_addr(void *addr);

/* Sometimes we know we already have a refcount, and it's easier not
to handle the error case (which only happens with rmmod --wait). */
static inline void __module_get(struct module *module)
{
if (module) {
preempt_disable();
__this_cpu_inc(module->refptr->incs);
trace_module_get(module, _THIS_IP_);
preempt_enable();
}
}

static inline int try_module_get(struct module *module)
{
int ret = 1;

if (module) {
preempt_disable();
extern void __module_get(struct module *module);

if (likely(module_is_live(module))) {
__this_cpu_inc(module->refptr->incs);
trace_module_get(module, _THIS_IP_);
} else
ret = 0;

preempt_enable();
}
return ret;
}
/* This is the Right Way to get a module: if it fails, it's being removed,
* so pretend it's not there. */
extern bool try_module_get(struct module *module);

extern void module_put(struct module *module);

Expand Down
58 changes: 43 additions & 15 deletions include/linux/moduleparam.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,11 @@ struct kernel_param_ops {
void (*free)(void *arg);
};

/* Flag bits for kernel_param.flags */
#define KPARAM_ISBOOL 2

struct kernel_param {
const char *name;
const struct kernel_param_ops *ops;
u16 perm;
u16 flags;
s16 level;
union {
void *arg;
const struct kparam_string *str;
Expand Down Expand Up @@ -131,8 +128,40 @@ struct kparam_array
* The ops can have NULL set or get functions.
*/
#define module_param_cb(name, ops, arg, perm) \
__module_param_call(MODULE_PARAM_PREFIX, \
name, ops, arg, __same_type((arg), bool *), perm)
__module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, 0)

/**
* <level>_param_cb - general callback for a module/cmdline parameter
* to be evaluated before certain initcall level
* @name: a valid C identifier which is the parameter name.
* @ops: the set & get operations for this parameter.
* @perm: visibility in sysfs.
*
* The ops can have NULL set or get functions.
*/
#define __level_param_cb(name, ops, arg, perm, level) \
__module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, level)

#define core_param_cb(name, ops, arg, perm) \
__level_param_cb(name, ops, arg, perm, 1)

#define postcore_param_cb(name, ops, arg, perm) \
__level_param_cb(name, ops, arg, perm, 2)

#define arch_param_cb(name, ops, arg, perm) \
__level_param_cb(name, ops, arg, perm, 3)

#define subsys_param_cb(name, ops, arg, perm) \
__level_param_cb(name, ops, arg, perm, 4)

#define fs_param_cb(name, ops, arg, perm) \
__level_param_cb(name, ops, arg, perm, 5)

#define device_param_cb(name, ops, arg, perm) \
__level_param_cb(name, ops, arg, perm, 6)

#define late_param_cb(name, ops, arg, perm) \
__level_param_cb(name, ops, arg, perm, 7)

/* On alpha, ia64 and ppc64 relocations to global data cannot go into
read-only sections (which is part of respective UNIX ABI on these
Expand All @@ -146,7 +175,7 @@ struct kparam_array

/* This is the fundamental function for registering boot/module
parameters. */
#define __module_param_call(prefix, name, ops, arg, isbool, perm) \
#define __module_param_call(prefix, name, ops, arg, perm, level) \
/* Default value instead of permissions? */ \
static int __param_perm_check_##name __attribute__((unused)) = \
BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \
Expand All @@ -155,17 +184,15 @@ struct kparam_array
static struct kernel_param __moduleparam_const __param_##name \
__used \
__attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
= { __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0, \
{ arg } }
= { __param_str_##name, ops, perm, level, { arg } }

/* Obsolete - use module_param_cb() */
#define module_param_call(name, set, get, arg, perm) \
static struct kernel_param_ops __param_ops_##name = \
{ (void *)set, (void *)get }; \
__module_param_call(MODULE_PARAM_PREFIX, \
name, &__param_ops_##name, arg, \
__same_type(arg, bool *), \
(perm) + sizeof(__check_old_set_param(set))*0)
(perm) + sizeof(__check_old_set_param(set))*0, 0)

/* We don't get oldget: it's often a new-style param_get_uint, etc. */
static inline int
Expand Down Expand Up @@ -245,8 +272,7 @@ static inline void __kernel_param_unlock(void)
*/
#define core_param(name, var, type, perm) \
param_check_##type(name, &(var)); \
__module_param_call("", name, &param_ops_##type, \
&var, __same_type(var, bool), perm)
__module_param_call("", name, &param_ops_##type, &var, perm, 0)
#endif /* !MODULE */

/**
Expand All @@ -264,7 +290,7 @@ static inline void __kernel_param_unlock(void)
= { len, string }; \
__module_param_call(MODULE_PARAM_PREFIX, name, \
&param_ops_string, \
.str = &__param_string_##name, 0, perm); \
.str = &__param_string_##name, perm, 0); \
__MODULE_PARM_TYPE(name, "string")

/**
Expand Down Expand Up @@ -292,6 +318,8 @@ extern int parse_args(const char *name,
char *args,
const struct kernel_param *params,
unsigned num,
s16 level_min,
s16 level_max,
int (*unknown)(char *param, char *val));

/* Called by module remove. */
Expand Down Expand Up @@ -403,7 +431,7 @@ extern int param_set_bint(const char *val, const struct kernel_param *kp);
__module_param_call(MODULE_PARAM_PREFIX, name, \
&param_array_ops, \
.arr = &__param_arr_##name, \
__same_type(array[0], bool), perm); \
perm, 0); \
__MODULE_PARM_TYPE(name, "array of " #type)

extern struct kernel_param_ops param_array_ops;
Expand Down
65 changes: 59 additions & 6 deletions init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ static int __init do_early_param(char *param, char *val)

void __init parse_early_options(char *cmdline)
{
parse_args("early options", cmdline, NULL, 0, do_early_param);
parse_args("early options", cmdline, NULL, 0, 0, 0, do_early_param);
}

/* Arch code calls this early on, or if not, just before other parsing. */
Expand Down Expand Up @@ -503,7 +503,7 @@ asmlinkage void __init start_kernel(void)
parse_early_param();
parse_args("Booting kernel", static_command_line, __start___param,
__stop___param - __start___param,
&unknown_bootoption);
0, 0, &unknown_bootoption);

jump_label_init();

Expand Down Expand Up @@ -699,16 +699,69 @@ int __init_or_module do_one_initcall(initcall_t fn)
}


extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
extern initcall_t __initcall_start[];
extern initcall_t __initcall0_start[];
extern initcall_t __initcall1_start[];
extern initcall_t __initcall2_start[];
extern initcall_t __initcall3_start[];
extern initcall_t __initcall4_start[];
extern initcall_t __initcall5_start[];
extern initcall_t __initcall6_start[];
extern initcall_t __initcall7_start[];
extern initcall_t __initcall_end[];

static initcall_t *initcall_levels[] __initdata = {
__initcall0_start,
__initcall1_start,
__initcall2_start,
__initcall3_start,
__initcall4_start,
__initcall5_start,
__initcall6_start,
__initcall7_start,
__initcall_end,
};

static char *initcall_level_names[] __initdata = {
"early parameters",
"core parameters",
"postcore parameters",
"arch parameters",
"subsys parameters",
"fs parameters",
"device parameters",
"late parameters",
};

static int __init ignore_unknown_bootoption(char *param, char *val)
{
return 0;
}

static void __init do_initcalls(void)
static void __init do_initcall_level(int level)
{
extern const struct kernel_param __start___param[], __stop___param[];
initcall_t *fn;

for (fn = __early_initcall_end; fn < __initcall_end; fn++)
strcpy(static_command_line, saved_command_line);
parse_args(initcall_level_names[level],
static_command_line, __start___param,
__stop___param - __start___param,
level, level,
ignore_unknown_bootoption);

for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
do_one_initcall(*fn);
}

static void __init do_initcalls(void)
{
int level;

for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
do_initcall_level(level);
}

/*
* Ok, the machine is now initialized. None of the devices
* have been touched yet, but the CPU subsystem is up and
Expand All @@ -732,7 +785,7 @@ static void __init do_pre_smp_initcalls(void)
{
initcall_t *fn;

for (fn = __initcall_start; fn < __early_initcall_end; fn++)
for (fn = __initcall_start; fn < __initcall0_start; fn++)
do_one_initcall(*fn);
}

Expand Down
Loading

0 comments on commit d25413e

Please sign in to comment.