kern_synch.c revision 1.177.2.6 1 /* $NetBSD: kern_synch.c,v 1.177.2.6 2007/02/21 12:05:48 yamt Exp $ */
2
3 /*-
4 * Copyright (c) 1999, 2000, 2004, 2006, 2007 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 Charles M. Hannum, Andrew Doran and
10 * Daniel Sieger.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the NetBSD
23 * Foundation, Inc. and its contributors.
24 * 4. Neither the name of The NetBSD Foundation nor the names of its
25 * contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41 /*-
42 * Copyright (c) 1982, 1986, 1990, 1991, 1993
43 * The Regents of the University of California. All rights reserved.
44 * (c) UNIX System Laboratories, Inc.
45 * All or some portions of this file are derived from material licensed
46 * to the University of California by American Telephone and Telegraph
47 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
48 * the permission of UNIX System Laboratories, Inc.
49 *
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 * 1. Redistributions of source code must retain the above copyright
54 * notice, this list of conditions and the following disclaimer.
55 * 2. Redistributions in binary form must reproduce the above copyright
56 * notice, this list of conditions and the following disclaimer in the
57 * documentation and/or other materials provided with the distribution.
58 * 3. Neither the name of the University nor the names of its contributors
59 * may be used to endorse or promote products derived from this software
60 * without specific prior written permission.
61 *
62 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
63 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
64 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
66 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
72 * SUCH DAMAGE.
73 *
74 * @(#)kern_synch.c 8.9 (Berkeley) 5/19/95
75 */
76
77 #include <sys/cdefs.h>
78 __KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.177.2.6 2007/02/21 12:05:48 yamt Exp $");
79
80 #include "opt_kstack.h"
81 #include "opt_lockdebug.h"
82 #include "opt_multiprocessor.h"
83 #include "opt_perfctrs.h"
84
85 #define __MUTEX_PRIVATE
86
87 #include <sys/param.h>
88 #include <sys/systm.h>
89 #include <sys/proc.h>
90 #include <sys/kernel.h>
91 #if defined(PERFCTRS)
92 #include <sys/pmc.h>
93 #endif
94 #include <sys/resourcevar.h>
95 #include <sys/sched.h>
96 #include <sys/sleepq.h>
97 #include <sys/lockdebug.h>
98
99 #include <uvm/uvm_extern.h>
100
101 #include <machine/cpu.h>
102
103 int lbolt; /* once a second sleep address */
104
105 /*
106 * The global scheduler state.
107 */
108 kmutex_t sched_mutex; /* global sched state mutex */
109
110 void sched_unsleep(struct lwp *);
111
112 syncobj_t sleep_syncobj = {
113 SOBJ_SLEEPQ_SORTED,
114 sleepq_unsleep,
115 sleepq_changepri
116 };
117
118 syncobj_t sched_syncobj = {
119 SOBJ_SLEEPQ_SORTED,
120 sched_unsleep,
121 sched_changepri
122 };
123
124 /*
125 * During autoconfiguration or after a panic, a sleep will simply lower the
126 * priority briefly to allow interrupts, then return. The priority to be
127 * used (safepri) is machine-dependent, thus this value is initialized and
128 * maintained in the machine-dependent layers. This priority will typically
129 * be 0, or the lowest priority that is safe for use on the interrupt stack;
130 * it can be made higher to block network software interrupts after panics.
131 */
132 int safepri;
133
134 /*
135 * OBSOLETE INTERFACE
136 *
137 * General sleep call. Suspends the current process until a wakeup is
138 * performed on the specified identifier. The process will then be made
139 * runnable with the specified priority. Sleeps at most timo/hz seconds (0
140 * means no timeout). If pri includes PCATCH flag, signals are checked
141 * before and after sleeping, else signals are not checked. Returns 0 if
142 * awakened, EWOULDBLOCK if the timeout expires. If PCATCH is set and a
143 * signal needs to be delivered, ERESTART is returned if the current system
144 * call should be restarted if possible, and EINTR is returned if the system
145 * call should be interrupted by the signal (return EINTR).
146 *
147 * The interlock is held until we are on a sleep queue. The interlock will
148 * be locked before returning back to the caller unless the PNORELOCK flag
149 * is specified, in which case the interlock will always be unlocked upon
150 * return.
151 */
152 int
153 ltsleep(wchan_t ident, int priority, const char *wmesg, int timo,
154 volatile struct simplelock *interlock)
155 {
156 struct lwp *l = curlwp;
157 sleepq_t *sq;
158 int error, catch;
159
160 if (sleepq_dontsleep(l)) {
161 (void)sleepq_abort(NULL, 0);
162 if ((priority & PNORELOCK) != 0)
163 simple_unlock(interlock);
164 return 0;
165 }
166
167 sq = sleeptab_lookup(&sleeptab, ident);
168 sleepq_enter(sq, l);
169
170 if (interlock != NULL) {
171 LOCK_ASSERT(simple_lock_held(interlock));
172 simple_unlock(interlock);
173 }
174
175 catch = priority & PCATCH;
176 sleepq_block(sq, priority & PRIMASK, ident, wmesg, timo, catch,
177 &sleep_syncobj);
178 error = sleepq_unblock(timo, catch);
179
180 if (interlock != NULL && (priority & PNORELOCK) == 0)
181 simple_lock(interlock);
182
183 return error;
184 }
185
186 /*
187 * General sleep call for situations where a wake-up is not expected.
188 */
189 int
190 kpause(const char *wmesg, boolean_t intr, int timo, kmutex_t *mtx)
191 {
192 struct lwp *l = curlwp;
193 sleepq_t *sq;
194 int error;
195
196 if (sleepq_dontsleep(l))
197 return sleepq_abort(NULL, 0);
198
199 if (mtx != NULL)
200 mutex_exit(mtx);
201 sq = sleeptab_lookup(&sleeptab, l);
202 sleepq_enter(sq, l);
203 sleepq_block(sq, sched_kpri(l), l, wmesg, timo, intr, &sleep_syncobj);
204 error = sleepq_unblock(timo, intr);
205 if (mtx != NULL)
206 mutex_enter(mtx);
207
208 return error;
209 }
210
211 /*
212 * OBSOLETE INTERFACE
213 *
214 * Make all processes sleeping on the specified identifier runnable.
215 */
216 void
217 wakeup(wchan_t ident)
218 {
219 sleepq_t *sq;
220
221 if (cold)
222 return;
223
224 sq = sleeptab_lookup(&sleeptab, ident);
225 sleepq_wake(sq, ident, (u_int)-1);
226 }
227
228 /*
229 * OBSOLETE INTERFACE
230 *
231 * Make the highest priority process first in line on the specified
232 * identifier runnable.
233 */
234 void
235 wakeup_one(wchan_t ident)
236 {
237 sleepq_t *sq;
238
239 if (cold)
240 return;
241
242 sq = sleeptab_lookup(&sleeptab, ident);
243 sleepq_wake(sq, ident, 1);
244 }
245
246
247 /*
248 * General yield call. Puts the current process back on its run queue and
249 * performs a voluntary context switch. Should only be called when the
250 * current process explicitly requests it (eg sched_yield(2) in compat code).
251 */
252 void
253 yield(void)
254 {
255 struct lwp *l = curlwp;
256
257 KERNEL_UNLOCK_ALL(l, &l->l_biglocks);
258 lwp_lock(l);
259 if (l->l_stat == LSONPROC) {
260 KASSERT(lwp_locked(l, &sched_mutex));
261 l->l_priority = l->l_usrpri;
262 }
263 l->l_nvcsw++;
264 mi_switch(l, NULL);
265 KERNEL_LOCK(l->l_biglocks, l);
266 }
267
268 /*
269 * General preemption call. Puts the current process back on its run queue
270 * and performs an involuntary context switch.
271 */
272 void
273 preempt(void)
274 {
275 struct lwp *l = curlwp;
276
277 KERNEL_UNLOCK_ALL(l, &l->l_biglocks);
278 lwp_lock(l);
279 if (l->l_stat == LSONPROC) {
280 KASSERT(lwp_locked(l, &sched_mutex));
281 l->l_priority = l->l_usrpri;
282 }
283 l->l_nivcsw++;
284 (void)mi_switch(l, NULL);
285 KERNEL_LOCK(l->l_biglocks, l);
286 }
287
288 /*
289 * sched_switch_unlock: update 'curlwp' and release old lwp.
290 */
291
292 void
293 sched_switch_unlock(struct lwp *old, struct lwp *new)
294 {
295
296 KASSERT(old == NULL || old == curlwp);
297
298 if (old != NULL) {
299 LOCKDEBUG_BARRIER(old->l_mutex, 1);
300 } else {
301 LOCKDEBUG_BARRIER(NULL, 1);
302 }
303
304 curlwp = new;
305 if (old != NULL) {
306 lwp_unlock(old);
307 }
308 spl0();
309 }
310
311 /*
312 * Compute the amount of time during which the current lwp was running.
313 *
314 * - update l_rtime unless it's an idle lwp.
315 * - update spc_runtime for the next lwp.
316 */
317
318 static inline void
319 updatertime(struct lwp *l, struct schedstate_percpu *spc)
320 {
321 struct timeval tv;
322 long s, u;
323
324 if ((l->l_flag & L_IDLE) != 0) {
325 microtime(&spc->spc_runtime);
326 return;
327 }
328
329 microtime(&tv);
330 u = l->l_rtime.tv_usec + (tv.tv_usec - spc->spc_runtime.tv_usec);
331 s = l->l_rtime.tv_sec + (tv.tv_sec - spc->spc_runtime.tv_sec);
332 if (u < 0) {
333 u += 1000000;
334 s--;
335 } else if (u >= 1000000) {
336 u -= 1000000;
337 s++;
338 }
339 l->l_rtime.tv_usec = u;
340 l->l_rtime.tv_sec = s;
341
342 spc->spc_runtime = tv;
343 }
344
345 /*
346 * The machine independent parts of context switch. Switch to "new"
347 * if non-NULL, otherwise let cpu_switch choose the next lwp.
348 *
349 * Returns 1 if another process was actually run.
350 */
351 int
352 mi_switch(struct lwp *l, struct lwp *newl)
353 {
354 struct schedstate_percpu *spc;
355 int retval, oldspl;
356
357 LOCK_ASSERT(lwp_locked(l, NULL));
358
359 #ifdef LOCKDEBUG
360 spinlock_switchcheck();
361 simple_lock_switchcheck();
362 #endif
363 #ifdef KSTACK_CHECK_MAGIC
364 kstack_check_magic(l);
365 #endif
366
367 /*
368 * It's safe to read the per CPU schedstate unlocked here, as all we
369 * are after is the run time and that's guarenteed to have been last
370 * updated by this CPU.
371 */
372 KDASSERT(l->l_cpu == curcpu());
373 spc = &l->l_cpu->ci_schedstate;
374
375 /*
376 * XXXSMP If we are using h/w performance counters, save context.
377 */
378 #if PERFCTRS
379 if (PMC_ENABLED(l->l_proc)) {
380 pmc_save_context(l->l_proc);
381 }
382 #endif
383
384 /*
385 * If on the CPU and we have gotten this far, then we must yield.
386 */
387 KASSERT(l->l_stat != LSRUN);
388 if (l->l_stat == LSONPROC) {
389 KASSERT(lwp_locked(l, &sched_mutex));
390 l->l_stat = LSRUN;
391 if ((l->l_flag & L_IDLE) == 0) {
392 sched_enqueue(l);
393 }
394 }
395 uvmexp.swtch++;
396
397 /*
398 * Process is about to yield the CPU; clear the appropriate
399 * scheduling flags.
400 */
401 spc->spc_flags &= ~SPCF_SWITCHCLEAR;
402
403 LOCKDEBUG_BARRIER(l->l_mutex, 1);
404
405 /*
406 * Switch to the new LWP if necessary.
407 * When we run again, we'll return back here.
408 */
409 oldspl = MUTEX_SPIN_OLDSPL(l->l_cpu);
410
411 /*
412 * Acquire the sched_mutex if necessary.
413 */
414 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
415 if (l->l_mutex != &sched_mutex) {
416 mutex_enter(&sched_mutex);
417 }
418 #endif
419
420 if (newl == NULL) {
421 newl = sched_nextlwp();
422 }
423 if (newl != NULL) {
424 KASSERT(lwp_locked(newl, &sched_mutex));
425 sched_dequeue(newl);
426 } else {
427 newl = l->l_cpu->ci_data.cpu_idlelwp;
428 KASSERT(newl != NULL);
429 }
430
431 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
432 if (l->l_mutex != &sched_mutex) {
433 mutex_exit(&sched_mutex);
434 }
435 #endif
436
437 newl->l_stat = LSONPROC;
438 updatertime(l, spc);
439 if (l != newl) {
440 struct lwp *prevlwp;
441
442 uvmexp.swtch++;
443 pmap_deactivate(l);
444 newl->l_cpu = l->l_cpu;
445 prevlwp = cpu_switchto(l, newl);
446 sched_switch_unlock(prevlwp, l);
447 pmap_activate(l);
448 retval = 1;
449 } else {
450 sched_switch_unlock(l, l);
451 retval = 0;
452 }
453
454 KASSERT(l == curlwp);
455 KASSERT(l->l_stat == LSONPROC);
456
457 /*
458 * XXXSMP If we are using h/w performance counters, restore context.
459 */
460 #if PERFCTRS
461 if (PMC_ENABLED(l->l_proc)) {
462 pmc_restore_context(l->l_proc);
463 }
464 #endif
465
466 /*
467 * We're running again; record our new start time. We might
468 * be running on a new CPU now, so don't use the cached
469 * schedstate_percpu pointer.
470 */
471 KDASSERT(l->l_cpu == curcpu());
472
473 (void)splsched();
474 splx(oldspl);
475 return retval;
476 }
477
478 /*
479 * Change process state to be runnable, placing it on the run queue if it is
480 * in memory, and awakening the swapper if it isn't in memory.
481 *
482 * Call with the process and LWP locked. Will return with the LWP unlocked.
483 */
484 void
485 setrunnable(struct lwp *l)
486 {
487 struct proc *p = l->l_proc;
488 sigset_t *ss;
489
490 KASSERT((l->l_flag & L_IDLE) == 0);
491 LOCK_ASSERT(mutex_owned(&p->p_smutex));
492 LOCK_ASSERT(lwp_locked(l, NULL));
493
494 switch (l->l_stat) {
495 case LSSTOP:
496 /*
497 * If we're being traced (possibly because someone attached us
498 * while we were stopped), check for a signal from the debugger.
499 */
500 if ((p->p_slflag & PSL_TRACED) != 0 && p->p_xstat != 0) {
501 if ((sigprop[p->p_xstat] & SA_TOLWP) != 0)
502 ss = &l->l_sigpend.sp_set;
503 else
504 ss = &p->p_sigpend.sp_set;
505 sigaddset(ss, p->p_xstat);
506 signotify(l);
507 }
508 p->p_nrlwps++;
509 break;
510 case LSSUSPENDED:
511 l->l_flag &= ~L_WSUSPEND;
512 p->p_nrlwps++;
513 break;
514 case LSSLEEP:
515 KASSERT(l->l_wchan != NULL);
516 break;
517 default:
518 panic("setrunnable: lwp %p state was %d", l, l->l_stat);
519 }
520
521 /*
522 * If the LWP was sleeping interruptably, then it's OK to start it
523 * again. If not, mark it as still sleeping.
524 */
525 if (l->l_wchan != NULL) {
526 l->l_stat = LSSLEEP;
527 if ((l->l_flag & L_SINTR) != 0)
528 lwp_unsleep(l);
529 else {
530 lwp_unlock(l);
531 #ifdef DIAGNOSTIC
532 panic("setrunnable: !L_SINTR");
533 #endif
534 }
535 return;
536 }
537
538 LOCK_ASSERT(lwp_locked(l, &sched_mutex));
539
540 /*
541 * If the LWP is still on the CPU, mark it as LSONPROC. It may be
542 * about to call mi_switch(), in which case it will yield.
543 *
544 * XXXSMP Will need to change for preemption.
545 */
546 #ifdef MULTIPROCESSOR
547 if (l->l_cpu->ci_curlwp == l) {
548 #else
549 if (l == curlwp) {
550 #endif
551 l->l_stat = LSONPROC;
552 l->l_slptime = 0;
553 lwp_unlock(l);
554 return;
555 }
556
557 /*
558 * Set the LWP runnable. If it's swapped out, we need to wake the swapper
559 * to bring it back in. Otherwise, enter it into a run queue.
560 */
561 sched_setrunnable(l);
562 l->l_stat = LSRUN;
563 l->l_slptime = 0;
564
565 if (l->l_flag & L_INMEM) {
566 sched_enqueue(l);
567 resched_cpu(l, l->l_priority);
568 lwp_unlock(l);
569 } else {
570 lwp_unlock(l);
571 uvm_kick_scheduler();
572 }
573 }
574
575 /*
576 * suspendsched:
577 *
578 * Convert all non-L_SYSTEM LSSLEEP or LSRUN LWPs to LSSUSPENDED.
579 */
580 void
581 suspendsched(void)
582 {
583 #ifdef MULTIPROCESSOR
584 CPU_INFO_ITERATOR cii;
585 struct cpu_info *ci;
586 #endif
587 struct lwp *l;
588 struct proc *p;
589
590 /*
591 * We do this by process in order not to violate the locking rules.
592 */
593 mutex_enter(&proclist_mutex);
594 PROCLIST_FOREACH(p, &allproc) {
595 mutex_enter(&p->p_smutex);
596
597 if ((p->p_flag & P_SYSTEM) != 0) {
598 mutex_exit(&p->p_smutex);
599 continue;
600 }
601
602 p->p_stat = SSTOP;
603
604 LIST_FOREACH(l, &p->p_lwps, l_sibling) {
605 if (l == curlwp)
606 continue;
607
608 lwp_lock(l);
609
610 /*
611 * Set L_WREBOOT so that the LWP will suspend itself
612 * when it tries to return to user mode. We want to
613 * try and get to get as many LWPs as possible to
614 * the user / kernel boundary, so that they will
615 * release any locks that they hold.
616 */
617 l->l_flag |= (L_WREBOOT | L_WSUSPEND);
618
619 if (l->l_stat == LSSLEEP &&
620 (l->l_flag & L_SINTR) != 0) {
621 /* setrunnable() will release the lock. */
622 setrunnable(l);
623 continue;
624 }
625
626 lwp_unlock(l);
627 }
628
629 mutex_exit(&p->p_smutex);
630 }
631 mutex_exit(&proclist_mutex);
632
633 /*
634 * Kick all CPUs to make them preempt any LWPs running in user mode.
635 * They'll trap into the kernel and suspend themselves in userret().
636 */
637 sched_lock(0);
638 #ifdef MULTIPROCESSOR
639 for (CPU_INFO_FOREACH(cii, ci))
640 cpu_need_resched(ci);
641 #else
642 cpu_need_resched(curcpu());
643 #endif
644 sched_unlock(0);
645 }
646
647 /*
648 * sched_kpri:
649 *
650 * Scale a priority level to a kernel priority level, usually
651 * for an LWP that is about to sleep.
652 */
653 int
654 sched_kpri(struct lwp *l)
655 {
656 /*
657 * Scale user priorities (127 -> 50) up to kernel priorities
658 * in the range (49 -> 8). Reserve the top 8 kernel priorities
659 * for high priority kthreads. Kernel priorities passed in
660 * are left "as is". XXX This is somewhat arbitrary.
661 */
662 static const uint8_t kpri_tab[] = {
663 0, 1, 2, 3, 4, 5, 6, 7,
664 8, 9, 10, 11, 12, 13, 14, 15,
665 16, 17, 18, 19, 20, 21, 22, 23,
666 24, 25, 26, 27, 28, 29, 30, 31,
667 32, 33, 34, 35, 36, 37, 38, 39,
668 40, 41, 42, 43, 44, 45, 46, 47,
669 48, 49, 8, 8, 9, 9, 10, 10,
670 11, 11, 12, 12, 13, 14, 14, 15,
671 15, 16, 16, 17, 17, 18, 18, 19,
672 20, 20, 21, 21, 22, 22, 23, 23,
673 24, 24, 25, 26, 26, 27, 27, 28,
674 28, 29, 29, 30, 30, 31, 32, 32,
675 33, 33, 34, 34, 35, 35, 36, 36,
676 37, 38, 38, 39, 39, 40, 40, 41,
677 41, 42, 42, 43, 44, 44, 45, 45,
678 46, 46, 47, 47, 48, 48, 49, 49,
679 };
680
681 return kpri_tab[l->l_usrpri];
682 }
683
684 /*
685 * sched_unsleep:
686 *
687 * The is called when the LWP has not been awoken normally but instead
688 * interrupted: for example, if the sleep timed out. Because of this,
689 * it's not a valid action for running or idle LWPs.
690 */
691 void
692 sched_unsleep(struct lwp *l)
693 {
694
695 lwp_unlock(l);
696 panic("sched_unsleep");
697 }
698
699 inline void
700 resched_cpu(struct lwp *l, u_char pri)
701 {
702 struct cpu_info *ci;
703
704 /*
705 * XXXSMP
706 * Since l->l_cpu persists across a context switch,
707 * this gives us *very weak* processor affinity, in
708 * that we notify the CPU on which the process last
709 * ran that it should try to switch.
710 *
711 * This does not guarantee that the process will run on
712 * that processor next, because another processor might
713 * grab it the next time it performs a context switch.
714 *
715 * This also does not handle the case where its last
716 * CPU is running a higher-priority process, but every
717 * other CPU is running a lower-priority process. There
718 * are ways to handle this situation, but they're not
719 * currently very pretty, and we also need to weigh the
720 * cost of moving a process from one CPU to another.
721 *
722 * XXXSMP
723 * There is also the issue of locking the other CPU's
724 * sched state, which we currently do not do.
725 */
726 ci = (l->l_cpu != NULL) ? l->l_cpu : curcpu();
727 if (pri < ci->ci_schedstate.spc_curpriority)
728 cpu_need_resched(ci);
729 }
730