From: Nikolay Borisov Date: Tue, 11 Oct 2016 20:55:05 +0000 (-0700) Subject: ipc/sem.c: add cond_resched in exit_sme X-Git-Tag: v4.9-rc1~42^2~19 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2a1613a586de91457fa93c3e468a6e2438fe52a0;p=platform%2Fkernel%2Flinux-exynos.git ipc/sem.c: add cond_resched in exit_sme In CONFIG_PREEMPT=n kernel a softlockup was observed while the for loop in exit_sem. Apparently it's possible for the loop to take quite a long time and it doesn't have a scheduling point in it. Since the codes is executing under an rcu read section this may also cause rcu stalls, which in turn block synchronize_rcu operations, which more or less de-stabilises the whole system. Fix this by introducing a cond_resched() at the beginning of the loop. So this patch fixes the following: NMI watchdog: BUG: soft lockup - CPU#10 stuck for 23s! [httpd:18119] CPU: 10 PID: 18119 Comm: httpd Tainted: G O 4.4.20-clouder2 #6 Hardware name: Supermicro X10DRi/X10DRi, BIOS 1.1 04/14/2015 task: ffff88348d695280 ti: ffff881c95550000 task.ti: ffff881c95550000 RIP: 0010:[] [] _raw_spin_lock+0x17/0x30 RSP: 0018:ffff881c95553e40 EFLAGS: 00000246 RAX: 0000000000000000 RBX: ffff883161b1eea8 RCX: 000000000000000d RDX: 0000000000000001 RSI: 000000000000000e RDI: ffff883161b1eea4 RBP: ffff881c95553ea0 R08: ffff881c95553e68 R09: ffff883fef376f88 R10: ffff881fffb58c20 R11: ffffea0072556600 R12: ffff883161b1eea0 R13: ffff88348d695280 R14: ffff883dec427000 R15: ffff8831621672a0 FS: 0000000000000000(0000) GS:ffff881fffb40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f3b3723e020 CR3: 0000000001c0a000 CR4: 00000000001406e0 Call Trace: ? exit_sem+0x7c/0x280 do_exit+0x338/0xb40 do_group_exit+0x43/0xd0 SyS_exit_group+0x14/0x20 entry_SYSCALL_64_fastpath+0x16/0x6e Link: http://lkml.kernel.org/r/1475154992-6363-1-git-send-email-kernel@kyup.com Signed-off-by: Nikolay Borisov Cc: Herton R. Krzesinski Cc: Fabian Frederick Cc: Davidlohr Bueso Cc: Manfred Spraul Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/ipc/sem.c b/ipc/sem.c index 5e318c5f749d..10b94bc59d4a 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -2105,6 +2105,8 @@ void exit_sem(struct task_struct *tsk) struct list_head tasks; int semid, i; + cond_resched(); + rcu_read_lock(); un = list_entry_rcu(ulp->list_proc.next, struct sem_undo, list_proc);