Sun Oct 13 03:10:22 2019 UTC ()
Add sigswitch_unlock_and_switch_away(), extracted from sigswitch()

Use sigswitch_unlock_and_switch_away() whenever there is no need for
sigswitch().


(kamil)
diff -r1.369 -r1.370 src/sys/kern/kern_sig.c

cvs diff -r1.369 -r1.370 src/sys/kern/kern_sig.c (expand / switch to unified diff)

--- src/sys/kern/kern_sig.c 2019/10/12 19:57:09 1.369
+++ src/sys/kern/kern_sig.c 2019/10/13 03:10:22 1.370
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: kern_sig.c,v 1.369 2019/10/12 19:57:09 kamil Exp $ */ 1/* $NetBSD: kern_sig.c,v 1.370 2019/10/13 03:10:22 kamil Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -60,27 +60,27 @@ @@ -60,27 +60,27 @@
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE. 63 * SUCH DAMAGE.
64 * 64 *
65 * @(#)kern_sig.c 8.14 (Berkeley) 5/14/95 65 * @(#)kern_sig.c 8.14 (Berkeley) 5/14/95
66 */ 66 */
67 67
68/* 68/*
69 * Signal subsystem. 69 * Signal subsystem.
70 */ 70 */
71 71
72#include <sys/cdefs.h> 72#include <sys/cdefs.h>
73__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.369 2019/10/12 19:57:09 kamil Exp $"); 73__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.370 2019/10/13 03:10:22 kamil Exp $");
74 74
75#include "opt_ptrace.h" 75#include "opt_ptrace.h"
76#include "opt_dtrace.h" 76#include "opt_dtrace.h"
77#include "opt_compat_sunos.h" 77#include "opt_compat_sunos.h"
78#include "opt_compat_netbsd.h" 78#include "opt_compat_netbsd.h"
79#include "opt_compat_netbsd32.h" 79#include "opt_compat_netbsd32.h"
80#include "opt_pax.h" 80#include "opt_pax.h"
81 81
82#define SIGPROP /* include signal properties table */ 82#define SIGPROP /* include signal properties table */
83#include <sys/param.h> 83#include <sys/param.h>
84#include <sys/signalvar.h> 84#include <sys/signalvar.h>
85#include <sys/proc.h> 85#include <sys/proc.h>
86#include <sys/ptrace.h> 86#include <sys/ptrace.h>
@@ -116,26 +116,27 @@ sigset_t contsigmask __cacheline_aligne @@ -116,26 +116,27 @@ sigset_t contsigmask __cacheline_aligne
116sigset_t stopsigmask __cacheline_aligned; 116sigset_t stopsigmask __cacheline_aligned;
117static sigset_t vforksigmask __cacheline_aligned; 117static sigset_t vforksigmask __cacheline_aligned;
118sigset_t sigcantmask __cacheline_aligned; 118sigset_t sigcantmask __cacheline_aligned;
119 119
120static void ksiginfo_exechook(struct proc *, void *); 120static void ksiginfo_exechook(struct proc *, void *);
121static void proc_stop(struct proc *, int); 121static void proc_stop(struct proc *, int);
122static void proc_stop_done(struct proc *, int); 122static void proc_stop_done(struct proc *, int);
123static void proc_stop_callout(void *); 123static void proc_stop_callout(void *);
124static int sigchecktrace(void); 124static int sigchecktrace(void);
125static int sigpost(struct lwp *, sig_t, int, int); 125static int sigpost(struct lwp *, sig_t, int, int);
126static int sigput(sigpend_t *, struct proc *, ksiginfo_t *); 126static int sigput(sigpend_t *, struct proc *, ksiginfo_t *);
127static int sigunwait(struct proc *, const ksiginfo_t *); 127static int sigunwait(struct proc *, const ksiginfo_t *);
128static void sigswitch(int, int, bool); 128static void sigswitch(int, int, bool);
 129static void sigswitch_unlock_and_switch_away(struct lwp *);
129 130
130static void sigacts_poolpage_free(struct pool *, void *); 131static void sigacts_poolpage_free(struct pool *, void *);
131static void *sigacts_poolpage_alloc(struct pool *, int); 132static void *sigacts_poolpage_alloc(struct pool *, int);
132 133
133void (*sendsig_sigcontext_vec)(const struct ksiginfo *, const sigset_t *); 134void (*sendsig_sigcontext_vec)(const struct ksiginfo *, const sigset_t *);
134int (*coredump_vec)(struct lwp *, const char *) = 135int (*coredump_vec)(struct lwp *, const char *) =
135 (int (*)(struct lwp *, const char *))enosys; 136 (int (*)(struct lwp *, const char *))enosys;
136 137
137/* 138/*
138 * DTrace SDT provider definitions 139 * DTrace SDT provider definitions
139 */ 140 */
140SDT_PROVIDER_DECLARE(proc); 141SDT_PROVIDER_DECLARE(proc);
141SDT_PROBE_DEFINE3(proc, kernel, , signal__send, 142SDT_PROBE_DEFINE3(proc, kernel, , signal__send,
@@ -922,30 +923,31 @@ repeat: @@ -922,30 +923,31 @@ repeat:
922 */ 923 */
923 if (__predict_false(ISSET(p->p_sflag, PS_WEXIT))) { 924 if (__predict_false(ISSET(p->p_sflag, PS_WEXIT))) {
924 mutex_exit(p->p_lock); 925 mutex_exit(p->p_lock);
925 mutex_exit(proc_lock); 926 mutex_exit(proc_lock);
926 lwp_exit(l); 927 lwp_exit(l);
927 panic("trapsignal"); 928 panic("trapsignal");
928 /* NOTREACHED */ 929 /* NOTREACHED */
929 } 930 }
930 931
931 /* 932 /*
932 * The process is already stopping. 933 * The process is already stopping.
933 */ 934 */
934 if ((p->p_sflag & PS_STOPPING) != 0) { 935 if ((p->p_sflag & PS_STOPPING) != 0) {
935 sigswitch(0, p->p_xsig, true); 936 mutex_exit(proc_lock);
 937 sigswitch_unlock_and_switch_away(l);
936 mutex_enter(proc_lock); 938 mutex_enter(proc_lock);
937 mutex_enter(p->p_lock); 939 mutex_enter(p->p_lock);
938 goto repeat; /* XXX */ 940 goto repeat;
939 } 941 }
940 942
941 mask = &l->l_sigmask; 943 mask = &l->l_sigmask;
942 ps = p->p_sigacts; 944 ps = p->p_sigacts;
943 action = SIGACTION_PS(ps, signo).sa_handler; 945 action = SIGACTION_PS(ps, signo).sa_handler;
944 946
945 if (ISSET(p->p_slflag, PSL_TRACED) && 947 if (ISSET(p->p_slflag, PSL_TRACED) &&
946 !(p->p_pptr == p->p_opptr && ISSET(p->p_lflag, PL_PPWAIT)) && 948 !(p->p_pptr == p->p_opptr && ISSET(p->p_lflag, PL_PPWAIT)) &&
947 p->p_xsig != SIGKILL && 949 p->p_xsig != SIGKILL &&
948 !sigismember(&p->p_sigpend.sp_set, SIGKILL)) { 950 !sigismember(&p->p_sigpend.sp_set, SIGKILL)) {
949 p->p_xsig = signo; 951 p->p_xsig = signo;
950 p->p_sigctx.ps_faked = true; 952 p->p_sigctx.ps_faked = true;
951 p->p_sigctx.ps_lwp = ksi->ksi_lid; 953 p->p_sigctx.ps_lwp = ksi->ksi_lid;
@@ -1632,30 +1634,31 @@ repeat: @@ -1632,30 +1634,31 @@ repeat:
1632 * If there's a pending SIGKILL process it immediately. 1634 * If there's a pending SIGKILL process it immediately.
1633 */ 1635 */
1634 if (p->p_xsig == SIGKILL || 1636 if (p->p_xsig == SIGKILL ||
1635 sigismember(&p->p_sigpend.sp_set, SIGKILL)) { 1637 sigismember(&p->p_sigpend.sp_set, SIGKILL)) {
1636 mutex_exit(p->p_lock); 1638 mutex_exit(p->p_lock);
1637 mutex_exit(proc_lock); 1639 mutex_exit(proc_lock);
1638 return; 1640 return;
1639 } 1641 }
1640 1642
1641 /* 1643 /*
1642 * The process is already stopping. 1644 * The process is already stopping.
1643 */ 1645 */
1644 if ((p->p_sflag & PS_STOPPING) != 0) { 1646 if ((p->p_sflag & PS_STOPPING) != 0) {
1645 sigswitch(0, p->p_xsig, true); 1647 mutex_exit(proc_lock);
 1648 sigswitch_unlock_and_switch_away(l);
1646 mutex_enter(proc_lock); 1649 mutex_enter(proc_lock);
1647 mutex_enter(p->p_lock); 1650 mutex_enter(p->p_lock);
1648 goto repeat; /* XXX */ 1651 goto repeat;
1649 } 1652 }
1650 1653
1651 KSI_INIT_TRAP(&ksi); 1654 KSI_INIT_TRAP(&ksi);
1652 ksi.ksi_lid = l->l_lid; 1655 ksi.ksi_lid = l->l_lid;
1653 ksi.ksi_signo = signo; 1656 ksi.ksi_signo = signo;
1654 ksi.ksi_code = code; 1657 ksi.ksi_code = code;
1655 ksi.ksi_pe_report_event = pe_report_event; 1658 ksi.ksi_pe_report_event = pe_report_event;
1656 1659
1657 CTASSERT(sizeof(ksi.ksi_pe_other_pid) == sizeof(ksi.ksi_pe_lwp)); 1660 CTASSERT(sizeof(ksi.ksi_pe_other_pid) == sizeof(ksi.ksi_pe_lwp));
1658 ksi.ksi_pe_other_pid = entity; 1661 ksi.ksi_pe_other_pid = entity;
1659 1662
1660 /* Needed for ktrace */ 1663 /* Needed for ktrace */
1661 ps = p->p_sigacts; 1664 ps = p->p_sigacts;
@@ -1682,27 +1685,26 @@ repeat: @@ -1682,27 +1685,26 @@ repeat:
1682 else 1685 else
1683 ktrpsig(signo, action, mask, &ksi); 1686 ktrpsig(signo, action, mask, &ksi);
1684 } 1687 }
1685} 1688}
1686 1689
1687/* 1690/*
1688 * Stop the current process and switch away when being stopped or traced. 1691 * Stop the current process and switch away when being stopped or traced.
1689 */ 1692 */
1690static void 1693static void
1691sigswitch(int ppmask, int signo, bool proc_lock_held) 1694sigswitch(int ppmask, int signo, bool proc_lock_held)
1692{ 1695{
1693 struct lwp *l = curlwp; 1696 struct lwp *l = curlwp;
1694 struct proc *p = l->l_proc; 1697 struct proc *p = l->l_proc;
1695 int biglocks; 
1696 1698
1697 KASSERT(mutex_owned(p->p_lock)); 1699 KASSERT(mutex_owned(p->p_lock));
1698 KASSERT(l->l_stat == LSONPROC); 1700 KASSERT(l->l_stat == LSONPROC);
1699 KASSERT(p->p_nrlwps > 0); 1701 KASSERT(p->p_nrlwps > 0);
1700 1702
1701 if (proc_lock_held) { 1703 if (proc_lock_held) {
1702 KASSERT(mutex_owned(proc_lock)); 1704 KASSERT(mutex_owned(proc_lock));
1703 } else { 1705 } else {
1704 KASSERT(!mutex_owned(proc_lock)); 1706 KASSERT(!mutex_owned(proc_lock));
1705 } 1707 }
1706 1708
1707 /* 1709 /*
1708 * If we are exiting, demise now. 1710 * If we are exiting, demise now.
@@ -1742,30 +1744,46 @@ sigswitch(int ppmask, int signo, bool pr @@ -1742,30 +1744,46 @@ sigswitch(int ppmask, int signo, bool pr
1742 } 1744 }
1743 1745
1744 if (p->p_nrlwps == 1 && (p->p_sflag & PS_STOPPING) != 0) { 1746 if (p->p_nrlwps == 1 && (p->p_sflag & PS_STOPPING) != 0) {
1745 /* 1747 /*
1746 * Note that proc_stop_done() can drop 1748 * Note that proc_stop_done() can drop
1747 * p->p_lock briefly. 1749 * p->p_lock briefly.
1748 */ 1750 */
1749 proc_stop_done(p, ppmask); 1751 proc_stop_done(p, ppmask);
1750 } 1752 }
1751 1753
1752 mutex_exit(proc_lock); 1754 mutex_exit(proc_lock);
1753 } 1755 }
1754 1756
1755 /* 1757 sigswitch_unlock_and_switch_away(l);
1756 * Unlock and switch away. 1758}
1757 */ 1759
 1760/*
 1761 * Unlock and switch away.
 1762 */
 1763static void
 1764sigswitch_unlock_and_switch_away(struct lwp *l)
 1765{
 1766 struct proc *p;
 1767 int biglocks;
 1768
 1769 p = l->l_proc;
 1770
 1771 KASSERT(mutex_owned(p->p_lock));
1758 KASSERT(!mutex_owned(proc_lock)); 1772 KASSERT(!mutex_owned(proc_lock));
 1773
 1774 KASSERT(l->l_stat == LSONPROC);
 1775 KASSERT(p->p_nrlwps > 0);
 1776
1759 KERNEL_UNLOCK_ALL(l, &biglocks); 1777 KERNEL_UNLOCK_ALL(l, &biglocks);
1760 if (p->p_stat == SSTOP || (p->p_sflag & PS_STOPPING) != 0) { 1778 if (p->p_stat == SSTOP || (p->p_sflag & PS_STOPPING) != 0) {
1761 p->p_nrlwps--; 1779 p->p_nrlwps--;
1762 lwp_lock(l); 1780 lwp_lock(l);
1763 KASSERT(l->l_stat == LSONPROC || l->l_stat == LSSLEEP); 1781 KASSERT(l->l_stat == LSONPROC || l->l_stat == LSSLEEP);
1764 l->l_stat = LSSTOP; 1782 l->l_stat = LSSTOP;
1765 lwp_unlock(l); 1783 lwp_unlock(l);
1766 } 1784 }
1767 1785
1768 mutex_exit(p->p_lock); 1786 mutex_exit(p->p_lock);
1769 lwp_lock(l); 1787 lwp_lock(l);
1770 mi_switch(l); 1788 mi_switch(l);
1771 KERNEL_LOCK(biglocks, l); 1789 KERNEL_LOCK(biglocks, l);
@@ -1835,27 +1853,27 @@ issignal(struct lwp *l) @@ -1835,27 +1853,27 @@ issignal(struct lwp *l)
1835 1853
1836 for (;;) { 1854 for (;;) {
1837 /* Discard any signals that we have decided not to take. */ 1855 /* Discard any signals that we have decided not to take. */
1838 if (signo != 0) { 1856 if (signo != 0) {
1839 (void)sigget(sp, NULL, signo, NULL); 1857 (void)sigget(sp, NULL, signo, NULL);
1840 } 1858 }
1841 1859
1842 /* 1860 /*
1843 * If the process is stopped/stopping, then stop ourselves 1861 * If the process is stopped/stopping, then stop ourselves
1844 * now that we're on the kernel/userspace boundary. When 1862 * now that we're on the kernel/userspace boundary. When
1845 * we awaken, check for a signal from the debugger. 1863 * we awaken, check for a signal from the debugger.
1846 */ 1864 */
1847 if (p->p_stat == SSTOP || (p->p_sflag & PS_STOPPING) != 0) { 1865 if (p->p_stat == SSTOP || (p->p_sflag & PS_STOPPING) != 0) {
1848 sigswitch(PS_NOCLDSTOP, 0, false); 1866 sigswitch_unlock_and_switch_away(l);
1849 mutex_enter(p->p_lock); 1867 mutex_enter(p->p_lock);
1850 signo = sigchecktrace(); 1868 signo = sigchecktrace();
1851 } else if (p->p_stat == SACTIVE) 1869 } else if (p->p_stat == SACTIVE)
1852 signo = sigchecktrace(); 1870 signo = sigchecktrace();
1853 else 1871 else
1854 signo = 0; 1872 signo = 0;
1855 1873
1856 /* Signals from the debugger are "out of band". */ 1874 /* Signals from the debugger are "out of band". */
1857 sp = NULL; 1875 sp = NULL;
1858 1876
1859 /* 1877 /*
1860 * If the debugger didn't provide a signal, find a pending 1878 * If the debugger didn't provide a signal, find a pending
1861 * signal from our set. Check per-LWP signals first, and 1879 * signal from our set. Check per-LWP signals first, and
@@ -2517,29 +2535,29 @@ repeat: @@ -2517,29 +2535,29 @@ repeat:
2517 * If we are no longer traced, abandon this event signal. 2535 * If we are no longer traced, abandon this event signal.
2518 * 2536 *
2519 * This avoids killing a process after detaching the debugger. 2537 * This avoids killing a process after detaching the debugger.
2520 */ 2538 */
2521 if (__predict_false(!ISSET(p->p_slflag, PSL_TRACED))) { 2539 if (__predict_false(!ISSET(p->p_slflag, PSL_TRACED))) {
2522 mutex_exit(p->p_lock); 2540 mutex_exit(p->p_lock);
2523 return; 2541 return;
2524 } 2542 }
2525 2543
2526 /* 2544 /*
2527 * The process is already stopping. 2545 * The process is already stopping.
2528 */ 2546 */
2529 if ((p->p_sflag & PS_STOPPING) != 0) { 2547 if ((p->p_sflag & PS_STOPPING) != 0) {
2530 sigswitch(0, p->p_xsig, false); 2548 sigswitch_unlock_and_switch_away(l);
2531 mutex_enter(p->p_lock); 2549 mutex_enter(p->p_lock);
2532 goto repeat; /* XXX */ 2550 goto repeat;
2533 } 2551 }
2534 2552
2535 /* Needed for ktrace */ 2553 /* Needed for ktrace */
2536 ps = p->p_sigacts; 2554 ps = p->p_sigacts;
2537 action = SIGACTION_PS(ps, signo).sa_handler; 2555 action = SIGACTION_PS(ps, signo).sa_handler;
2538 mask = &l->l_sigmask; 2556 mask = &l->l_sigmask;
2539 2557
2540 p->p_xsig = signo; 2558 p->p_xsig = signo;
2541 p->p_sigctx.ps_lwp = ksi.ksi_lid; 2559 p->p_sigctx.ps_lwp = ksi.ksi_lid;
2542 p->p_sigctx.ps_info = ksi.ksi_info; 2560 p->p_sigctx.ps_info = ksi.ksi_info;
2543 sigswitch(0, signo, false); 2561 sigswitch(0, signo, false);
2544 2562
2545 if (ktrpoint(KTR_PSIG)) { 2563 if (ktrpoint(KTR_PSIG)) {