Deleted Added
full compact
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 ---