Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce6513f7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/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.
parents d8fe4acc b6568b1a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -473,6 +473,7 @@
#define KERNEL_CTORS()	. = ALIGN(8);			   \
			VMLINUX_SYMBOL(__ctors_start) = .; \
			*(.ctors)			   \
			*(.init_array)			   \
			VMLINUX_SYMBOL(__ctors_end) = .;
#else
#define KERNEL_CTORS()
+2 −2
Original line number Diff line number Diff line
@@ -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))	\
@@ -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 }
+0 −3
Original line number Diff line number Diff line
@@ -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);

+5 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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);
@@ -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);
+26 −40
Original line number Diff line number Diff line
@@ -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;
}
@@ -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 };

	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;
	}
}

unsigned long module_refcount(struct module *mod)
@@ -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)
{
@@ -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;

@@ -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;
@@ -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)
@@ -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();
	}
}
@@ -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);
@@ -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
@@ -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)
@@ -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)
Loading