Deleted Added
full compact
subr_smp.c (134416) subr_smp.c (134591)
1/*
2 * Copyright (c) 2001
3 * John Baldwin <jhb@FreeBSD.org>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 19 unchanged lines hidden (view full) ---

28 */
29
30/*
31 * This module holds the global variables and machine independent functions
32 * used for the kernel SMP support.
33 */
34
35#include <sys/cdefs.h>
1/*
2 * Copyright (c) 2001
3 * John Baldwin <jhb@FreeBSD.org>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 19 unchanged lines hidden (view full) ---

28 */
29
30/*
31 * This module holds the global variables and machine independent functions
32 * used for the kernel SMP support.
33 */
34
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD: head/sys/kern/subr_smp.c 134416 2004-08-28 00:49:55Z obrien $");
36__FBSDID("$FreeBSD: head/sys/kern/subr_smp.c 134591 2004-09-01 06:42:02Z julian $");
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/kernel.h>
41#include <sys/ktr.h>
42#include <sys/proc.h>
43#include <sys/bus.h>
44#include <sys/lock.h>
45#include <sys/mutex.h>
46#include <sys/pcpu.h>
47#include <sys/smp.h>
48#include <sys/sysctl.h>
49
50#include <machine/smp.h>
51
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/kernel.h>
41#include <sys/ktr.h>
42#include <sys/proc.h>
43#include <sys/bus.h>
44#include <sys/lock.h>
45#include <sys/mutex.h>
46#include <sys/pcpu.h>
47#include <sys/smp.h>
48#include <sys/sysctl.h>
49
50#include <machine/smp.h>
51
52#include "opt_sched.h"
53
52#ifdef SMP
53volatile cpumask_t stopped_cpus;
54volatile cpumask_t started_cpus;
54#ifdef SMP
55volatile cpumask_t stopped_cpus;
56volatile cpumask_t started_cpus;
57cpumask_t all_cpus;
58cpumask_t idle_cpus_mask;
59cpumask_t hlt_cpus_mask;
60cpumask_t logical_cpus_mask;
55
56void (*cpustop_restartfunc)(void);
57#endif
58
59int mp_ncpus;
60/* export this for libkvm consumers. */
61int mp_maxcpus = MAXCPU;
62
63struct cpu_top *smp_topology;
64volatile int smp_started;
61
62void (*cpustop_restartfunc)(void);
63#endif
64
65int mp_ncpus;
66/* export this for libkvm consumers. */
67int mp_maxcpus = MAXCPU;
68
69struct cpu_top *smp_topology;
70volatile int smp_started;
65cpumask_t all_cpus;
66u_int mp_maxid;
67
68SYSCTL_NODE(_kern, OID_AUTO, smp, CTLFLAG_RD, NULL, "Kernel SMP");
69
70SYSCTL_INT(_kern_smp, OID_AUTO, maxcpus, CTLFLAG_RD, &mp_maxcpus, 0,
71 "Max number of CPUs that the system was compiled for.");
72
73int smp_active = 0; /* are the APs allowed to run? */

--- 17 unchanged lines hidden (view full) ---

91 "Forwarding of a signal to a process on a different CPU");
92
93/* Enable forwarding of roundrobin to all other cpus */
94static int forward_roundrobin_enabled = 1;
95SYSCTL_INT(_kern_smp, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW,
96 &forward_roundrobin_enabled, 0,
97 "Forwarding of roundrobin to all other CPUs");
98
71u_int mp_maxid;
72
73SYSCTL_NODE(_kern, OID_AUTO, smp, CTLFLAG_RD, NULL, "Kernel SMP");
74
75SYSCTL_INT(_kern_smp, OID_AUTO, maxcpus, CTLFLAG_RD, &mp_maxcpus, 0,
76 "Max number of CPUs that the system was compiled for.");
77
78int smp_active = 0; /* are the APs allowed to run? */

--- 17 unchanged lines hidden (view full) ---

96 "Forwarding of a signal to a process on a different CPU");
97
98/* Enable forwarding of roundrobin to all other cpus */
99static int forward_roundrobin_enabled = 1;
100SYSCTL_INT(_kern_smp, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW,
101 &forward_roundrobin_enabled, 0,
102 "Forwarding of roundrobin to all other CPUs");
103
104#ifdef SCHED_4BSD
105/* Enable forwarding of wakeups to all other cpus */
106SYSCTL_NODE(_kern_smp, OID_AUTO, ipiwakeup, CTLFLAG_RD, NULL, "Kernel SMP");
107
108static int forward_wakeup_enabled = 0;
109SYSCTL_INT(_kern_smp_ipiwakeup, OID_AUTO, enabled, CTLFLAG_RW,
110 &forward_wakeup_enabled, 0,
111 "Forwarding of wakeup to idle CPUs");
112
113static int forward_wakeups_requested = 0;
114SYSCTL_INT(_kern_smp_ipiwakeup, OID_AUTO, requested, CTLFLAG_RD,
115 &forward_wakeups_requested, 0,
116 "Requests for Forwarding of wakeup to idle CPUs");
117
118static int forward_wakeups_delivered = 0;
119SYSCTL_INT(_kern_smp_ipiwakeup, OID_AUTO, delivered, CTLFLAG_RD,
120 &forward_wakeups_delivered, 0,
121 "Completed Forwarding of wakeup to idle CPUs");
122
123static int forward_wakeup_use_mask = 0;
124SYSCTL_INT(_kern_smp_ipiwakeup, OID_AUTO, usemask, CTLFLAG_RW,
125 &forward_wakeup_use_mask, 0,
126 "Use the mask of idle cpus");
127
128static int forward_wakeup_use_loop = 0;
129SYSCTL_INT(_kern_smp_ipiwakeup, OID_AUTO, useloop, CTLFLAG_RW,
130 &forward_wakeup_use_loop, 0,
131 "Use a loop to find idle cpus");
132
133static int forward_wakeup_use_single = 0;
134SYSCTL_INT(_kern_smp_ipiwakeup, OID_AUTO, onecpu, CTLFLAG_RW,
135 &forward_wakeup_use_single, 0,
136 "Only signal one idle cpu");
137
138static int forward_wakeup_use_htt = 0;
139SYSCTL_INT(_kern_smp_ipiwakeup, OID_AUTO, htt2, CTLFLAG_RW,
140 &forward_wakeup_use_htt, 0,
141 "account for htt");
142
143#endif /* SCHED_4BSD */
99/* Variables needed for SMP rendezvous. */
100static void (*smp_rv_setup_func)(void *arg);
101static void (*smp_rv_action_func)(void *arg);
102static void (*smp_rv_teardown_func)(void *arg);
103static void *smp_rv_func_arg;
104static volatile int smp_rv_waiters[2];
105
106/*

--- 91 unchanged lines hidden (view full) ---

198 td != pc->pc_idlethread) {
199 td->td_flags |= TDF_NEEDRESCHED;
200 map |= id;
201 }
202 }
203 ipi_selected(map, IPI_AST);
204}
205
144/* Variables needed for SMP rendezvous. */
145static void (*smp_rv_setup_func)(void *arg);
146static void (*smp_rv_action_func)(void *arg);
147static void (*smp_rv_teardown_func)(void *arg);
148static void *smp_rv_func_arg;
149static volatile int smp_rv_waiters[2];
150
151/*

--- 91 unchanged lines hidden (view full) ---

243 td != pc->pc_idlethread) {
244 td->td_flags |= TDF_NEEDRESCHED;
245 map |= id;
246 }
247 }
248 ipi_selected(map, IPI_AST);
249}
250
251#ifdef SCHED_4BSD
252/* enable HTT_2 if you have a 2-way HTT cpu.*/
253int
254forward_wakeup(int cpunum)
255{
256 cpumask_t map, me, dontuse;
257 cpumask_t map2;
258 struct pcpu *pc;
259 cpumask_t id, map3;
260
261 mtx_assert(&sched_lock, MA_OWNED);
262
263 CTR0(KTR_SMP, "forward_wakeup()");
264
265 if ((!forward_wakeup_enabled) ||
266 (forward_wakeup_use_mask == 0 && forward_wakeup_use_loop == 0))
267 return (0);
268 if (!smp_started || cold || panicstr)
269 return (0);
270
271 forward_wakeups_requested++;
272
206/*
273/*
274 * check the idle mask we received against what we calculated before
275 * in the old version.
276 */
277 me = PCPU_GET(cpumask);
278 /*
279 * don't bother if we should be doing it ourself..
280 */
281 if ((me & idle_cpus_mask) && (cpunum == NOCPU || me == (1 << cpunum)))
282 return (0);
283
284 dontuse = me | stopped_cpus | hlt_cpus_mask;
285 map3 = 0;
286 if (forward_wakeup_use_loop) {
287 SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
288 id = pc->pc_cpumask;
289 if ( (id & dontuse) == 0 &&
290 pc->pc_curthread == pc->pc_idlethread) {
291 map3 |= id;
292 }
293 }
294 }
295
296 if (forward_wakeup_use_mask) {
297 map = 0;
298 map = idle_cpus_mask & ~dontuse;
299
300 /* If they are both on, compare and use loop if different */
301 if (forward_wakeup_use_loop) {
302 if (map != map3) {
303 printf("map (%02X) != map3 (%02X)\n",
304 map, map3);
305 map = map3;
306 }
307 }
308 } else {
309 map = map3;
310 }
311 /* If we only allow a specific CPU, then mask off all the others */
312 if (cpunum != NOCPU) {
313 KASSERT((cpunum <= mp_maxcpus),("forward_wakeup: bad cpunum."));
314 map &= (1 << cpunum);
315 } else {
316 /* Try choose an idle die. */
317 if (forward_wakeup_use_htt) {
318 map2 = (map & (map >> 1)) & 0x5555;
319 if (map2) {
320 map = map2;
321 }
322 }
323
324 /* set only one bit */
325 if (forward_wakeup_use_single) {
326 map = map & ((~map) + 1);
327 }
328 }
329 if (map) {
330 forward_wakeups_delivered++;
331 ipi_selected(map, IPI_AST);
332 return (1);
333 }
334 if (cpunum == NOCPU)
335 printf("forward_wakeup: Idle processor not found\n");
336 return (0);
337}
338#endif /* SCHED_4BSD */
339
340/*
207 * When called the executing CPU will send an IPI to all other CPUs
208 * requesting that they halt execution.
209 *
210 * Usually (but not necessarily) called with 'other_cpus' as its arg.
211 *
212 * - Signals all CPUs in map to stop.
213 * - Waits for each to stop.
214 *

--- 170 unchanged lines hidden ---
341 * When called the executing CPU will send an IPI to all other CPUs
342 * requesting that they halt execution.
343 *
344 * Usually (but not necessarily) called with 'other_cpus' as its arg.
345 *
346 * - Signals all CPUs in map to stop.
347 * - Waits for each to stop.
348 *

--- 170 unchanged lines hidden ---