summaryrefslogtreecommitdiffstats
path: root/lib/syscall.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2013-03-22 15:04:41 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-03-22 16:41:20 -0700
commit2ca067efd82939dfd87827d29d36a265823a4c2f (patch)
treea6291128f65ef015ab36460a5e5f39a5bc25c4a1 /lib/syscall.c
parentd00285884c0892bb1310df96bce6056e9ce9b9d9 (diff)
downloadlinux-2ca067efd82939dfd87827d29d36a265823a4c2f.tar.gz
linux-2ca067efd82939dfd87827d29d36a265823a4c2f.tar.bz2
linux-2ca067efd82939dfd87827d29d36a265823a4c2f.zip
poweroff: change orderly_poweroff() to use schedule_work()
David said: Commit 6c0c0d4d1080 ("poweroff: fix bug in orderly_poweroff()") apparently fixes one bug in orderly_poweroff(), but introduces another. The comments on orderly_poweroff() claim it can be called from any context - and indeed we call it from interrupt context in arch/powerpc/platforms/pseries/ras.c for example. But since that commit this is no longer safe, since call_usermodehelper_fns() is not safe in interrupt context without the UMH_NO_WAIT option. orderly_poweroff() can be used from any context but UMH_WAIT_EXEC is sleepable. Move the "force" logic into __orderly_poweroff() and change orderly_poweroff() to use the global poweroff_work which simply calls __orderly_poweroff(). While at it, remove the unneeded "int argc" and change argv_split() to use GFP_KERNEL. We use the global "bool poweroff_force" to pass the argument, this can obviously affect the previous request if it is pending/running. So we only allow the "false => true" transition assuming that the pending "true" should succeed anyway. If schedule_work() fails after that we know that work->func() was not called yet, it must see the new value. This means that orderly_poweroff() becomes async even if we do not run the command and always succeeds, schedule_work() can only fail if the work is already pending. We can export __orderly_poweroff() and change the non-atomic callers which want the old semantics. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Reported-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Reported-by: David Gibson <david@gibson.dropbear.id.au> Cc: Lucas De Marchi <lucas.demarchi@profusion.mobi> Cc: Feng Hong <hongfeng@marvell.com> Cc: Kees Cook <keescook@chromium.org> Cc: Serge Hallyn <serge.hallyn@canonical.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: "Rafael J. Wysocki" <rjw@sisk.pl> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib/syscall.c')
0 files changed, 0 insertions, 0 deletions