kernel - Fix nstopped SMP race during core dump
authorMatthew Dillon <dillon@apollo.backplane.com>
Thu, 29 Nov 2018 06:56:24 +0000 (22:56 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 29 Nov 2018 06:56:24 +0000 (22:56 -0800)
* During a process core dump, p->p_nstopped can be adjusted without
  holding p->p_token, resulting in a SMP race which can cause
  p_nstopped to become permanently desynchronized and deadlock the
  process.

* Be robust in a p_nstopped handling case in kern_exit, just in case.

sys/kern/kern_exit.c
sys/kern/kern_synch.c

index 919df8b..b70307d 100644 (file)
@@ -226,7 +226,7 @@ killalllwps(int forexec)
        /*
         * Undo temporary stopped state
         */
-       if (fakestop) {
+       if (fakestop && (lp->lwp_mpflags & LWP_MP_WSTOP)) {
                atomic_clear_int(&lp->lwp_mpflags, LWP_MP_WSTOP);
                --p->p_nstopped;
        }
index d462d9b..4d0ea1b 100644 (file)
@@ -597,10 +597,13 @@ tsleep(const volatile void *ident, int flags, const char *wmesg, int timo)
                 * this juncture because that will mess-up the state the
                 * coredump is trying to save.
                 */
-               if (p->p_stat == SCORE &&
-                   (lp->lwp_mpflags & LWP_MP_WSTOP) == 0) {
-                       atomic_set_int(&lp->lwp_mpflags, LWP_MP_WSTOP);
-                       ++p->p_nstopped;
+               if (p->p_stat == SCORE) {
+                       lwkt_gettoken(&p->p_token);
+                       if ((lp->lwp_mpflags & LWP_MP_WSTOP) == 0) {
+                               atomic_set_int(&lp->lwp_mpflags, LWP_MP_WSTOP);
+                               ++p->p_nstopped;
+                       }
+                       lwkt_reltoken(&p->p_token);
                }
 
                /*