diff --git a/PKGBUILD b/PKGBUILD index 8108588..2632c1e 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -5,7 +5,7 @@ pkgbase=linux # Build stock -ARCH kernel #pkgbase=linux-custom # Build kernel with a different name _srcname=linux-3.6 -pkgver=3.6.2 +pkgver=3.6.3 pkgrel=1 arch=('i686' 'x86_64') url="http://www.kernel.org/" @@ -18,13 +18,17 @@ source=("http://www.kernel.org/pub/linux/kernel/v3.x/${_srcname}.tar.xz" 'config' 'config.x86_64' # standard config files for mkinitcpio ramdisk 'linux.preset' - 'change-default-console-loglevel.patch') + 'change-default-console-loglevel.patch' + 'module-symbol-waiting-3.6.patch' + 'module-init-wait-3.6.patch') md5sums=('1a1760420eac802c541a20ab51a093d1' - 'ad1020c82a71ee1ef2416a0d12e724df' - '443f285744cb96401f9a631f542b9248' - '2793e97a9e98c501afd3e18d2e3b9762' + '96701113d37ef4f9b785206ab8bcc71e' + '65f7ff39775f20f65014383564d3cb65' + '3adbfa45451c4bcf9dd7879bed033d77' 'eb14dcfd80c00852ef81ded6e826826a' - '9d3c56a4b999c8bfbd4018089a62f662') + '9d3c56a4b999c8bfbd4018089a62f662' + '670931649c60fcb3ef2e0119ed532bd4' + '8a71abc4224f575008f974a099b5cf6f') _kernelname=${pkgbase#linux} @@ -42,6 +46,11 @@ build() { # (relevant patch sent upstream: https://lkml.org/lkml/2011/7/26/227) patch -Np1 -i "${srcdir}/change-default-console-loglevel.patch" + # fix module initialisation + # https://bugs.archlinux.org/task/32122 + patch -Np1 -i "${srcdir}/module-symbol-waiting-3.6.patch" + patch -Np1 -i "${srcdir}/module-init-wait-3.6.patch" + if [ "${CARCH}" = "x86_64" ]; then cat "${srcdir}/config.x86_64" > ./.config else @@ -306,4 +315,4 @@ for _p in ${pkgname[@]}; do }" done -# vim:set ts=8 sts=2 sw=2 et: +# vim:set ts=8 sts=2 sw=2 et: \ No newline at end of file diff --git a/config b/config index 772a79e..2bd1ccb 100644 --- a/config +++ b/config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/i386 3.6.0 Kernel Configuration +# Linux/i386 3.6.3 Kernel Configuration # # CONFIG_64BIT is not set CONFIG_X86_32=y @@ -134,7 +134,10 @@ CONFIG_CPUSETS=y CONFIG_PROC_PID_CPUSET=y CONFIG_CGROUP_CPUACCT=y CONFIG_RESOURCE_COUNTERS=y -# CONFIG_MEMCG is not set +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +# CONFIG_MEMCG_SWAP_ENABLED is not set +CONFIG_MEMCG_KMEM=y # CONFIG_CGROUP_HUGETLB is not set # CONFIG_CGROUP_PERF is not set CONFIG_CGROUP_SCHED=y diff --git a/config.x86_64 b/config.x86_64 index 35ed46b..c4613ee 100644 --- a/config.x86_64 +++ b/config.x86_64 @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86_64 3.6.0 Kernel Configuration +# Linux/x86_64 3.6.3 Kernel Configuration # CONFIG_64BIT=y # CONFIG_X86_32 is not set @@ -136,7 +136,10 @@ CONFIG_CPUSETS=y CONFIG_PROC_PID_CPUSET=y CONFIG_CGROUP_CPUACCT=y CONFIG_RESOURCE_COUNTERS=y -# CONFIG_MEMCG is not set +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +# CONFIG_MEMCG_SWAP_ENABLED is not set +CONFIG_MEMCG_KMEM=y # CONFIG_CGROUP_HUGETLB is not set # CONFIG_CGROUP_PERF is not set CONFIG_CGROUP_SCHED=y diff --git a/linux.install b/linux.install index 96d32c3..ed9f9ac 100644 --- a/linux.install +++ b/linux.install @@ -2,7 +2,7 @@ # arg 2: the old package version KERNEL_NAME= -KERNEL_VERSION=3.6.2-1-ARCH +KERNEL_VERSION=3.6.3-1-ARCH # set a sane PATH to ensure that critical utils like depmod will be found export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' diff --git a/module-init-wait-3.6.patch b/module-init-wait-3.6.patch new file mode 100644 index 0000000..1bcfd24 --- /dev/null +++ b/module-init-wait-3.6.patch @@ -0,0 +1,77 @@ +From: Rusty Russell +Date: Fri, 28 Sep 2012 05:01:03 +0000 (+0930) +Subject: module: wait when loading a module which is currently initializing. +X-Git-Tag: v3.7-rc1~2^2~32 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9bb9c3be568346538 + +module: wait when loading a module which is currently initializing. + +The original module-init-tools module loader used a fnctl lock on the +.ko file to avoid attempts to simultaneously load a module. +Unfortunately, you can't get an exclusive fcntl lock on a read-only +fd, making this not work for read-only mounted filesystems. +module-init-tools has a hacky sleep-and-loop for this now. + +It's not that hard to wait in the kernel, and only return -EEXIST once +the first module has finished loading (or continue loading the module +if the first one failed to initialize for some reason). It's also +consistent with what we do for dependent modules which are still loading. + +Suggested-by: Lucas De Marchi +Signed-off-by: Rusty Russell +--- + +diff --git a/kernel/module.c b/kernel/module.c +index 63cf6e7..74bc195 100644 +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -2845,6 +2845,20 @@ static int post_relocation(struct module *mod, const struct load_info *info) + return module_finalize(info->hdr, info->sechdrs, mod); + } + ++/* Is this module of this name done loading? No locks held. */ ++static bool finished_loading(const char *name) ++{ ++ struct module *mod; ++ bool ret; ++ ++ mutex_lock(&module_mutex); ++ mod = find_module(name); ++ ret = !mod || mod->state != MODULE_STATE_COMING; ++ mutex_unlock(&module_mutex); ++ ++ return ret; ++} ++ + /* Allocate and load the module: note that size of section 0 is always + zero, and we rely on this for optional sections. */ + static struct module *load_module(void __user *umod, +@@ -2852,7 +2866,7 @@ static struct module *load_module(void __user *umod, + const char __user *uargs) + { + struct load_info info = { NULL, }; +- struct module *mod; ++ struct module *mod, *old; + long err; + + pr_debug("load_module: umod=%p, len=%lu, uargs=%p\n", +@@ -2918,8 +2932,18 @@ static struct module *load_module(void __user *umod, + * function to insert in a way safe to concurrent readers. + * The mutex protects against concurrent writers. + */ ++again: + mutex_lock(&module_mutex); +- if (find_module(mod->name)) { ++ if ((old = find_module(mod->name)) != NULL) { ++ if (old->state == MODULE_STATE_COMING) { ++ /* Wait in case it fails to load. */ ++ mutex_unlock(&module_mutex); ++ err = wait_event_interruptible(module_wq, ++ finished_loading(mod->name)); ++ if (err) ++ goto free_arch_cleanup; ++ goto again; ++ } + err = -EEXIST; + goto unlock; + } diff --git a/module-symbol-waiting-3.6.patch b/module-symbol-waiting-3.6.patch new file mode 100644 index 0000000..b87a38f --- /dev/null +++ b/module-symbol-waiting-3.6.patch @@ -0,0 +1,66 @@ +From: Rusty Russell +Date: Fri, 28 Sep 2012 05:01:03 +0000 (+0930) +Subject: module: fix symbol waiting when module fails before init +X-Git-Tag: v3.7-rc1~2^2~33 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=6f13909f4fe9652f1 + +module: fix symbol waiting when module fails before init + +We use resolve_symbol_wait(), which blocks if the module containing +the symbol is still loading. However: + +1) The module_wq we use is only woken after calling the modules' init + function, but there are other failure paths after the module is + placed in the linked list where we need to do the same thing. + +2) wake_up() only wakes one waiter, and our waitqueue is shared by all + modules, so we need to wake them all. + +3) wake_up_all() doesn't imply a memory barrier: I feel happier calling + it after we've grabbed and dropped the module_mutex, not just after + the state assignment. + +Signed-off-by: Rusty Russell +--- + +diff --git a/kernel/module.c b/kernel/module.c +index 7f2ee45f..63cf6e7 100644 +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -2959,7 +2959,7 @@ static struct module *load_module(void __user *umod, + /* Unlink carefully: kallsyms could be walking list. */ + list_del_rcu(&mod->list); + module_bug_cleanup(mod); +- ++ wake_up_all(&module_wq); + ddebug: + dynamic_debug_remove(info.debug); + unlock: +@@ -3034,7 +3034,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, + blocking_notifier_call_chain(&module_notify_list, + MODULE_STATE_GOING, mod); + free_module(mod); +- wake_up(&module_wq); ++ wake_up_all(&module_wq); + return ret; + } + if (ret > 0) { +@@ -3046,9 +3046,8 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, + dump_stack(); + } + +- /* Now it's a first class citizen! Wake up anyone waiting for it. */ ++ /* Now it's a first class citizen! */ + mod->state = MODULE_STATE_LIVE; +- wake_up(&module_wq); + blocking_notifier_call_chain(&module_notify_list, + MODULE_STATE_LIVE, mod); + +@@ -3071,6 +3070,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, + mod->init_ro_size = 0; + mod->init_text_size = 0; + mutex_unlock(&module_mutex); ++ wake_up_all(&module_wq); + + return 0; + }