Print this page
OS-3088 need a lighterweight page invalidation mechanism for zone memcap
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/syscall/rusagesys.c
+++ new/usr/src/uts/common/syscall/rusagesys.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + * Copyright 2014 Joyent, Inc. All rights reserved.
24 25 */
25 26
26 27 /*
27 28 * Implement fast getrusage call
28 29 */
29 30
30 31 #include <sys/types.h>
31 32 #include <sys/systm.h>
32 33 #include <sys/time.h>
33 34 #include <sys/errno.h>
34 35 #include <sys/resource.h>
35 36 #include <sys/vm_usage.h>
36 37
37 38 static int
38 39 getrusage(void *user_rusage)
39 40 {
40 41 struct rusage r;
41 42 kthread_t *t = curthread;
42 43 proc_t *p = ttoproc(t);
43 44 hrtime_t snsecs, unsecs;
44 45 klwp_t *lwp;
45 46
46 47 bzero(&r, sizeof (struct rusage));
47 48
48 49 mutex_enter(&p->p_lock);
49 50
50 51 if (p->p_defunct > 0) {
51 52 r.ru_majflt = p->p_ru.majflt;
52 53 r.ru_minflt = p->p_ru.minflt;
53 54 r.ru_nswap = p->p_ru.nswap;
54 55 r.ru_inblock = p->p_ru.inblock;
55 56 r.ru_oublock = p->p_ru.oublock;
56 57 r.ru_msgsnd = p->p_ru.msgsnd;
57 58 r.ru_msgrcv = p->p_ru.msgrcv;
58 59 r.ru_nsignals = p->p_ru.nsignals;
59 60 r.ru_nvcsw = p->p_ru.nvcsw;
60 61 r.ru_nivcsw = p->p_ru.nivcsw;
61 62 }
62 63
63 64 unsecs = mstate_aggr_state(p, LMS_USER);
64 65 snsecs = mstate_aggr_state(p, LMS_SYSTEM);
65 66
66 67 do {
67 68 if (t->t_proc_flag & TP_LWPEXIT)
68 69 continue;
69 70
70 71 lwp = ttolwp(t);
71 72
72 73 r.ru_majflt += lwp->lwp_ru.majflt;
73 74 r.ru_minflt += lwp->lwp_ru.minflt;
74 75 r.ru_nswap += lwp->lwp_ru.nswap;
75 76 r.ru_inblock += lwp->lwp_ru.inblock;
76 77 r.ru_oublock += lwp->lwp_ru.oublock;
77 78 r.ru_msgsnd += lwp->lwp_ru.msgsnd;
78 79 r.ru_msgrcv += lwp->lwp_ru.msgrcv;
79 80 r.ru_nsignals += lwp->lwp_ru.nsignals;
80 81 r.ru_nvcsw += lwp->lwp_ru.nvcsw;
81 82 r.ru_nivcsw += lwp->lwp_ru.nivcsw;
82 83
83 84 } while ((t = t->t_forw) != curthread);
84 85
85 86 mutex_exit(&p->p_lock);
86 87
87 88 hrt2tv(unsecs, &r.ru_utime);
88 89 hrt2tv(snsecs, &r.ru_stime);
89 90
90 91 #ifdef _SYSCALL32_IMPL
91 92 if (get_udatamodel() == DATAMODEL_ILP32) {
92 93 struct rusage32 r32;
93 94
94 95 bzero(&r32, sizeof (struct rusage32));
95 96
96 97 r32.ru_utime.tv_sec = r.ru_utime.tv_sec;
97 98 r32.ru_utime.tv_usec = r.ru_utime.tv_usec;
98 99 r32.ru_stime.tv_sec = r.ru_stime.tv_sec;
99 100 r32.ru_stime.tv_usec = r.ru_stime.tv_usec;
100 101
101 102 r32.ru_majflt = (int32_t)r.ru_majflt;
102 103 r32.ru_minflt = (int32_t)r.ru_minflt;
103 104 r32.ru_nswap = (int32_t)r.ru_nswap;
104 105 r32.ru_inblock = (int32_t)r.ru_inblock;
105 106 r32.ru_oublock = (int32_t)r.ru_oublock;
106 107 r32.ru_msgsnd = (int32_t)r.ru_msgsnd;
107 108 r32.ru_msgrcv = (int32_t)r.ru_msgrcv;
108 109 r32.ru_nsignals = (int32_t)r.ru_nsignals;
109 110 r32.ru_nvcsw = (int32_t)r.ru_nvcsw;
110 111 r32.ru_nivcsw = (int32_t)r.ru_nivcsw;
111 112 if (copyout(&r32, user_rusage, sizeof (r32)) != 0)
112 113 return (set_errno(EFAULT));
113 114 } else
114 115 #endif /* _SYSCALL32_IMPL */
115 116
116 117 if (copyout(&r, user_rusage, sizeof (r)) != 0)
117 118 return (set_errno(EFAULT));
118 119
119 120 return (0);
120 121 }
121 122
122 123 static int
123 124 getrusage_chld(void *user_rusage)
124 125 {
125 126 struct rusage r;
126 127 kthread_t *t = curthread;
127 128 proc_t *p = ttoproc(t);
128 129 hrtime_t snsecs, unsecs;
129 130
130 131 bzero(&r, sizeof (struct rusage));
131 132
132 133 mutex_enter(&p->p_lock);
133 134
134 135 unsecs = p->p_cacct[LMS_USER];
135 136 snsecs = p->p_cacct[LMS_SYSTEM] + p->p_cacct[LMS_TRAP];
136 137
137 138 r.ru_majflt = p->p_cru.majflt;
138 139 r.ru_minflt = p->p_cru.minflt;
139 140 r.ru_nswap = p->p_cru.nswap;
140 141 r.ru_inblock = p->p_cru.inblock;
141 142 r.ru_oublock = p->p_cru.oublock;
142 143 r.ru_msgsnd = p->p_cru.msgsnd;
143 144 r.ru_msgrcv = p->p_cru.msgrcv;
144 145 r.ru_nsignals = p->p_cru.nsignals;
145 146 r.ru_nvcsw = p->p_cru.nvcsw;
146 147 r.ru_nivcsw = p->p_cru.nivcsw;
147 148
148 149 mutex_exit(&p->p_lock);
149 150
150 151 hrt2tv(unsecs, &r.ru_utime);
151 152 hrt2tv(snsecs, &r.ru_stime);
152 153 #ifdef _SYSCALL32_IMPL
153 154 if (get_udatamodel() == DATAMODEL_ILP32) {
154 155 struct rusage32 r32;
155 156
156 157 bzero(&r32, sizeof (struct rusage32));
157 158
158 159 r32.ru_utime.tv_sec = r.ru_utime.tv_sec;
159 160 r32.ru_utime.tv_usec = r.ru_utime.tv_usec;
160 161 r32.ru_stime.tv_sec = r.ru_stime.tv_sec;
161 162 r32.ru_stime.tv_usec = r.ru_stime.tv_usec;
162 163
163 164 r32.ru_majflt = (int32_t)r.ru_majflt;
164 165 r32.ru_minflt = (int32_t)r.ru_minflt;
165 166 r32.ru_nswap = (int32_t)r.ru_nswap;
166 167 r32.ru_inblock = (int32_t)r.ru_inblock;
167 168 r32.ru_oublock = (int32_t)r.ru_oublock;
168 169 r32.ru_msgsnd = (int32_t)r.ru_msgsnd;
169 170 r32.ru_msgrcv = (int32_t)r.ru_msgrcv;
170 171 r32.ru_nsignals = (int32_t)r.ru_nsignals;
171 172 r32.ru_nvcsw = (int32_t)r.ru_nvcsw;
172 173 r32.ru_nivcsw = (int32_t)r.ru_nivcsw;
173 174 if (copyout(&r32, user_rusage, sizeof (r32)) != 0)
174 175 return (set_errno(EFAULT));
175 176 } else
176 177 #endif /* _SYSCALL32_IMPL */
177 178
178 179 if (copyout(&r, user_rusage, sizeof (r)) != 0)
179 180 return (set_errno(EFAULT));
180 181
181 182 return (0);
182 183 }
183 184
184 185 static int
185 186 getrusage_lwp(void *user_rusage)
186 187 {
187 188 struct rusage r;
188 189 kthread_t *t = curthread;
189 190 klwp_t *lwp;
190 191 hrtime_t snsecs, unsecs;
191 192 struct mstate *ms;
192 193
193 194 bzero(&r, sizeof (struct rusage));
194 195
195 196 lwp = ttolwp(t);
196 197 ms = &lwp->lwp_mstate;
197 198 unsecs = ms->ms_acct[LMS_USER];
198 199 snsecs = ms->ms_acct[LMS_SYSTEM] + ms->ms_acct[LMS_TRAP];
199 200 scalehrtime(&unsecs);
200 201 scalehrtime(&snsecs);
201 202 r.ru_majflt = lwp->lwp_ru.majflt;
202 203 r.ru_minflt = lwp->lwp_ru.minflt;
203 204 r.ru_nswap = lwp->lwp_ru.nswap;
204 205 r.ru_inblock = lwp->lwp_ru.inblock;
205 206 r.ru_oublock = lwp->lwp_ru.oublock;
206 207 r.ru_msgsnd = lwp->lwp_ru.msgsnd;
207 208 r.ru_msgrcv = lwp->lwp_ru.msgrcv;
208 209 r.ru_nsignals = lwp->lwp_ru.nsignals;
209 210 r.ru_nvcsw = lwp->lwp_ru.nvcsw;
210 211 r.ru_nivcsw = lwp->lwp_ru.nivcsw;
211 212
212 213 hrt2tv(unsecs, &r.ru_utime);
213 214 hrt2tv(snsecs, &r.ru_stime);
214 215 #ifdef _SYSCALL32_IMPL
215 216 if (get_udatamodel() == DATAMODEL_ILP32) {
216 217 struct rusage32 r32;
217 218
218 219 bzero(&r32, sizeof (struct rusage32));
219 220
220 221 r32.ru_utime.tv_sec = r.ru_utime.tv_sec;
221 222 r32.ru_utime.tv_usec = r.ru_utime.tv_usec;
222 223 r32.ru_stime.tv_sec = r.ru_stime.tv_sec;
223 224 r32.ru_stime.tv_usec = r.ru_stime.tv_usec;
224 225
225 226 r32.ru_majflt = (int32_t)r.ru_majflt;
226 227 r32.ru_minflt = (int32_t)r.ru_minflt;
227 228 r32.ru_nswap = (int32_t)r.ru_nswap;
228 229 r32.ru_inblock = (int32_t)r.ru_inblock;
229 230 r32.ru_oublock = (int32_t)r.ru_oublock;
230 231 r32.ru_msgsnd = (int32_t)r.ru_msgsnd;
231 232 r32.ru_msgrcv = (int32_t)r.ru_msgrcv;
232 233 r32.ru_nsignals = (int32_t)r.ru_nsignals;
233 234 r32.ru_nvcsw = (int32_t)r.ru_nvcsw;
234 235 r32.ru_nivcsw = (int32_t)r.ru_nivcsw;
235 236 if (copyout(&r32, user_rusage, sizeof (r32)) != 0)
236 237 return (set_errno(EFAULT));
237 238 } else
238 239 #endif /* _SYSCALL32_IMPL */
239 240
240 241 if (copyout(&r, user_rusage, sizeof (r)) != 0)
241 242 return (set_errno(EFAULT));
242 243
243 244 return (0);
244 245 }
245 246
246 247 int
247 248 rusagesys(int code, void *arg1, void *arg2, void *arg3, void *arg4)
248 249 {
249 250 switch (code) {
|
↓ open down ↓ |
216 lines elided |
↑ open up ↑ |
250 251
251 252 case _RUSAGESYS_GETRUSAGE:
252 253 return (getrusage(arg1));
253 254 case _RUSAGESYS_GETRUSAGE_CHLD:
254 255 return (getrusage_chld(arg1));
255 256 case _RUSAGESYS_GETRUSAGE_LWP:
256 257 return (getrusage_lwp(arg1));
257 258 case _RUSAGESYS_GETVMUSAGE:
258 259 return (vm_getusage((uint_t)(uintptr_t)arg1, (time_t)arg2,
259 260 (vmusage_t *)arg3, (size_t *)arg4, 0));
261 + case _RUSAGESYS_INVALMAP:
262 + /*
263 + * SPARC sfmmu hat does not support HAT_CURPROC_PGUNLOAD
264 + * handling so callers on SPARC should get simple sync
265 + * handling with invalidation to all processes.
266 + */
267 +#if defined(__sparc)
268 + return (memcntl((caddr_t)arg2, (size_t)arg3, MC_SYNC,
269 + (caddr_t)(MS_ASYNC | MS_INVALIDATE), 0, 0));
270 +#else
271 + return (vm_map_inval((pid_t)(uintptr_t)arg1, (caddr_t)arg2,
272 + (size_t)arg3));
273 +#endif
260 274 default:
261 275 return (set_errno(EINVAL));
262 276 }
263 277 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX