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 --- |