Remove LK_REENABLE (related to the LK_DRAIN removal).
[dragonfly.git] / sys / kern / kern_sysmsg.c
1 /*
2  * Copyright (c) 2003,2004 The DragonFly Project.  All rights reserved.
3  * 
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  * 
34  * $DragonFly: src/sys/kern/Attic/kern_sysmsg.c,v 1.6 2005/11/21 21:59:50 dillon Exp $
35  */
36
37 /*
38  * SYSMSG is our system call message encapsulation and handling subsystem.
39  * System calls are now encapsulated in messages.  A system call can execute
40  * synchronously or asynchronously.  If a system call wishes to run 
41  * asynchronously it returns EASYNC and the process records the pending system
42  * call message in p_sysmsgq.
43  *
44  * SYSMSGs work similarly to LWKT messages in that the originator can request
45  * a synchronous or asynchronous operation in isolation from the actual system
46  * call which can choose to run the system call synchronous or asynchronously
47  * (independant of what was requested).  Like LWKT messages, the synchronous
48  * path avoids all queueing operations and is almost as fast as making a 
49  * direct procedure call.
50  */
51
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/proc.h>
55 #include <sys/pioctl.h>
56 #include <sys/kernel.h>
57 #include <sys/resourcevar.h>
58 #include <sys/signalvar.h>
59 #include <sys/syscall.h>
60 #include <sys/sysctl.h>
61 #include <sys/sysent.h>
62 #include <sys/uio.h>
63 #include <sys/vmmeter.h>
64 #include <sys/malloc.h>
65 #ifdef KTRACE
66 #include <sys/ktrace.h>
67 #endif
68 #include <sys/upcall.h>
69 #include <sys/sysproto.h>
70 #include <sys/sysunion.h>
71
72 #include <vm/vm.h>
73 #include <vm/vm_param.h>
74 #include <sys/lock.h>
75 #include <vm/pmap.h>
76 #include <vm/vm_kern.h>
77 #include <vm/vm_map.h>
78 #include <vm/vm_page.h>
79 #include <vm/vm_extern.h>
80
81 #include <sys/msgport2.h>
82 #include <sys/thread2.h>
83
84 /*
85  * Sysctl to limit max in progress syscall messages per process. 0 for
86  * unlimited.
87  */
88 int max_sysmsg = 0;
89 SYSCTL_INT(_kern, OID_AUTO, max_sysmsg, CTLFLAG_RW, &max_sysmsg, 0,
90                 "Max sysmsg's a process can have running");
91
92 /*
93  * Wait for a system call message to be returned.  If NULL is passed we
94  * wait for the next ready sysmsg and return it.  We return NULL if there
95  * are no pending sysmsgs queued.
96  *
97  * NOTE: proc must be curproc.
98  *
99  * MPSAFE
100  */
101 struct sysmsg *
102 sysmsg_wait(struct lwp *lp, struct sysmsg *sysmsg, int nonblock)
103 {
104         thread_t td = lp->lwp_thread;
105
106         /*
107          * Get the next finished system call or the specified system call,
108          * blocking until it is finished (if requested).
109          */
110         if (sysmsg == NULL) {
111                 if (TAILQ_FIRST(&lp->lwp_sysmsgq) == NULL)
112                         return(NULL);
113                 if (nonblock) {
114                         if ((sysmsg = lwkt_getport(&td->td_msgport)) == NULL)
115                                 return(NULL);
116                 } else {
117                         sysmsg = lwkt_waitport(&td->td_msgport, NULL);
118                 }
119         } else {
120                 if (nonblock && !lwkt_checkmsg(&sysmsg->lmsg))
121                         return(NULL);
122                 lwkt_waitport(&td->td_msgport, &sysmsg->lmsg);
123         }
124
125         /*
126          * sysmsg is not NULL here
127          */
128         TAILQ_REMOVE(&lp->lwp_sysmsgq, sysmsg, msgq);
129         lp->lwp_nsysmsg--;
130         return(sysmsg);
131 }
132
133 /*
134  * Wait for all pending asynchronous system calls to complete, aborting them
135  * if requested (XXX).
136  */
137 void
138 sysmsg_rundown(struct lwp *lp, int doabort)
139 {
140         struct sysmsg *sysmsg;
141         thread_t td = lp->lwp_thread;
142         globaldata_t gd = td->td_gd;
143
144         while (TAILQ_FIRST(&lp->lwp_sysmsgq) != NULL) {
145                 printf("WAITSYSMSG\n");
146                 sysmsg = sysmsg_wait(lp, NULL, 0);
147                 printf("WAITSYSMSG %p\n", sysmsg);
148                 KKASSERT(sysmsg != NULL);
149                 /* XXX don't bother with pending copyouts */
150                 /* XXX we really should do pending copyouts */
151                 crit_enter_quick(td);
152                 sysmsg->lmsg.opaque.ms_sysunnext = gd->gd_freesysun;
153                 gd->gd_freesysun = (void *)sysmsg;
154                 crit_exit_quick(td);
155         }
156 }
157