Skip to content

Commit

Permalink
Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/rusty/linux

Pull module updates from Rusty Russell:
 "Mainly boring here, too.  rmmod --wait finally removed, though"

* tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
  modpost: fix bogus 'exported twice' warnings.
  init: fix in-place parameter modification regression
  asmlinkage, module: Make ksymtab and kcrctab symbols and __this_module __visible
  kernel: add support for init_array constructors
  modpost: Optionally ignore secondary errors seen if a single module build fails
  module: remove rmmod --wait option.
  • Loading branch information
torvalds committed Nov 15, 2013
2 parents d8fe4ac + b6568b1 commit ce6513f
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 52 deletions.
1 change: 1 addition & 0 deletions include/asm-generic/vmlinux.lds.h
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@
#define KERNEL_CTORS() . = ALIGN(8); \
VMLINUX_SYMBOL(__ctors_start) = .; \
*(.ctors) \
*(.init_array) \
VMLINUX_SYMBOL(__ctors_end) = .;
#else
#define KERNEL_CTORS()
Expand Down
4 changes: 2 additions & 2 deletions include/linux/export.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ extern struct module __this_module;
/* Mark the CRC weak since genksyms apparently decides not to
* generate a checksums for some symbols */
#define __CRC_SYMBOL(sym, sec) \
extern void *__crc_##sym __attribute__((weak)); \
extern __visible void *__crc_##sym __attribute__((weak)); \
static const unsigned long __kcrctab_##sym \
__used \
__attribute__((section("___kcrctab" sec "+" #sym), unused)) \
Expand All @@ -59,7 +59,7 @@ extern struct module __this_module;
static const char __kstrtab_##sym[] \
__attribute__((section("__ksymtab_strings"), aligned(1))) \
= VMLINUX_SYMBOL_STR(sym); \
static const struct kernel_symbol __ksymtab_##sym \
__visible const struct kernel_symbol __ksymtab_##sym \
__used \
__attribute__((section("___ksymtab" sec "+" #sym), unused)) \
= { (unsigned long)&sym, __kstrtab_##sym }
Expand Down
3 changes: 0 additions & 3 deletions include/linux/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,6 @@ struct module
/* What modules do I depend on? */
struct list_head target_list;

/* Who is waiting for us to be unloaded */
struct task_struct *waiter;

/* Destruction function. */
void (*exit)(void);

Expand Down
7 changes: 5 additions & 2 deletions init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ char __initdata boot_command_line[COMMAND_LINE_SIZE];
char *saved_command_line;
/* Command line for parameter parsing */
static char *static_command_line;
/* Command line for per-initcall parameter parsing */
static char *initcall_command_line;

static char *execute_command;
static char *ramdisk_execute_command;
Expand Down Expand Up @@ -354,6 +356,7 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { }
static void __init setup_command_line(char *command_line)
{
saved_command_line = alloc_bootmem(strlen (boot_command_line)+1);
initcall_command_line = alloc_bootmem(strlen (boot_command_line)+1);
static_command_line = alloc_bootmem(strlen (command_line)+1);
strcpy (saved_command_line, boot_command_line);
strcpy (static_command_line, command_line);
Expand Down Expand Up @@ -751,9 +754,9 @@ static void __init do_initcall_level(int level)
extern const struct kernel_param __start___param[], __stop___param[];
initcall_t *fn;

strcpy(static_command_line, saved_command_line);
strcpy(initcall_command_line, saved_command_line);
parse_args(initcall_level_names[level],
static_command_line, __start___param,
initcall_command_line, __start___param,
__stop___param - __start___param,
level, level,
&repair_env_string);
Expand Down
66 changes: 26 additions & 40 deletions kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -641,8 +641,6 @@ static int module_unload_init(struct module *mod)

/* Hold reference count during initialization. */
__this_cpu_write(mod->refptr->incs, 1);
/* Backwards compatibility macros put refcount during init. */
mod->waiter = current;

return 0;
}
Expand Down Expand Up @@ -768,16 +766,9 @@ static int __try_stop_module(void *_sref)

static int try_stop_module(struct module *mod, int flags, int *forced)
{
if (flags & O_NONBLOCK) {
struct stopref sref = { mod, flags, forced };
struct stopref sref = { mod, flags, forced };

return stop_machine(__try_stop_module, &sref, NULL);
} else {
/* We don't need to stop the machine for this. */
mod->state = MODULE_STATE_GOING;
synchronize_sched();
return 0;
}
return stop_machine(__try_stop_module, &sref, NULL);
}

unsigned long module_refcount(struct module *mod)
Expand Down Expand Up @@ -810,21 +801,6 @@ EXPORT_SYMBOL(module_refcount);
/* This exists whether we can unload or not */
static void free_module(struct module *mod);

static void wait_for_zero_refcount(struct module *mod)
{
/* Since we might sleep for some time, release the mutex first */
mutex_unlock(&module_mutex);
for (;;) {
pr_debug("Looking at refcount...\n");
set_current_state(TASK_UNINTERRUPTIBLE);
if (module_refcount(mod) == 0)
break;
schedule();
}
current->state = TASK_RUNNING;
mutex_lock(&module_mutex);
}

SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
unsigned int, flags)
{
Expand All @@ -839,6 +815,11 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
return -EFAULT;
name[MODULE_NAME_LEN-1] = '\0';

if (!(flags & O_NONBLOCK)) {
printk(KERN_WARNING
"waiting module removal not supported: please upgrade");
}

if (mutex_lock_interruptible(&module_mutex) != 0)
return -EINTR;

Expand All @@ -856,8 +837,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,

/* Doing init or already dying? */
if (mod->state != MODULE_STATE_LIVE) {
/* FIXME: if (force), slam module count and wake up
waiter --RR */
/* FIXME: if (force), slam module count damn the torpedoes */
pr_debug("%s already dying\n", mod->name);
ret = -EBUSY;
goto out;
Expand All @@ -873,18 +853,11 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
}
}

/* Set this up before setting mod->state */
mod->waiter = current;

/* Stop the machine so refcounts can't move and disable module. */
ret = try_stop_module(mod, flags, &forced);
if (ret != 0)
goto out;

/* Never wait if forced. */
if (!forced && module_refcount(mod) != 0)
wait_for_zero_refcount(mod);

mutex_unlock(&module_mutex);
/* Final destruction now no one is using it. */
if (mod->exit != NULL)
Expand Down Expand Up @@ -1002,9 +975,6 @@ void module_put(struct module *module)
__this_cpu_inc(module->refptr->decs);

trace_module_put(module, _RET_IP_);
/* Maybe they're waiting for us to drop reference? */
if (unlikely(!module_is_live(module)))
wake_up_process(module->waiter);
preempt_enable();
}
}
Expand Down Expand Up @@ -2728,7 +2698,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)
return 0;
}

static void find_module_sections(struct module *mod, struct load_info *info)
static int find_module_sections(struct module *mod, struct load_info *info)
{
mod->kp = section_objs(info, "__param",
sizeof(*mod->kp), &mod->num_kp);
Expand Down Expand Up @@ -2758,6 +2728,18 @@ static void find_module_sections(struct module *mod, struct load_info *info)
#ifdef CONFIG_CONSTRUCTORS
mod->ctors = section_objs(info, ".ctors",
sizeof(*mod->ctors), &mod->num_ctors);
if (!mod->ctors)
mod->ctors = section_objs(info, ".init_array",
sizeof(*mod->ctors), &mod->num_ctors);
else if (find_sec(info, ".init_array")) {
/*
* This shouldn't happen with same compiler and binutils
* building all parts of the module.
*/
printk(KERN_WARNING "%s: has both .ctors and .init_array.\n",
mod->name);
return -EINVAL;
}
#endif

#ifdef CONFIG_TRACEPOINTS
Expand Down Expand Up @@ -2795,6 +2777,8 @@ static void find_module_sections(struct module *mod, struct load_info *info)

info->debug = section_objs(info, "__verbose",
sizeof(*info->debug), &info->num_debug);

return 0;
}

static int move_module(struct module *mod, struct load_info *info)
Expand Down Expand Up @@ -3248,7 +3232,9 @@ static int load_module(struct load_info *info, const char __user *uargs,

/* Now we've got everything in the final locations, we can
* find optional sections. */
find_module_sections(mod, info);
err = find_module_sections(mod, info);
if (err)
goto free_unload;

err = check_module_license_and_versions(mod);
if (err)
Expand Down
4 changes: 3 additions & 1 deletion scripts/Makefile.modpost
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,11 @@ modpost = scripts/mod/modpost \
$(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \
$(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w)

MODPOST_OPT=$(subst -i,-n,$(filter -i,$(MAKEFLAGS)))

# We can go over command line length here, so be careful.
quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
cmd_modpost = $(MODLISTCMD) | sed 's/\.ko$$/.o/' | $(modpost) -s -T -
cmd_modpost = $(MODLISTCMD) | sed 's/\.ko$$/.o/' | $(modpost) $(MODPOST_OPT) -s -T -

PHONY += __modpost
__modpost: $(modules:.ko=.o) FORCE
Expand Down
22 changes: 18 additions & 4 deletions scripts/mod/modpost.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <string.h>
#include <limits.h>
#include <stdbool.h>
#include <errno.h>
#include "modpost.h"
#include "../../include/generated/autoconf.h"
#include "../../include/linux/license.h"
Expand All @@ -37,6 +38,8 @@ static int warn_unresolved = 0;
/* How a symbol is exported */
static int sec_mismatch_count = 0;
static int sec_mismatch_verbose = 1;
/* ignore missing files */
static int ignore_missing_files;

enum export {
export_plain, export_unused, export_gpl,
Expand Down Expand Up @@ -161,7 +164,7 @@ struct symbol {
unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */
unsigned int kernel:1; /* 1 if symbol is from kernel
* (only for external modules) **/
unsigned int preloaded:1; /* 1 if symbol from Module.symvers */
unsigned int preloaded:1; /* 1 if symbol from Module.symvers, or crc */
enum export export; /* Type of export */
char name[0];
};
Expand Down Expand Up @@ -329,8 +332,11 @@ static void sym_update_crc(const char *name, struct module *mod,
{
struct symbol *s = find_symbol(name);

if (!s)
if (!s) {
s = new_symbol(name, mod, export);
/* Don't complain when we find it later. */
s->preloaded = 1;
}
s->crc = crc;
s->crc_valid = 1;
}
Expand Down Expand Up @@ -407,6 +413,11 @@ static int parse_elf(struct elf_info *info, const char *filename)

hdr = grab_file(filename, &info->size);
if (!hdr) {
if (ignore_missing_files) {
fprintf(stderr, "%s: %s (ignored)\n", filename,
strerror(errno));
return 0;
}
perror(filename);
exit(1);
}
Expand Down Expand Up @@ -1852,7 +1863,7 @@ static void add_header(struct buffer *b, struct module *mod)
buf_printf(b, "\n");
buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
buf_printf(b, "\n");
buf_printf(b, "struct module __this_module\n");
buf_printf(b, "__visible struct module __this_module\n");
buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
buf_printf(b, "\t.name = KBUILD_MODNAME,\n");
if (mod->has_init)
Expand Down Expand Up @@ -2118,7 +2129,7 @@ int main(int argc, char **argv)
struct ext_sym_list *extsym_iter;
struct ext_sym_list *extsym_start = NULL;

while ((opt = getopt(argc, argv, "i:I:e:msST:o:awM:K:")) != -1) {
while ((opt = getopt(argc, argv, "i:I:e:mnsST:o:awM:K:")) != -1) {
switch (opt) {
case 'i':
kernel_read = optarg;
Expand All @@ -2138,6 +2149,9 @@ int main(int argc, char **argv)
case 'm':
modversions = 1;
break;
case 'n':
ignore_missing_files = 1;
break;
case 'o':
dump_write = optarg;
break;
Expand Down

0 comments on commit ce6513f

Please sign in to comment.