diff options
author | root <root@rshg054.dnsready.net> | 2012-10-23 01:37:15 -0700 |
---|---|---|
committer | root <root@rshg054.dnsready.net> | 2012-10-23 01:37:15 -0700 |
commit | 3c19af9355ba86a5b99d6e5a57ecaa68a7ea6e8e (patch) | |
tree | 8fac31deec086251b3b9dc8faddfe14f5667392b /libre/linux-libre-lts | |
parent | 99746708edfd2c56f2ba654a14f27e98b1601a43 (diff) |
Tue Oct 23 01:37:02 PDT 2012
Diffstat (limited to 'libre/linux-libre-lts')
-rw-r--r-- | libre/linux-libre-lts/PKGBUILD | 17 | ||||
-rw-r--r-- | libre/linux-libre-lts/linux-libre-lts.install | 2 | ||||
-rw-r--r-- | libre/linux-libre-lts/module-init-wait-3.0.patch | 77 | ||||
-rw-r--r-- | libre/linux-libre-lts/module-symbol-waiting-3.0.patch | 66 |
4 files changed, 157 insertions, 5 deletions
diff --git a/libre/linux-libre-lts/PKGBUILD b/libre/linux-libre-lts/PKGBUILD index d544abb26..65e5e55b0 100644 --- a/libre/linux-libre-lts/PKGBUILD +++ b/libre/linux-libre-lts/PKGBUILD @@ -7,10 +7,10 @@ pkgbase=linux-libre-lts # Build stock -LIBRE-LTS kernel #pkgbase=linux-libre-custom # Build kernel with a different name _basekernel=3.0 -_sublevel=46 +_sublevel=47 pkgver=${_basekernel}.${_sublevel} pkgrel=1 -_lxopkgver=${_basekernel}.45 # nearly always the same as pkgver +_lxopkgver=${_basekernel}.46 # nearly always the same as pkgver arch=('i686' 'x86_64' 'mips64el') url="http://linux-libre.fsfla.org/" license=('GPL2') @@ -28,9 +28,11 @@ source=("http://linux-libre.fsfla.org/pub/linux-libre/releases/${_basekernel}-gn 'change-default-console-loglevel.patch' 'i915-fix-ghost-tv-output.patch' 'ext4-options.patch' + 'module-symbol-waiting-3.0.patch' + 'module-init-wait-3.0.patch' "http://www.linux-libre.fsfla.org/pub/linux-libre/lemote/gnewsense/pool/debuginfo/linux-patches-${_lxopkgver}-gnu_0loongsonlibre_mipsel.tar.bz2") md5sums=('5f64180fe7df4e574dac5911b78f5067' - 'a2ced38cb23963b9efef79100f5885c5' + '6ad7f8f5b7230d1425dcb2c0bc336cf8' 'aed25ab047e1c0b020a1516c235c6a74' '7d37e8ce0f4bd5a957172b12ae742ea0' 'c072b17032e80debc6a8626299245d46' @@ -40,7 +42,9 @@ md5sums=('5f64180fe7df4e574dac5911b78f5067' '9d3c56a4b999c8bfbd4018089a62f662' '263725f20c0b9eb9c353040792d644e5' 'f36222e7ce20c8e4dc27376f9be60f6c' - '2fb6f217d649733bd5d977bf32c1f292') + '670931649c60fcb3ef2e0119ed532bd4' + '8a71abc4224f575008f974a099b5cf6f' + '546d9b9893e49bddf13a106f890caf94') if [ "$CARCH" != "mips64el" ]; then # Don't use the Loongson-specific patches on non-mips64el arches. unset source[${#source[@]}-1] @@ -78,6 +82,11 @@ build() { # https://bugs.archlinux.org/task/28653 patch -Np1 -i "${srcdir}/ext4-options.patch" + # fix module initialisation + # https://bugs.archlinux.org/task/32122 + patch -Np1 -i "${srcdir}/module-symbol-waiting-3.0.patch" + patch -Np1 -i "${srcdir}/module-init-wait-3.0.patch" + if [ "$CARCH" == "mips64el" ]; then sed -i "s|^EXTRAVERSION.*|EXTRAVERSION =-libre-lts|" Makefile sed -r "s|^( SUBLEVEL = ).*|\1$_sublevel|" \ diff --git a/libre/linux-libre-lts/linux-libre-lts.install b/libre/linux-libre-lts/linux-libre-lts.install index 57f19a417..3dc3be117 100644 --- a/libre/linux-libre-lts/linux-libre-lts.install +++ b/libre/linux-libre-lts/linux-libre-lts.install @@ -2,7 +2,7 @@ # arg 2: the old package version KERNEL_NAME=-lts -KERNEL_VERSION=3.0.46-1-LIBRE-LTS +KERNEL_VERSION=3.0.47-1-LIBRE-LTS # 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-lts/module-init-wait-3.0.patch b/libre/linux-libre-lts/module-init-wait-3.0.patch new file mode 100644 index 000000000..1bcfd2491 --- /dev/null +++ b/libre/linux-libre-lts/module-init-wait-3.0.patch @@ -0,0 +1,77 @@ +From: Rusty Russell <rusty@rustcorp.com.au> +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 <lucas.demarchi@profusion.mobi> +Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> +--- + +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-lts/module-symbol-waiting-3.0.patch b/libre/linux-libre-lts/module-symbol-waiting-3.0.patch new file mode 100644 index 000000000..b87a38ff5 --- /dev/null +++ b/libre/linux-libre-lts/module-symbol-waiting-3.0.patch @@ -0,0 +1,66 @@ +From: Rusty Russell <rusty@rustcorp.com.au> +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 <rusty@rustcorp.com.au> +--- + +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; + } |