From 3c19af9355ba86a5b99d6e5a57ecaa68a7ea6e8e Mon Sep 17 00:00:00 2001 From: root Date: Tue, 23 Oct 2012 01:37:15 -0700 Subject: Tue Oct 23 01:37:02 PDT 2012 --- libre/linux-libre/PKGBUILD | 21 +++++-- libre/linux-libre/config.i686 | 7 ++- libre/linux-libre/config.x86_64 | 7 ++- libre/linux-libre/linux-libre.install | 2 +- libre/linux-libre/module-init-wait-3.6.patch | 77 +++++++++++++++++++++++ libre/linux-libre/module-symbol-waiting-3.6.patch | 66 +++++++++++++++++++ 6 files changed, 169 insertions(+), 11 deletions(-) create mode 100644 libre/linux-libre/module-init-wait-3.6.patch create mode 100644 libre/linux-libre/module-symbol-waiting-3.6.patch (limited to 'libre/linux-libre') diff --git a/libre/linux-libre/PKGBUILD b/libre/linux-libre/PKGBUILD index a0f8777e6..8fd3e3138 100644 --- a/libre/linux-libre/PKGBUILD +++ b/libre/linux-libre/PKGBUILD @@ -10,10 +10,10 @@ pkgbase=linux-libre # Build stock -LIBRE kernel #pkgbase=linux-libre-custom # Build kernel with a different name _basekernel=3.6 -_sublevel=2 +_sublevel=3 pkgver=${_basekernel}.${_sublevel} pkgrel=1 -_lxopkgver=${_basekernel}.1 # nearly always the same as pkgver +_lxopkgver=${_basekernel}.2 # nearly always the same as pkgver arch=('i686' 'x86_64' 'mips64el') url="http://linux-libre.fsfla.org/" license=('GPL2') @@ -29,17 +29,21 @@ source=("http://linux-libre.fsfla.org/pub/linux-libre/releases/${_basekernel}-gn 'Kbuild.platforms' 'boot-logo.patch' 'change-default-console-loglevel.patch' + 'module-symbol-waiting-3.6.patch' + 'module-init-wait-3.6.patch' "http://www.linux-libre.fsfla.org/pub/linux-libre/lemote/gnewsense/pool/debuginfo/linux-patches-${_lxopkgver}-gnu_0loongsonlibre_mipsel.tar.bz2") md5sums=('a2312edd0265b5b07bd4b50afae2b380' - '1014a197e2bea449600d7b2cca415eec' - '600af9b069c8a1c18dd5ef1f25bf7080' - 'c18004748092bf4ee57ade7e25fdef22' + '844bd14e9f58225274e096c31bbb8a8f' + 'e4a3a4677e1fac6ecf0e0fb44c41ca08' + '68fc36a4efb6ade0eca409b9444fef0c' 'e49ac236dfeef709f91a3d993ea7b62c' '2967cecc3af9f954ccc822fd63dca6ff' '8267264d9a8966e57fdacd1fa1fc65c4' '04b21c79df0a952c22d681dd4f4562df' '9d3c56a4b999c8bfbd4018089a62f662' - '1690532ad271b11a87e8824f7da65101') + '670931649c60fcb3ef2e0119ed532bd4' + '8a71abc4224f575008f974a099b5cf6f' + '34508a324c3704662e9fc115d07735a3') if [ "$CARCH" != "mips64el" ]; then # Don't use the Loongson-specific patches on non-mips64el arches. unset source[${#source[@]}-1] @@ -64,6 +68,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" == "mips64el" ]; then sed -i "s|^EXTRAVERSION.*|EXTRAVERSION =-libre|" Makefile sed -r "s|^( SUBLEVEL = ).*|\1$_sublevel|" \ diff --git a/libre/linux-libre/config.i686 b/libre/linux-libre/config.i686 index e553c3d44..6533b0402 100644 --- a/libre/linux-libre/config.i686 +++ b/libre/linux-libre/config.i686 @@ -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/libre/linux-libre/config.x86_64 b/libre/linux-libre/config.x86_64 index 479c39929..fbc1c7588 100644 --- a/libre/linux-libre/config.x86_64 +++ b/libre/linux-libre/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/libre/linux-libre/linux-libre.install b/libre/linux-libre/linux-libre.install index e5af2a1bd..e327cd7ea 100644 --- a/libre/linux-libre/linux-libre.install +++ b/libre/linux-libre/linux-libre.install @@ -2,7 +2,7 @@ # arg 2: the old package version KERNEL_NAME= -KERNEL_VERSION=3.6.2-1-LIBRE +KERNEL_VERSION=3.6.3-1-LIBRE # 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/libre/linux-libre/module-init-wait-3.6.patch b/libre/linux-libre/module-init-wait-3.6.patch new file mode 100644 index 000000000..1bcfd2491 --- /dev/null +++ b/libre/linux-libre/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/libre/linux-libre/module-symbol-waiting-3.6.patch b/libre/linux-libre/module-symbol-waiting-3.6.patch new file mode 100644 index 000000000..b87a38ff5 --- /dev/null +++ b/libre/linux-libre/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; + } -- cgit v1.2.3-54-g00ecf