xref: /netbsd/sys/compat/freebsd/freebsd_sched.c (revision 6550d01e)
1 /*	$NetBSD: freebsd_sched.c,v 1.19 2008/04/28 20:23:41 martin Exp $	*/
2 
3 /*-
4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9  * NASA Ames Research Center; by Matthias Scheler.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * FreeBSD compatibility module. Try to deal with scheduler related syscalls.
35  */
36 
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: freebsd_sched.c,v 1.19 2008/04/28 20:23:41 martin Exp $");
39 
40 #include <sys/param.h>
41 #include <sys/mount.h>
42 #include <sys/proc.h>
43 #include <sys/systm.h>
44 #include <sys/syscallargs.h>
45 #include <sys/kauth.h>
46 
47 #include <sys/cpu.h>
48 
49 #include <compat/freebsd/freebsd_syscallargs.h>
50 #include <compat/freebsd/freebsd_sched.h>
51 
52 int
53 freebsd_sys_yield(struct lwp *l, const void *v, register_t *retval)
54 {
55 
56 	yield();
57 	return 0;
58 }
59 
60 /*
61  * XXX: Needs adjustment to do a proper conversion.
62  */
63 static int
64 sched_freebsd2native(int freebsd_policy,
65     struct freebsd_sched_param *freebsd_params, int *native_policy,
66     struct sched_param *native_params)
67 {
68 	int error;
69 
70 	error = 0;
71 
72 	switch (freebsd_policy) {
73 	case FREEBSD_SCHED_OTHER:
74 		*native_policy = SCHED_OTHER;
75 		break;
76 
77 	case FREEBSD_SCHED_FIFO:
78 		*native_policy = SCHED_FIFO;
79 		break;
80 
81 	case FREEBSD_SCHED_RR:
82 		*native_policy = SCHED_RR;
83 		break;
84 
85 	default:
86 		error = EINVAL;
87 		break;
88 	}
89 
90 	if (freebsd_params != NULL && native_params != NULL && !error) {
91 		native_params = (struct sched_param *)freebsd_params;
92 	}
93 
94 	return (error);
95 }
96 
97 /*
98  * XXX: Needs adjustment to do a proper conversion.
99  */
100 static int
101 sched_native2freebsd(int native_policy, struct sched_param *native_params,
102     int *freebsd_policy, struct freebsd_sched_param *freebsd_params)
103 {
104 	int error;
105 
106 	error = 0;
107 
108 	switch (native_policy) {
109 	case SCHED_OTHER:
110 		*freebsd_policy = FREEBSD_SCHED_OTHER;
111 		break;
112 
113 	case SCHED_FIFO:
114 		*freebsd_policy = FREEBSD_SCHED_FIFO;
115 		break;
116 
117 	case SCHED_RR:
118 		*freebsd_policy = FREEBSD_SCHED_RR;
119 		break;
120 
121 	default:
122 		error = EINVAL;
123 		break;
124 	}
125 
126 	if (native_params != NULL && freebsd_params != NULL && !error) {
127 		freebsd_params = (struct freebsd_sched_param *)native_params;
128 	}
129 
130 	return (error);
131 }
132 
133 int
134 freebsd_sys_sched_setparam(struct lwp *l, const struct freebsd_sys_sched_setparam_args *uap, register_t *retval)
135 {
136 	/* {
137 		syscallarg(pid_t) pid;
138 		syscallarg(const struct freebsd_sched_param *) sp;
139 	} */
140 	int error, policy;
141 	struct freebsd_sched_param lp;
142 	struct sched_param sp;
143 
144 	if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL) {
145 		error = EINVAL;
146 		goto out;
147 	}
148 
149 	error = copyin(SCARG(uap, sp), &lp, sizeof(lp));
150 	if (error)
151 		goto out;
152 
153 	/* We need the current policy in FreeBSD terms. */
154 	error = do_sched_getparam(SCARG(uap, pid), 0, &policy, NULL);
155 	if (error)
156 		goto out;
157 	error = sched_native2freebsd(policy, NULL, &policy, NULL);
158 	if (error)
159 		goto out;
160 
161 	error = sched_freebsd2native(policy, &lp, &policy, &sp);
162 	if (error)
163 		goto out;
164 
165 	error = do_sched_setparam(SCARG(uap, pid), 0, policy, &sp);
166 	if (error)
167 		goto out;
168 
169  out:
170 	return error;
171 }
172 
173 int
174 freebsd_sys_sched_getparam(struct lwp *l, const struct freebsd_sys_sched_getparam_args *uap, register_t *retval)
175 {
176 	/* {
177 		syscallarg(pid_t) pid;
178 		syscallarg(struct freebsd_sched_param *) sp;
179 	} */
180 	struct freebsd_sched_param lp;
181 	struct sched_param sp;
182 	int error;
183 
184 	if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL) {
185 		error = EINVAL;
186 		goto out;
187 	}
188 
189 	error = do_sched_getparam(SCARG(uap, pid), 0, NULL, &sp);
190 	if (error)
191 		goto out;
192 
193 	error = sched_native2freebsd(0, &sp, NULL, &lp);
194 	if (error)
195 		goto out;
196 
197 	error = copyout(&lp, SCARG(uap, sp), sizeof(lp));
198 	if (error)
199 		goto out;
200 
201  out:
202 	return (error);
203 }
204 
205 int
206 freebsd_sys_sched_setscheduler(struct lwp *l, const struct freebsd_sys_sched_setscheduler_args *uap, register_t *retval)
207 {
208 	/* {
209 		syscallarg(pid_t) pid;
210 		syscallarg(int) policy;
211 		syscallarg(cont struct freebsd_sched_scheduler *) sp;
212 	} */
213 	int error, policy;
214 	struct freebsd_sched_param lp;
215 	struct sched_param sp;
216 
217 	if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL) {
218  		error = EINVAL;
219 		goto out;
220 	}
221 
222 	error = copyin(SCARG(uap, sp), &lp, sizeof(lp));
223 	if (error)
224 		goto out;
225 
226 	error = sched_freebsd2native(SCARG(uap, policy), &lp, &policy, &sp);
227 	if (error)
228 		goto out;
229 
230 	error = do_sched_setparam(SCARG(uap, pid), 0, policy, &sp);
231 	if (error)
232 		goto out;
233 
234  out:
235 	return error;
236 }
237 
238 int
239 freebsd_sys_sched_getscheduler(struct lwp *l, const struct freebsd_sys_sched_getscheduler_args *uap, register_t *retval)
240 {
241 	/* {
242 		syscallarg(pid_t) pid;
243 	} */
244 	int error, policy;
245 
246 	*retval = -1;
247 
248 	error = do_sched_getparam(SCARG(uap, pid), 0, &policy, NULL);
249 	if (error)
250 		goto out;
251 
252 	error = sched_native2freebsd(policy, NULL, &policy, NULL);
253 	if (error)
254 		goto out;
255 
256 	*retval = policy;
257 
258  out:
259 	return error;
260 }
261 
262 int
263 freebsd_sys_sched_yield(struct lwp *l, const void *v, register_t *retval)
264 {
265 
266 	yield();
267 	return 0;
268 }
269 
270 int
271 freebsd_sys_sched_get_priority_max(struct lwp *l, const struct freebsd_sys_sched_get_priority_max_args *uap, register_t *retval)
272 {
273 	/* {
274 		syscallarg(int) policy;
275 	} */
276 
277 	/*
278 	 * We can't emulate anything put the default scheduling policy.
279 	 */
280 	if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) {
281 		*retval = -1;
282 		return EINVAL;
283 	}
284 
285 	*retval = 0;
286 	return 0;
287 }
288 
289 int
290 freebsd_sys_sched_get_priority_min(struct lwp *l, const struct freebsd_sys_sched_get_priority_min_args *uap, register_t *retval)
291 {
292 	/* {
293 		syscallarg(int) policy;
294 	} */
295 
296 	/*
297 	 * We can't emulate anything put the default scheduling policy.
298 	 */
299 	if (SCARG(uap, policy) != FREEBSD_SCHED_OTHER) {
300 		*retval = -1;
301 		return EINVAL;
302 	}
303 
304 	*retval = 0;
305 	return 0;
306 }
307