subr_smp.c (244444) | subr_smp.c (255726) |
---|---|
1/*- 2 * Copyright (c) 2001, John Baldwin <jhb@FreeBSD.org>. 3 * 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, John Baldwin <jhb@FreeBSD.org>. 3 * 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 244444 2012-12-19 20:08:06Z jeff $"); | 36__FBSDID("$FreeBSD: head/sys/kern/subr_smp.c 255726 2013-09-20 05:06:03Z gibbs $"); |
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> --- 175 unchanged lines hidden (view full) --- 220 ("%s: invalid stop type", __func__)); 221 222 if (!smp_started) 223 return (0); 224 225 CTR2(KTR_SMP, "stop_cpus(%s) with %u type", 226 cpusetobj_strprint(cpusetbuf, &map), type); 227 | 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> --- 175 unchanged lines hidden (view full) --- 220 ("%s: invalid stop type", __func__)); 221 222 if (!smp_started) 223 return (0); 224 225 CTR2(KTR_SMP, "stop_cpus(%s) with %u type", 226 cpusetobj_strprint(cpusetbuf, &map), type); 227 |
228#ifdef XENHVM 229 /* 230 * When migrating a PVHVM domain we need to make sure there are 231 * no IPIs in progress. IPIs that have been issued, but not 232 * yet delivered (not pending on a vCPU) will be lost in the 233 * IPI rebinding process, violating FreeBSD's assumption of 234 * reliable IPI delivery. 235 */ 236 if (type == IPI_SUSPEND) 237 mtx_lock_spin(&smp_ipi_mtx); 238#endif 239 |
|
228 if (stopping_cpu != PCPU_GET(cpuid)) 229 while (atomic_cmpset_int(&stopping_cpu, NOCPU, 230 PCPU_GET(cpuid)) == 0) 231 while (stopping_cpu != NOCPU) 232 cpu_spinwait(); /* spin */ 233 234 /* send the stop IPI to all CPUs in map */ 235 ipi_selected(map, type); --- 11 unchanged lines hidden (view full) --- 247 cpu_spinwait(); 248 i++; 249 if (i == 100000000) { 250 printf("timeout stopping cpus\n"); 251 break; 252 } 253 } 254 | 240 if (stopping_cpu != PCPU_GET(cpuid)) 241 while (atomic_cmpset_int(&stopping_cpu, NOCPU, 242 PCPU_GET(cpuid)) == 0) 243 while (stopping_cpu != NOCPU) 244 cpu_spinwait(); /* spin */ 245 246 /* send the stop IPI to all CPUs in map */ 247 ipi_selected(map, type); --- 11 unchanged lines hidden (view full) --- 259 cpu_spinwait(); 260 i++; 261 if (i == 100000000) { 262 printf("timeout stopping cpus\n"); 263 break; 264 } 265 } 266 |
267#ifdef XENHVM 268 if (type == IPI_SUSPEND) 269 mtx_unlock_spin(&smp_ipi_mtx); 270#endif 271 |
|
255 stopping_cpu = NOCPU; 256 return (1); 257} 258 259int 260stop_cpus(cpuset_t map) 261{ 262 --- 24 unchanged lines hidden (view full) --- 287 * - Signals all CPUs in map to restart. 288 * - Waits for each to restart. 289 * 290 * Returns: 291 * -1: error 292 * 0: NA 293 * 1: ok 294 */ | 272 stopping_cpu = NOCPU; 273 return (1); 274} 275 276int 277stop_cpus(cpuset_t map) 278{ 279 --- 24 unchanged lines hidden (view full) --- 304 * - Signals all CPUs in map to restart. 305 * - Waits for each to restart. 306 * 307 * Returns: 308 * -1: error 309 * 0: NA 310 * 1: ok 311 */ |
295int 296restart_cpus(cpuset_t map) | 312static int 313generic_restart_cpus(cpuset_t map, u_int type) |
297{ 298#ifdef KTR 299 char cpusetbuf[CPUSETBUFSIZ]; 300#endif | 314{ 315#ifdef KTR 316 char cpusetbuf[CPUSETBUFSIZ]; 317#endif |
318 volatile cpuset_t *cpus; |
|
301 | 319 |
320 KASSERT( 321#if defined(__amd64__) || defined(__i386__) 322 type == IPI_STOP || type == IPI_STOP_HARD || type == IPI_SUSPEND, 323#else 324 type == IPI_STOP || type == IPI_STOP_HARD, 325#endif 326 ("%s: invalid stop type", __func__)); 327 |
|
302 if (!smp_started) 303 return 0; 304 305 CTR1(KTR_SMP, "restart_cpus(%s)", cpusetobj_strprint(cpusetbuf, &map)); 306 | 328 if (!smp_started) 329 return 0; 330 331 CTR1(KTR_SMP, "restart_cpus(%s)", cpusetobj_strprint(cpusetbuf, &map)); 332 |
333#if defined(__amd64__) || defined(__i386__) 334 if (type == IPI_SUSPEND) 335 cpus = &suspended_cpus; 336 else 337#endif 338 cpus = &stopped_cpus; 339 |
|
307 /* signal other cpus to restart */ 308 CPU_COPY_STORE_REL(&map, &started_cpus); 309 310 /* wait for each to clear its bit */ | 340 /* signal other cpus to restart */ 341 CPU_COPY_STORE_REL(&map, &started_cpus); 342 343 /* wait for each to clear its bit */ |
311 while (CPU_OVERLAP(&stopped_cpus, &map)) | 344 while (CPU_OVERLAP(cpus, &map)) |
312 cpu_spinwait(); 313 314 return 1; 315} 316 | 345 cpu_spinwait(); 346 347 return 1; 348} 349 |
350int 351restart_cpus(cpuset_t map) 352{ 353 354 return (generic_restart_cpus(map, IPI_STOP)); 355} 356 357#if defined(__amd64__) || defined(__i386__) 358int 359resume_cpus(cpuset_t map) 360{ 361 362 return (generic_restart_cpus(map, IPI_SUSPEND)); 363} 364#endif 365 |
|
317/* 318 * All-CPU rendezvous. CPUs are signalled, all execute the setup function 319 * (if specified), rendezvous, execute the action function (if specified), 320 * rendezvous again, execute the teardown function (if specified), and then 321 * resume. 322 * 323 * Note that the supplied external functions _must_ be reentrant and aware 324 * that they are running in parallel and in an unknown lock context. --- 463 unchanged lines hidden --- | 366/* 367 * All-CPU rendezvous. CPUs are signalled, all execute the setup function 368 * (if specified), rendezvous, execute the action function (if specified), 369 * rendezvous again, execute the teardown function (if specified), and then 370 * resume. 371 * 372 * Note that the supplied external functions _must_ be reentrant and aware 373 * that they are running in parallel and in an unknown lock context. --- 463 unchanged lines hidden --- |