From owner-svn-src-stable-12@freebsd.org Thu Jan 9 08:24:10 2020 Return-Path: Delivered-To: svn-src-stable-12@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 9A87822D594; Thu, 9 Jan 2020 08:24:10 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47tfKQ3bXMz3Hht; Thu, 9 Jan 2020 08:24:10 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 76A0A25ED1; Thu, 9 Jan 2020 08:24:10 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0098OAPd013950; Thu, 9 Jan 2020 08:24:10 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0098O96g013948; Thu, 9 Jan 2020 08:24:09 GMT (envelope-from kib@FreeBSD.org) Message-Id: <202001090824.0098O96g013948@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Thu, 9 Jan 2020 08:24:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r356542 - in stable/12/sys: kern sys X-SVN-Group: stable-12 X-SVN-Commit-Author: kib X-SVN-Commit-Paths: in stable/12/sys: kern sys X-SVN-Commit-Revision: 356542 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-12@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 12-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Jan 2020 08:24:10 -0000 Author: kib Date: Thu Jan 9 08:24:09 2020 New Revision: 356542 URL: https://svnweb.freebsd.org/changeset/base/356542 Log: MFC r356293: Rename umtxq_check_susp() to thread_check_susp(). Modified: stable/12/sys/kern/kern_thread.c stable/12/sys/kern/kern_umtx.c stable/12/sys/sys/proc.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/kern/kern_thread.c ============================================================================== --- stable/12/sys/kern/kern_thread.c Thu Jan 9 08:20:31 2020 (r356541) +++ stable/12/sys/kern/kern_thread.c Thu Jan 9 08:24:09 2020 (r356542) @@ -1044,6 +1044,49 @@ thread_suspend_check(int return_instead) return (0); } +/* + * Check for possible stops and suspensions while executing a + * casueword or similar transiently failing operation. + * + * The sleep argument controls whether the function can handle a stop + * request itself or it should return ERESTART and the request is + * proceed at the kernel/user boundary in ast. + * + * Typically, when retrying due to casueword(9) failure (rv == 1), we + * should handle the stop requests there, with exception of cases when + * the thread owns a kernel resource, for instance busied the umtx + * key, or when functions return immediately if casueword_check_susp() + * returned non-zero. On the other hand, retrying the whole lock + * operation, we better not stop there but delegate the handling to + * ast. + * + * If the request is for thread termination P_SINGLE_EXIT, we cannot + * handle it at all, and simply return EINTR. + */ +int +thread_check_susp(struct thread *td, bool sleep) +{ + struct proc *p; + int error; + + /* + * The check for TDF_NEEDSUSPCHK is racy, but it is enough to + * eventually break the lockstep loop. + */ + if ((td->td_flags & TDF_NEEDSUSPCHK) == 0) + return (0); + error = 0; + p = td->td_proc; + PROC_LOCK(p); + if (p->p_flag & P_SINGLE_EXIT) + error = EINTR; + else if (P_SHOULDSTOP(p) || + ((p->p_flag & P_TRACED) && (td->td_dbgflags & TDB_SUSPEND))) + error = sleep ? thread_suspend_check(0) : ERESTART; + PROC_UNLOCK(p); + return (error); +} + void thread_suspend_switch(struct thread *td, struct proc *p) { Modified: stable/12/sys/kern/kern_umtx.c ============================================================================== --- stable/12/sys/kern/kern_umtx.c Thu Jan 9 08:20:31 2020 (r356541) +++ stable/12/sys/kern/kern_umtx.c Thu Jan 9 08:24:09 2020 (r356542) @@ -691,48 +691,6 @@ umtxq_count_pi(struct umtx_key *key, struct umtx_q **f } /* - * Check for possible stops and suspensions while executing a umtx - * locking operation. - * - * The sleep argument controls whether the function can handle a stop - * request itself or it should return ERESTART and the request is - * proceed at the kernel/user boundary in ast. - * - * Typically, when retrying due to casueword(9) failure (rv == 1), we - * should handle the stop requests there, with exception of cases when - * the thread busied the umtx key, or when functions return - * immediately if umtxq_check_susp() returned non-zero. On the other - * hand, retrying the whole lock operation, we better not stop there - * but delegate the handling to ast. - * - * If the request is for thread termination P_SINGLE_EXIT, we cannot - * handle it at all, and simply return EINTR. - */ -static int -umtxq_check_susp(struct thread *td, bool sleep) -{ - struct proc *p; - int error; - - /* - * The check for TDF_NEEDSUSPCHK is racy, but it is enough to - * eventually break the lockstep loop. - */ - if ((td->td_flags & TDF_NEEDSUSPCHK) == 0) - return (0); - error = 0; - p = td->td_proc; - PROC_LOCK(p); - if (p->p_flag & P_SINGLE_EXIT) - error = EINTR; - else if (P_SHOULDSTOP(p) || - ((p->p_flag & P_TRACED) && (td->td_dbgflags & TDB_SUSPEND))) - error = sleep ? thread_suspend_check(0) : ERESTART; - PROC_UNLOCK(p); - return (error); -} - -/* * Wake up threads waiting on an userland object. */ @@ -1070,7 +1028,7 @@ do_lock_normal(struct thread *td, struct umutex *m, ui return (EOWNERDEAD); /* success */ } MPASS(rv == 1); - rv = umtxq_check_susp(td, false); + rv = thread_check_susp(td, false); if (rv != 0) return (rv); continue; @@ -1111,7 +1069,7 @@ do_lock_normal(struct thread *td, struct umutex *m, ui return (0); } if (rv == 1) { - rv = umtxq_check_susp(td, false); + rv = thread_check_susp(td, false); if (rv != 0) return (rv); } @@ -1124,7 +1082,7 @@ do_lock_normal(struct thread *td, struct umutex *m, ui } /* rv == 1 but not contested, likely store failure */ - rv = umtxq_check_susp(td, false); + rv = thread_check_susp(td, false); if (rv != 0) return (rv); } @@ -1167,7 +1125,7 @@ do_lock_normal(struct thread *td, struct umutex *m, ui if (rv == -1) return (EFAULT); if (rv == 1) { - rv = umtxq_check_susp(td, false); + rv = thread_check_susp(td, false); if (rv != 0) return (rv); } @@ -1189,7 +1147,7 @@ do_lock_normal(struct thread *td, struct umutex *m, ui umtx_key_release(&uq->uq_key); if (error == 0) - error = umtxq_check_susp(td, false); + error = thread_check_susp(td, false); } return (0); @@ -1224,7 +1182,7 @@ again: if (error == -1) return (EFAULT); if (error == 1) { - error = umtxq_check_susp(td, false); + error = thread_check_susp(td, false); if (error != 0) return (error); goto again; @@ -1261,7 +1219,7 @@ again: if (error == 1) { if (old != owner) return (EINVAL); - error = umtxq_check_susp(td, false); + error = thread_check_susp(td, false); if (error != 0) return (error); goto again; @@ -1316,7 +1274,7 @@ again: umtxq_unbusy(&key); umtxq_unlock(&key); umtx_key_release(&key); - error = umtxq_check_susp(td, false); + error = thread_check_susp(td, false); if (error != 0) return (error); goto again; @@ -1400,7 +1358,7 @@ do_wake2_umutex(struct thread *td, struct umutex *m, u break; } owner = old; - error = umtxq_check_susp(td, false); + error = thread_check_susp(td, false); } umtxq_lock(&key); @@ -1905,7 +1863,7 @@ do_lock_pi(struct thread *td, struct umutex *m, uint32 * to the pending signal with suspension check result. */ if (error == 0) { - error = umtxq_check_susp(td, true); + error = thread_check_susp(td, true); if (error != 0) break; } @@ -1922,7 +1880,7 @@ do_lock_pi(struct thread *td, struct umutex *m, uint32 } if (rv == 1) { if (error == 0) { - error = umtxq_check_susp(td, true); + error = thread_check_susp(td, true); if (error != 0) break; } @@ -1994,7 +1952,7 @@ do_lock_pi(struct thread *td, struct umutex *m, uint32 } if (rv == 1) { umtxq_unbusy_unlocked(&uq->uq_key); - error = umtxq_check_susp(td, true); + error = thread_check_susp(td, true); if (error != 0) break; @@ -2017,7 +1975,7 @@ do_lock_pi(struct thread *td, struct umutex *m, uint32 if (error != 0) continue; - error = umtxq_check_susp(td, false); + error = thread_check_susp(td, false); if (error != 0) break; } @@ -2063,7 +2021,7 @@ usrloop: if (error == -1) return (EFAULT); if (error == 1) { - error = umtxq_check_susp(td, true); + error = thread_check_susp(td, true); if (error != 0) return (error); goto usrloop; @@ -2150,7 +2108,7 @@ usrloop: again: error = casueword32(&m->m_owner, owner, &old, new_owner); if (error == 1) { - error = umtxq_check_susp(td, false); + error = thread_check_susp(td, false); if (error == 0) goto again; } @@ -2255,7 +2213,7 @@ do_lock_pp(struct thread *td, struct umutex *m, uint32 * error to not skip the last loop iteration. */ if (error == 0) { - error = umtxq_check_susp(td, false); + error = thread_check_susp(td, false); if (error == 0) { if (try != 0) error = EBUSY; @@ -2770,7 +2728,7 @@ do_rw_rdlock(struct thread *td, struct urwlock *rwlock umtx_key_release(&uq->uq_key); return (0); } - error = umtxq_check_susp(td, true); + error = thread_check_susp(td, true); if (error != 0) break; state = oldstate; @@ -2806,7 +2764,7 @@ do_rw_rdlock(struct thread *td, struct urwlock *rwlock goto sleep; } state = oldstate; - error = umtxq_check_susp(td, false); + error = thread_check_susp(td, false); if (error != 0) break; } @@ -2818,7 +2776,7 @@ do_rw_rdlock(struct thread *td, struct urwlock *rwlock /* state is changed while setting flags, restart */ if (!(state & wrflags)) { umtxq_unbusy_unlocked(&uq->uq_key); - error = umtxq_check_susp(td, true); + error = thread_check_susp(td, true); if (error != 0) break; continue; @@ -2886,7 +2844,7 @@ sleep: break; } state = oldstate; - error1 = umtxq_check_susp(td, false); + error1 = thread_check_susp(td, false); if (error1 != 0) { if (error == 0) error = error1; @@ -2948,7 +2906,7 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock return (0); } state = oldstate; - error = umtxq_check_susp(td, true); + error = thread_check_susp(td, true); if (error != 0) break; } @@ -2995,7 +2953,7 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock goto sleep; } state = oldstate; - error = umtxq_check_susp(td, false); + error = thread_check_susp(td, false); if (error != 0) break; } @@ -3007,7 +2965,7 @@ do_rw_wrlock(struct thread *td, struct urwlock *rwlock if ((state & URWLOCK_WRITE_OWNER) == 0 && URWLOCK_READER_COUNT(state) == 0) { umtxq_unbusy_unlocked(&uq->uq_key); - error = umtxq_check_susp(td, false); + error = thread_check_susp(td, false); if (error != 0) break; continue; @@ -3070,7 +3028,7 @@ sleep: break; } state = oldstate; - error1 = umtxq_check_susp(td, false); + error1 = thread_check_susp(td, false); /* * We are leaving the URWLOCK_WRITE_WAITERS * behind, but this should not harm the @@ -3136,7 +3094,7 @@ do_rw_unlock(struct thread *td, struct urwlock *rwlock error = EPERM; goto out; } - error = umtxq_check_susp(td, true); + error = thread_check_susp(td, true); if (error != 0) goto out; } else @@ -3156,7 +3114,7 @@ do_rw_unlock(struct thread *td, struct urwlock *rwlock error = EPERM; goto out; } - error = umtxq_check_susp(td, true); + error = thread_check_susp(td, true); if (error != 0) goto out; } else @@ -3234,7 +3192,7 @@ again: umtxq_remove(uq); umtxq_unlock(&uq->uq_key); if (rv == 1) { - rv = umtxq_check_susp(td, true); + rv = thread_check_susp(td, true); if (rv == 0) goto again; error = rv; @@ -3356,7 +3314,7 @@ again: umtx_key_release(&uq->uq_key); if (rv == -1) return (EFAULT); - rv = umtxq_check_susp(td, true); + rv = thread_check_susp(td, true); if (rv != 0) return (rv); goto again; @@ -3416,7 +3374,7 @@ do_sem2_wake(struct thread *td, struct _usem2 *sem) rv = casueword32(&sem->_count, count, &count, count & ~USEM_HAS_WAITERS); if (rv == 1) { - rv = umtxq_check_susp(td, true); + rv = thread_check_susp(td, true); if (rv != 0) break; } Modified: stable/12/sys/sys/proc.h ============================================================================== --- stable/12/sys/sys/proc.h Thu Jan 9 08:20:31 2020 (r356541) +++ stable/12/sys/sys/proc.h Thu Jan 9 08:24:09 2020 (r356542) @@ -1115,6 +1115,7 @@ void cpu_thread_swapin(struct thread *); void cpu_thread_swapout(struct thread *); struct thread *thread_alloc(int pages); int thread_alloc_stack(struct thread *, int pages); +int thread_check_susp(struct thread *td, bool sleep); void thread_cow_get_proc(struct thread *newtd, struct proc *p); void thread_cow_get(struct thread *newtd, struct thread *td); void thread_cow_free(struct thread *td);