svn commit: r222813 - in head: . contrib/top gnu/usr.bin/gdb/kgdb lib/libkvm lib/libmemstat share/man/man4 share/mk sys/amd64/acpica sys/amd64/amd64 sys/amd64/include sys/arm/arm sys/arm/include sy...

Attilio Rao attilio at FreeBSD.org
Tue Jun 7 08:46:14 UTC 2011


Author: attilio
Date: Tue Jun  7 08:46:13 2011
New Revision: 222813
URL: http://svn.freebsd.org/changeset/base/222813

Log:
  etire the cpumask_t type and replace it with cpuset_t usage.
  
  This is intended to fix the bug where cpu mask objects are
  capped to 32.  MAXCPU, then, can now arbitrarely bumped to whatever
  value.  Anyway, as long as several structures in the kernel are
  statically allocated and sized as MAXCPU, it is suggested to keep it
  as low as possible for the time being.
  
  Technical notes on this commit itself:
  - More functions to handle with cpuset_t objects are introduced.
    The most notable are cpusetobj_ffs() (which calculates a ffs(3)
    for a cpuset_t object), cpusetobj_strprint() (which prepares a string
    representing a cpuset_t object) and cpusetobj_strscan() (which
    creates a valid cpuset_t starting from a string representation).
  - pc_cpumask and pc_other_cpus are target to be removed soon.
    With the moving from cpumask_t to cpuset_t they are now inefficient
    and not really useful.  Anyway, for the time being, please note that
    access to pcpu datas is protected by sched_pin() in order to avoid
    migrating the CPU while reading more than one (possible) word
  - Please note that size of cpuset_t objects may differ between kernel
    and userland.  While this is not directly related to the patch itself,
    it is good to understand that concept and possibly use the patch
    as a reference on how to deal with cpuset_t objects in userland, when
    accessing kernland members.
  - KTR_CPUMASK is changed and now is represented through a string, to be
    set as the example reported in NOTES.
  
  Please additively note that no MAXCPU is bumped in this patch, but
  private testing has been done until to MAXCPU=128 on a real 8x8x2(htt)
  machine (amd64).
  
  Please note that the FreeBSD version is not yet bumped because of
  the upcoming pcpu changes.  However, note that this patch is not
  targeted for MFC.
  
  People to thank for the time spent on this patch:
  - sbruno, pluknet and Nicholas Esborn (nick AT desert DOT net) tested
    several revision of the patches and really helped in improving
    stability of this work.
  - marius fixed several bugs in the sparc64 implementation and reviewed
    patches related to ktr.
  - jeff and jhb discussed the basic approach followed.
  - kib and marcel made targeted review on some specific part of the
    patch.
  - marius, art, nwhitehorn and andreast reviewed MD specific part of
    the patch.
  - marius, andreast, gonzo, nwhitehorn and jceel tested MD specific
    implementations of the patch.
  - Other people have made contributions on other patches that have been
    already committed and have been listed separately.
  
  Companies that should be mentioned for having participated at several
  degrees:
  - Yahoo! for having offered the machines used for testing on big
    count of CPUs.
  - The FreeBSD Foundation for having sponsored my devsummit attendance,
    which has been instrumental.
  - Sandvine for having offered offices and infrastructure during
    development.
  
  (I really hope I didn't forget anyone, if it happened I apologize in
  advance).

Added:
  head/sys/sys/_cpuset.h
     - copied unchanged from r222812, projects/largeSMP/sys/sys/_cpuset.h
Replaced:
  head/share/man/man4/geom_map.4
     - copied unchanged from r222812, projects/largeSMP/share/man/man4/geom_map.4
  head/sys/dev/iicbus/ad7417.c
     - copied unchanged from r222812, projects/largeSMP/sys/dev/iicbus/ad7417.c
  head/sys/nfs/nfs_kdtrace.h
     - copied unchanged from r222812, projects/largeSMP/sys/nfs/nfs_kdtrace.h
  head/sys/sys/_stdint.h
     - copied unchanged from r222812, projects/largeSMP/sys/sys/_stdint.h
  head/tools/build/options/WITHOUT_GPIO
     - copied unchanged from r222812, projects/largeSMP/tools/build/options/WITHOUT_GPIO
  head/tools/build/options/WITH_OFED
     - copied unchanged from r222812, projects/largeSMP/tools/build/options/WITH_OFED
  head/tools/regression/bin/sh/builtins/set1.0
     - copied unchanged from r222812, projects/largeSMP/tools/regression/bin/sh/builtins/set1.0
  head/tools/regression/bin/sh/parser/dollar-quote1.0
     - copied unchanged from r222812, projects/largeSMP/tools/regression/bin/sh/parser/dollar-quote1.0
  head/tools/regression/bin/sh/parser/dollar-quote2.0
     - copied unchanged from r222812, projects/largeSMP/tools/regression/bin/sh/parser/dollar-quote2.0
  head/tools/regression/bin/sh/parser/dollar-quote3.0
     - copied unchanged from r222812, projects/largeSMP/tools/regression/bin/sh/parser/dollar-quote3.0
  head/tools/regression/bin/sh/parser/dollar-quote4.0
     - copied unchanged from r222812, projects/largeSMP/tools/regression/bin/sh/parser/dollar-quote4.0
  head/tools/regression/bin/sh/parser/dollar-quote5.0
     - copied unchanged from r222812, projects/largeSMP/tools/regression/bin/sh/parser/dollar-quote5.0
  head/tools/regression/bin/sh/parser/dollar-quote6.0
     - copied unchanged from r222812, projects/largeSMP/tools/regression/bin/sh/parser/dollar-quote6.0
  head/tools/regression/bin/sh/parser/dollar-quote7.0
     - copied unchanged from r222812, projects/largeSMP/tools/regression/bin/sh/parser/dollar-quote7.0
  head/tools/regression/bin/sh/parser/dollar-quote8.0
     - copied unchanged from r222812, projects/largeSMP/tools/regression/bin/sh/parser/dollar-quote8.0
  head/tools/regression/bin/sh/parser/dollar-quote9.0
     - copied unchanged from r222812, projects/largeSMP/tools/regression/bin/sh/parser/dollar-quote9.0
Modified:
  head/UPDATING
  head/gnu/usr.bin/gdb/kgdb/kthr.c
  head/lib/libkvm/kvm_pcpu.c
  head/lib/libmemstat/memstat_uma.c
  head/sys/amd64/acpica/acpi_wakeup.c
  head/sys/amd64/amd64/intr_machdep.c
  head/sys/amd64/amd64/mp_machdep.c
  head/sys/amd64/amd64/pmap.c
  head/sys/amd64/amd64/vm_machdep.c
  head/sys/amd64/include/_types.h
  head/sys/amd64/include/pmap.h
  head/sys/amd64/include/smp.h
  head/sys/arm/arm/pmap.c
  head/sys/arm/include/_types.h
  head/sys/arm/include/pmap.h
  head/sys/cddl/dev/cyclic/i386/cyclic_machdep.c
  head/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
  head/sys/cddl/dev/dtrace/i386/dtrace_subr.c
  head/sys/conf/NOTES
  head/sys/dev/hwpmc/hwpmc_mod.c
  head/sys/dev/xen/control/control.c
  head/sys/geom/eli/g_eli.c
  head/sys/i386/i386/intr_machdep.c
  head/sys/i386/i386/mp_machdep.c
  head/sys/i386/i386/pmap.c
  head/sys/i386/i386/vm_machdep.c
  head/sys/i386/include/_types.h
  head/sys/i386/include/pmap.h
  head/sys/i386/include/sf_buf.h
  head/sys/i386/include/smp.h
  head/sys/i386/xen/mp_machdep.c
  head/sys/i386/xen/pmap.c
  head/sys/ia64/ia64/mp_machdep.c
  head/sys/ia64/include/_types.h
  head/sys/ia64/include/smp.h
  head/sys/kern/kern_cpuset.c
  head/sys/kern/kern_ktr.c
  head/sys/kern/kern_pmc.c
  head/sys/kern/kern_rmlock.c
  head/sys/kern/sched_4bsd.c
  head/sys/kern/sched_ule.c
  head/sys/kern/subr_kdb.c
  head/sys/kern/subr_pcpu.c
  head/sys/kern/subr_smp.c
  head/sys/mips/cavium/octeon_mp.c
  head/sys/mips/include/_types.h
  head/sys/mips/include/hwfunc.h
  head/sys/mips/include/pmap.h
  head/sys/mips/include/smp.h
  head/sys/mips/mips/mp_machdep.c
  head/sys/mips/mips/pmap.c
  head/sys/mips/rmi/xlr_machdep.c
  head/sys/mips/sibyte/sb_scd.c
  head/sys/ofed/include/linux/list.h
  head/sys/powerpc/aim/mmu_oea.c
  head/sys/powerpc/aim/mmu_oea64.c
  head/sys/powerpc/booke/platform_bare.c
  head/sys/powerpc/booke/pmap.c
  head/sys/powerpc/include/_types.h
  head/sys/powerpc/include/openpicvar.h
  head/sys/powerpc/include/pmap.h
  head/sys/powerpc/include/smp.h
  head/sys/powerpc/mpc85xx/openpic_fdt.c
  head/sys/powerpc/powerpc/intr_machdep.c
  head/sys/powerpc/powerpc/mp_machdep.c
  head/sys/powerpc/powerpc/openpic.c
  head/sys/powerpc/powerpc/pic_if.m
  head/sys/sparc64/include/_types.h
  head/sys/sparc64/include/ktr.h
  head/sys/sparc64/include/pmap.h
  head/sys/sparc64/include/smp.h
  head/sys/sparc64/sparc64/genassym.c
  head/sys/sparc64/sparc64/intr_machdep.c
  head/sys/sparc64/sparc64/mp_exception.S
  head/sys/sparc64/sparc64/mp_machdep.c
  head/sys/sparc64/sparc64/pmap.c
  head/sys/sparc64/sparc64/swtch.S
  head/sys/sparc64/sparc64/tlb.c
  head/sys/sys/_rmlock.h
  head/sys/sys/cpuset.h
  head/sys/sys/ktr.h
  head/sys/sys/pcpu.h
  head/sys/sys/pmckern.h
  head/sys/sys/smp.h
  head/sys/sys/types.h
  head/sys/x86/x86/local_apic.c
  head/usr.sbin/pmccontrol/pmccontrol.c
Directory Properties:
  head/   (props changed)
  head/cddl/contrib/opensolaris/   (props changed)
  head/contrib/bind9/   (props changed)
  head/contrib/binutils/   (props changed)
  head/contrib/bzip2/   (props changed)
  head/contrib/compiler-rt/   (props changed)
  head/contrib/dialog/   (props changed)
  head/contrib/ee/   (props changed)
  head/contrib/expat/   (props changed)
  head/contrib/file/   (props changed)
  head/contrib/gcc/   (props changed)
  head/contrib/gdb/   (props changed)
  head/contrib/gdtoa/   (props changed)
  head/contrib/gnu-sort/   (props changed)
  head/contrib/groff/   (props changed)
  head/contrib/less/   (props changed)
  head/contrib/libpcap/   (props changed)
  head/contrib/libstdc++/   (props changed)
  head/contrib/llvm/   (props changed)
  head/contrib/llvm/tools/clang/   (props changed)
  head/contrib/ncurses/   (props changed)
  head/contrib/netcat/   (props changed)
  head/contrib/ntp/   (props changed)
  head/contrib/one-true-awk/   (props changed)
  head/contrib/openbsm/   (props changed)
  head/contrib/openpam/   (props changed)
  head/contrib/pf/   (props changed)
  head/contrib/sendmail/   (props changed)
  head/contrib/tcpdump/   (props changed)
  head/contrib/tcsh/   (props changed)
  head/contrib/top/   (props changed)
  head/contrib/top/install-sh   (props changed)
  head/contrib/tzcode/stdtime/   (props changed)
  head/contrib/tzcode/zic/   (props changed)
  head/contrib/tzdata/   (props changed)
  head/contrib/wpa/   (props changed)
  head/contrib/xz/   (props changed)
  head/crypto/openssh/   (props changed)
  head/crypto/openssl/   (props changed)
  head/gnu/lib/   (props changed)
  head/gnu/usr.bin/binutils/   (props changed)
  head/gnu/usr.bin/cc/cc_tools/   (props changed)
  head/gnu/usr.bin/gdb/   (props changed)
  head/lib/libc/   (props changed)
  head/lib/libc/stdtime/   (props changed)
  head/lib/libutil/   (props changed)
  head/lib/libz/   (props changed)
  head/sbin/   (props changed)
  head/sbin/ipfw/   (props changed)
  head/share/mk/bsd.arch.inc.mk   (props changed)
  head/share/zoneinfo/   (props changed)
  head/sys/   (props changed)
  head/sys/amd64/include/xen/   (props changed)
  head/sys/boot/   (props changed)
  head/sys/boot/i386/efi/   (props changed)
  head/sys/boot/ia64/efi/   (props changed)
  head/sys/boot/ia64/ski/   (props changed)
  head/sys/boot/powerpc/boot1.chrp/   (props changed)
  head/sys/boot/powerpc/ofw/   (props changed)
  head/sys/cddl/contrib/opensolaris/   (props changed)
  head/sys/conf/   (props changed)
  head/sys/contrib/dev/acpica/   (props changed)
  head/sys/contrib/octeon-sdk/   (props changed)
  head/sys/contrib/pf/   (props changed)
  head/sys/contrib/x86emu/   (props changed)
  head/usr.bin/calendar/   (props changed)
  head/usr.bin/csup/   (props changed)
  head/usr.bin/procstat/   (props changed)
  head/usr.sbin/ndiscvt/   (props changed)
  head/usr.sbin/zic/   (props changed)

Modified: head/UPDATING
==============================================================================
--- head/UPDATING	Tue Jun  7 08:24:29 2011	(r222812)
+++ head/UPDATING	Tue Jun  7 08:46:13 2011	(r222813)
@@ -22,6 +22,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 9.
 	machines to maximize performance.  (To disable malloc debugging, run
 	ln -s aj /etc/malloc.conf.)
 
+20110607:
+	cpumask_t type is retired and cpuset_t is used in order to describe
+	a mask of CPUs.
+
 20110513:
 	Support for sun4v architecture is officially dropped
 

Modified: head/gnu/usr.bin/gdb/kgdb/kthr.c
==============================================================================
--- head/gnu/usr.bin/gdb/kgdb/kthr.c	Tue Jun  7 08:24:29 2011	(r222812)
+++ head/gnu/usr.bin/gdb/kgdb/kthr.c	Tue Jun  7 08:46:13 2011	(r222813)
@@ -28,6 +28,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/cpuset.h>
 #include <sys/proc.h>
 #include <sys/types.h>
 #include <sys/signal.h>
@@ -37,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <defs.h>
 #include <frame-unwind.h>
@@ -48,7 +50,7 @@ static CORE_ADDR dumppcb;
 static int dumptid;
 
 static CORE_ADDR stoppcbs;
-static __cpumask_t stopped_cpus;
+static cpuset_t stopped_cpus;
 
 static struct kthr *first;
 struct kthr *curkthr;
@@ -76,6 +78,7 @@ kgdb_thr_init(void)
 {
 	struct proc p;
 	struct thread td;
+	long cpusetsize;
 	struct kthr *kt;
 	CORE_ADDR addr;
 	uintptr_t paddr;
@@ -102,10 +105,11 @@ kgdb_thr_init(void)
 		dumptid = -1;
 
 	addr = kgdb_lookup("stopped_cpus");
-	if (addr != 0)
-		kvm_read(kvm, addr, &stopped_cpus, sizeof(stopped_cpus));
-	else
-		stopped_cpus = 0;
+	CPU_ZERO(&stopped_cpus);
+	cpusetsize = sysconf(_SC_CPUSET_SIZE);
+	if (cpusetsize != -1 && (u_long)cpusetsize <= sizeof(cpuset_t) &&
+	    addr != 0)
+		kvm_read(kvm, addr, &stopped_cpus, cpusetsize);
 
 	stoppcbs = kgdb_lookup("stoppcbs");
 
@@ -126,8 +130,8 @@ kgdb_thr_init(void)
 			kt->kaddr = addr;
 			if (td.td_tid == dumptid)
 				kt->pcb = dumppcb;
-			else if (td.td_state == TDS_RUNNING && ((1 << td.td_oncpu) & stopped_cpus)
-				&& stoppcbs != 0)
+			else if (td.td_state == TDS_RUNNING && stoppcbs != 0 &&
+			    CPU_ISSET(td.td_oncpu, &stopped_cpus))
 				kt->pcb = (uintptr_t) stoppcbs + sizeof(struct pcb) * td.td_oncpu;
 			else
 				kt->pcb = (uintptr_t)td.td_pcb;

Modified: head/lib/libkvm/kvm_pcpu.c
==============================================================================
--- head/lib/libkvm/kvm_pcpu.c	Tue Jun  7 08:24:29 2011	(r222812)
+++ head/lib/libkvm/kvm_pcpu.c	Tue Jun  7 08:46:13 2011	(r222813)
@@ -39,11 +39,13 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/cpuset.h>
 #include <sys/pcpu.h>
 #include <sys/sysctl.h>
 #include <kvm.h>
 #include <limits.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include "kvm_private.h"
 
@@ -118,6 +120,9 @@ _kvm_pcpu_clear(void)
 void *
 kvm_getpcpu(kvm_t *kd, int cpu)
 {
+	long kcpusetsize;
+	ssize_t nbytes;
+	uintptr_t readptr;
 	char *buf;
 
 	if (kd == NULL) {
@@ -125,6 +130,10 @@ kvm_getpcpu(kvm_t *kd, int cpu)
 		return (NULL);
 	}
 
+	kcpusetsize = sysconf(_SC_CPUSET_SIZE);
+	if (kcpusetsize == -1 || (u_long)kcpusetsize > sizeof(cpuset_t))
+		return ((void *)-1);
+
 	if (maxcpu == 0)
 		if (_kvm_pcpu_init(kd) < 0)
 			return ((void *)-1);
@@ -137,8 +146,26 @@ kvm_getpcpu(kvm_t *kd, int cpu)
 		_kvm_err(kd, kd->program, "out of memory");
 		return ((void *)-1);
 	}
-	if (kvm_read(kd, (uintptr_t)pcpu_data[cpu], buf, sizeof(struct pcpu)) !=
-	    sizeof(struct pcpu)) {
+	nbytes = sizeof(struct pcpu) - 2 * kcpusetsize;
+	readptr = (uintptr_t)pcpu_data[cpu];
+	if (kvm_read(kd, readptr, buf, nbytes) != nbytes) {
+		_kvm_err(kd, kd->program, "unable to read per-CPU data");
+		free(buf);
+		return ((void *)-1);
+	}
+
+	/* Fetch the valid cpuset_t objects. */
+	CPU_ZERO((cpuset_t *)(buf + nbytes));
+	CPU_ZERO((cpuset_t *)(buf + nbytes + sizeof(cpuset_t)));
+	readptr += nbytes;
+	if (kvm_read(kd, readptr, buf + nbytes, kcpusetsize) != kcpusetsize) {
+		_kvm_err(kd, kd->program, "unable to read per-CPU data");
+		free(buf);
+		return ((void *)-1);
+	}
+	readptr += kcpusetsize;
+	if (kvm_read(kd, readptr, buf + nbytes + sizeof(cpuset_t),
+	    kcpusetsize) != kcpusetsize) {
 		_kvm_err(kd, kd->program, "unable to read per-CPU data");
 		free(buf);
 		return ((void *)-1);

Modified: head/lib/libmemstat/memstat_uma.c
==============================================================================
--- head/lib/libmemstat/memstat_uma.c	Tue Jun  7 08:24:29 2011	(r222812)
+++ head/lib/libmemstat/memstat_uma.c	Tue Jun  7 08:46:13 2011	(r222813)
@@ -27,6 +27,7 @@
  */
 
 #include <sys/param.h>
+#include <sys/cpuset.h>
 #include <sys/sysctl.h>
 
 #define	LIBMEMSTAT	/* Cause vm_page.h not to include opt_vmpage.h */
@@ -44,6 +45,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "memstat.h"
 #include "memstat_internal.h"
@@ -313,7 +315,8 @@ memstat_kvm_uma(struct memory_type_list 
 	struct uma_keg *kzp, kz;
 	int hint_dontsearch, i, mp_maxid, ret;
 	char name[MEMTYPE_MAXNAME];
-	__cpumask_t all_cpus;
+	cpuset_t all_cpus;
+	long cpusetsize;
 	kvm_t *kvm;
 
 	kvm = (kvm_t *)kvm_handle;
@@ -337,7 +340,13 @@ memstat_kvm_uma(struct memory_type_list 
 		list->mtl_error = ret;
 		return (-1);
 	}
-	ret = kread_symbol(kvm, X_ALL_CPUS, &all_cpus, sizeof(all_cpus), 0);
+	cpusetsize = sysconf(_SC_CPUSET_SIZE);
+	if (cpusetsize == -1 || (u_long)cpusetsize > sizeof(cpuset_t)) {
+		list->mtl_error = MEMSTAT_ERROR_KVM_NOSYMBOL;
+		return (-1);
+	}
+	CPU_ZERO(&all_cpus);
+	ret = kread_symbol(kvm, X_ALL_CPUS, &all_cpus, cpusetsize, 0);
 	if (ret != 0) {
 		list->mtl_error = ret;
 		return (-1);
@@ -407,7 +416,7 @@ memstat_kvm_uma(struct memory_type_list 
 			if (kz.uk_flags & UMA_ZFLAG_INTERNAL)
 				goto skip_percpu;
 			for (i = 0; i < mp_maxid + 1; i++) {
-				if ((all_cpus & (1 << i)) == 0)
+				if (!CPU_ISSET(i, &all_cpus))
 					continue;
 				ucp = &ucp_array[i];
 				mtp->mt_numallocs += ucp->uc_allocs;

Copied: head/share/man/man4/geom_map.4 (from r222812, projects/largeSMP/share/man/man4/geom_map.4)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/man/man4/geom_map.4	Tue Jun  7 08:46:13 2011	(r222813, copy of r222812, projects/largeSMP/share/man/man4/geom_map.4)
@@ -0,0 +1,211 @@
+.\"
+.\" Copyright (c) 2011 Aleksandr Rybalko
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 17, 2011
+.Dt GEOM_MAP 4
+.Os
+.Sh NAME
+.Nm geom_map
+.Nd "GEOM module that maps defined items as separate partitions"
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following line in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device geom_map"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+framework provides support for mapping defined parts of the media.
+Basically it is helpful for embedded devices where in the one continuous
+flash are loader, kernel and rootfs parts.
+.Nm
+allows making them available as separate parts and protects the loader from
+being overwritten.
+.Pp
+At boot time
+.Nm
+partitions are listed (only with bootverbose) as:
+.Bd -literal -offset indent
+MAP: 0x30000, data=0x30000 "/dev/map/bootloader"
+MAP: 30000x10000, data=0x10000 "/dev/map/factory"
+MAP: 40000x7a0000, data=0x7a0000 "/dev/map/upgrade"
+MAP: search key ".!/bin/sh" from 0x100000, step 0x10000
+MAP: 40000x110000, data=0x110000 "/dev/map/kernel"
+MAP: search key ".!/bin/sh" from 0x100000, step 0x10000
+MAP: 150000x690000, data=0x690000 "/dev/map/rootfs"
+MAP: 7e0000x20000, data=0x20000 "/dev/map/config"
+.Ed
+.Pp
+The current
+.Nm
+configuration can be accessed with the following
+.Xr sysctl 8
+nodes:
+.Va kern.geom.conftxt , kern.geom.confxml ,
+and
+.Va kern.geom.confdot
+or by using
+.Dq Li "geom map list" .
+.Bd -literal -offset indent
+# sysctl -n kern.geom.conftxt
+0 MD md0 10485760 512 u 0 s 512 f 0 fs 0 l 10485760 t malloc
+0 DISK cfid0 8388608 4 hd 0 sc 0
+1 MAP map/config 131072 4 i 5 o 8257536 entry 0 dsize 131072
+1 MAP map/rootfs 6881280 4 i 4 o 1376256 entry 0 dsize 6881280
+2 UNCOMPRESS map/rootfs.uncompress 18677760 512
+1 MAP map/kernel 1114112 4 i 3 o 262144 entry 0 dsize 1114112
+1 MAP map/upgrade 7995392 4 i 2 o 262144 entry 0 dsize 7995392
+1 MAP map/factory 65536 4 i 1 o 196608 entry 0 dsize 65536
+1 MAP map/bootloader 196608 4 i 0 o 0 entry 0 dsize 196608
+.Ed
+.Pp
+Driver configuration can be done in
+.Xr device.hints 5 .
+List of used parameters:
+.Bl -tag -width indent
+.It Va at
+select media to attach
+.It Va name
+name of partition (will create device
+.Pa /dev/map/ Ns Ar that_name )
+.It Va start
+offset from the beginning of the parent media to start of the mapped partition.
+This field can also have a special value
+.Qq Li search: Ns Ar searchstart Ns Li : Ns Ar searchstep Ns Li : Ns Ar searchkey ,
+where:
+.Bl -tag -width indent
+.It Ar searchstart
+offset from the beginning of the parent media where search will be started
+.It Ar searchstep
+value of the increment used while searching for the partition boundary markers
+.It Ar searchkey
+key which will be used to find partition boundary markers.
+The wildcard
+.Ql .\&
+can be used to match any character on that position
+.El
+.It Va end
+offset from the beginning of the parent media to the end of the mapped partition.
+This field can also have the special value
+.Qq Li search: Ns Ar searchstart Ns Li : Ns Ar searchstep Ns Li : Ns Ar searchkey ,
+as described above.
+.It Va offset
+offset where the data of the mapped partition begins
+.El
+.Pp
+Each record contains the start address (in bytes) from the media begin, size
+(in bytes), offset where the data of mapped partition begins, and the name of
+new device.
+.Bd -literal -offset indent
+MAP: 150000x690000, data=0x690000 "/dev/map/rootfs"
+.Ed
+.Bd -literal
+00150000 - start address
+00690000 - size
+00000000 - data begin from zero offset
+00690000 - data size
+"map/rootfs" - new media will be accessible via /dev/map/rootfs dev.
+.Ed
+.Sh EXAMPLES
+If we need to implement layout shown above, we need to define the following
+hints:
+.Bd -literal -offset indent
+hint.map.0.at="cfid0"
+hint.map.0.start=0x00000000
+hint.map.0.end=0x00030000
+hint.map.0.name="bootloader"
+hint.map.0.readonly=1
+.Ed
+.Pp
+This defines
+.Pa /dev/map/bootloader
+at disk
+.Pa cfid0
+starting at
+.Li 0x00000000
+and ending at
+.Li 0x00030000 ,
+it is also marked as readonly.
+.Bd -literal -offset indent
+hint.map.1.at="cfid0"
+hint.map.1.start=0x00030000
+hint.map.1.end=0x00040000
+hint.map.1.name="factory"
+
+hint.map.2.at="cfid0"
+hint.map.2.start=0x00040000
+hint.map.2.end=0x007e0000
+hint.map.2.name="upgrade"
+
+hint.map.3.at="cfid0"
+hint.map.3.name="kernel"
+hint.map.3.start=0x00040000
+hint.map.3.end="search:0x00100000:0x10000:.!/bin/sh"
+.Ed
+.Pp
+This defines
+.Pa /dev/map/kernel
+at disk
+.Pa cfid0
+starting at
+.Li 0x00040000 ,
+but the end position must be searched by finding the key
+.Dq Li ".!/bin/sh" ,
+from offset
+.Li 0x00100000
+to the end of media with step
+.Li 0x10000 .
+The real marker in this case is
+.Dq Li "#!/bin/sh" ,
+but
+.Ql #
+terminates the line when the hints file is parsed, so we need to use wildcard
+.Ql .\&
+instead of
+.Ql # .
+.Bd -literal -offset indent
+hint.map.4.at="cfid0"
+hint.map.4.name="rootfs"
+hint.map.4.start="search:0x00100000:0x10000:.!/bin/sh"
+hint.map.4.end=0x007e0000
+
+hint.map.5.at="cfid0"
+hint.map.5.start=0x007e0000
+hint.map.5.end=0x00800000
+hint.map.5.name="config"
+.Ed
+.Sh SEE ALSO
+.Xr geom 4 ,
+.Xr geom 8 ,
+.Xr sysctl 8
+.Sh AUTHORS
+The
+.Nm
+driver was written by
+.An "Aleksandr Rybalko" Aq ray at ddteam.net .

Modified: head/sys/amd64/acpica/acpi_wakeup.c
==============================================================================
--- head/sys/amd64/acpica/acpi_wakeup.c	Tue Jun  7 08:24:29 2011	(r222812)
+++ head/sys/amd64/acpica/acpi_wakeup.c	Tue Jun  7 08:46:13 2011	(r222813)
@@ -78,7 +78,7 @@ static void		acpi_stop_beep(void *);
 
 #ifdef SMP
 static int		acpi_wakeup_ap(struct acpi_softc *, int);
-static void		acpi_wakeup_cpus(struct acpi_softc *, cpumask_t);
+static void		acpi_wakeup_cpus(struct acpi_softc *, const cpuset_t *);
 #endif
 
 #define	WAKECODE_VADDR(sc)	((sc)->acpi_wakeaddr + (3 * PAGE_SIZE))
@@ -173,7 +173,7 @@ acpi_wakeup_ap(struct acpi_softc *sc, in
 #define	BIOS_WARM		(0x0a)
 
 static void
-acpi_wakeup_cpus(struct acpi_softc *sc, cpumask_t wakeup_cpus)
+acpi_wakeup_cpus(struct acpi_softc *sc, const cpuset_t *wakeup_cpus)
 {
 	uint32_t	mpbioswarmvec;
 	int		cpu;
@@ -192,7 +192,7 @@ acpi_wakeup_cpus(struct acpi_softc *sc, 
 
 	/* Wake up each AP. */
 	for (cpu = 1; cpu < mp_ncpus; cpu++) {
-		if ((wakeup_cpus & (1 << cpu)) == 0)
+		if (!CPU_ISSET(cpu, wakeup_cpus))
 			continue;
 		if (acpi_wakeup_ap(sc, cpu) == 0) {
 			/* restore the warmstart vector */
@@ -214,7 +214,7 @@ int
 acpi_sleep_machdep(struct acpi_softc *sc, int state)
 {
 #ifdef SMP
-	cpumask_t	wakeup_cpus;
+	cpuset_t	wakeup_cpus;
 #endif
 	register_t	cr3, rf;
 	ACPI_STATUS	status;
@@ -244,10 +244,9 @@ acpi_sleep_machdep(struct acpi_softc *sc
 
 	if (savectx(susppcbs[0])) {
 #ifdef SMP
-		if (wakeup_cpus != 0 && suspend_cpus(wakeup_cpus) == 0) {
-			device_printf(sc->acpi_dev,
-			    "Failed to suspend APs: CPU mask = 0x%jx\n",
-			    (uintmax_t)(wakeup_cpus & ~stopped_cpus));
+		if (!CPU_EMPTY(&wakeup_cpus) &&
+		    suspend_cpus(wakeup_cpus) == 0) {
+			device_printf(sc->acpi_dev, "Failed to suspend APs\n");
 			goto out;
 		}
 #endif
@@ -282,8 +281,8 @@ acpi_sleep_machdep(struct acpi_softc *sc
 		PCPU_SET(switchtime, 0);
 		PCPU_SET(switchticks, ticks);
 #ifdef SMP
-		if (wakeup_cpus != 0)
-			acpi_wakeup_cpus(sc, wakeup_cpus);
+		if (!CPU_EMPTY(&wakeup_cpus))
+			acpi_wakeup_cpus(sc, &wakeup_cpus);
 #endif
 		acpi_resync_clock(sc);
 		ret = 0;
@@ -291,7 +290,7 @@ acpi_sleep_machdep(struct acpi_softc *sc
 
 out:
 #ifdef SMP
-	if (wakeup_cpus != 0)
+	if (!CPU_EMPTY(&wakeup_cpus))
 		restart_cpus(wakeup_cpus);
 #endif
 

Modified: head/sys/amd64/amd64/intr_machdep.c
==============================================================================
--- head/sys/amd64/amd64/intr_machdep.c	Tue Jun  7 08:24:29 2011	(r222812)
+++ head/sys/amd64/amd64/intr_machdep.c	Tue Jun  7 08:46:13 2011	(r222813)
@@ -443,8 +443,7 @@ DB_SHOW_COMMAND(irqs, db_show_irqs)
  * allocate CPUs round-robin.
  */
 
-/* The BSP is always a valid target. */
-static cpumask_t intr_cpus = (1 << 0);
+static cpuset_t intr_cpus;
 static int current_cpu;
 
 /*
@@ -466,7 +465,7 @@ intr_next_cpu(void)
 		current_cpu++;
 		if (current_cpu > mp_maxid)
 			current_cpu = 0;
-	} while (!(intr_cpus & (1 << current_cpu)));
+	} while (!CPU_ISSET(current_cpu, &intr_cpus));
 	mtx_unlock_spin(&icu_lock);
 	return (apic_id);
 }
@@ -497,7 +496,7 @@ intr_add_cpu(u_int cpu)
 		printf("INTR: Adding local APIC %d as a target\n",
 		    cpu_apic_ids[cpu]);
 
-	intr_cpus |= (1 << cpu);
+	CPU_SET(cpu, &intr_cpus);
 }
 
 /*
@@ -510,6 +509,9 @@ intr_shuffle_irqs(void *arg __unused)
 	struct intsrc *isrc;
 	int i;
 
+	/* The BSP is always a valid target. */
+	CPU_SETOF(0, &intr_cpus);
+
 	/* Don't bother on UP. */
 	if (mp_ncpus == 1)
 		return;

Modified: head/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- head/sys/amd64/amd64/mp_machdep.c	Tue Jun  7 08:24:29 2011	(r222812)
+++ head/sys/amd64/amd64/mp_machdep.c	Tue Jun  7 08:46:13 2011	(r222813)
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
+#include <sys/cpuset.h>
 #ifdef GPROF 
 #include <sys/gmon.h>
 #endif
@@ -125,7 +126,7 @@ extern inthand_t IDTVEC(fast_syscall), I
  * Local data and functions.
  */
 
-static volatile cpumask_t ipi_nmi_pending;
+static volatile cpuset_t ipi_nmi_pending;
 
 /* used to hold the AP's until we are ready to release them */
 static struct mtx ap_boot_mtx;
@@ -161,7 +162,7 @@ static void	release_aps(void *dummy);
 
 static int	hlt_logical_cpus;
 static u_int	hyperthreading_cpus;	/* logical cpus sharing L1 cache */
-static cpumask_t	hyperthreading_cpus_mask;
+static cpuset_t	hyperthreading_cpus_mask;
 static int	hyperthreading_allowed = 1;
 static struct	sysctl_ctx_list logical_cpu_clist;
 static u_int	bootMP_size;
@@ -337,7 +338,7 @@ topo_probe(void)
 	if (cpu_topo_probed)
 		return;
 
-	logical_cpus_mask = 0;
+	CPU_ZERO(&logical_cpus_mask);
 	if (mp_ncpus <= 1)
 		cpu_cores = cpu_logical = 1;
 	else if (cpu_vendor_id == CPU_VENDOR_AMD)
@@ -481,7 +482,7 @@ cpu_mp_probe(void)
 	 * Always record BSP in CPU map so that the mbuf init code works
 	 * correctly.
 	 */
-	all_cpus = 1;
+	CPU_SETOF(0, &all_cpus);
 	if (mp_ncpus == 0) {
 		/*
 		 * No CPUs were found, so this must be a UP system.  Setup
@@ -608,6 +609,7 @@ cpu_mp_announce(void)
 void
 init_secondary(void)
 {
+	cpuset_t tcpuset, tallcpus;
 	struct pcpu *pc;
 	struct nmi_pcpu *np;
 	u_int64_t msr, cr0;
@@ -739,19 +741,22 @@ init_secondary(void)
 
 	CTR1(KTR_SMP, "SMP: AP CPU #%d Launched", PCPU_GET(cpuid));
 	printf("SMP: AP CPU #%d Launched!\n", PCPU_GET(cpuid));
+	tcpuset = PCPU_GET(cpumask);
 
 	/* Determine if we are a logical CPU. */
 	/* XXX Calculation depends on cpu_logical being a power of 2, e.g. 2 */
 	if (cpu_logical > 1 && PCPU_GET(apic_id) % cpu_logical != 0)
-		logical_cpus_mask |= PCPU_GET(cpumask);
-	
+		CPU_OR(&logical_cpus_mask, &tcpuset);
+
 	/* Determine if we are a hyperthread. */
 	if (hyperthreading_cpus > 1 &&
 	    PCPU_GET(apic_id) % hyperthreading_cpus != 0)
-		hyperthreading_cpus_mask |= PCPU_GET(cpumask);
+		CPU_OR(&hyperthreading_cpus_mask, &tcpuset);
 
 	/* Build our map of 'other' CPUs. */
-	PCPU_SET(other_cpus, all_cpus & ~PCPU_GET(cpumask));
+	tallcpus = all_cpus;
+	CPU_NAND(&tallcpus, &tcpuset);
+	PCPU_SET(other_cpus, tallcpus);
 
 	if (bootverbose)
 		lapic_dump("AP");
@@ -894,6 +899,7 @@ assign_cpu_ids(void)
 static int
 start_all_aps(void)
 {
+	cpuset_t tallcpus, tcpuset;
 	vm_offset_t va = boot_address + KERNBASE;
 	u_int64_t *pt4, *pt3, *pt2;
 	u_int32_t mpbioswarmvec;
@@ -958,11 +964,14 @@ start_all_aps(void)
 			panic("AP #%d (PHY# %d) failed!", cpu, apic_id);
 		}
 
-		all_cpus |= (1 << cpu);		/* record AP in CPU map */
+		CPU_SET(cpu, &all_cpus);	/* record AP in CPU map */
 	}
 
 	/* build our map of 'other' CPUs */
-	PCPU_SET(other_cpus, all_cpus & ~PCPU_GET(cpumask));
+	tallcpus = all_cpus;
+	tcpuset = PCPU_GET(cpumask);
+	CPU_NAND(&tallcpus, &tcpuset);
+	PCPU_SET(other_cpus, tallcpus);
 
 	/* restore the warmstart vector */
 	*(u_int32_t *) WARMBOOT_OFF = mpbioswarmvec;
@@ -1091,6 +1100,30 @@ SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_
 #endif /* COUNT_XINVLTLB_HITS */
 
 /*
+ * Send an IPI to specified CPU handling the bitmap logic.
+ */
+static void
+ipi_send_cpu(int cpu, u_int ipi)
+{
+	u_int bitmap, old_pending, new_pending;
+
+	KASSERT(cpu_apic_ids[cpu] != -1, ("IPI to non-existent CPU %d", cpu));
+
+	if (IPI_IS_BITMAPED(ipi)) {
+		bitmap = 1 << ipi;
+		ipi = IPI_BITMAP_VECTOR;
+		do {
+			old_pending = cpu_ipi_pending[cpu];
+			new_pending = old_pending | bitmap;
+		} while  (!atomic_cmpset_int(&cpu_ipi_pending[cpu],
+		    old_pending, new_pending)); 
+		if (old_pending)
+			return;
+	}
+	lapic_ipi_vectored(ipi, cpu_apic_ids[cpu]);
+}
+
+/*
  * Flush the TLB on all other CPU's
  */
 static void
@@ -1114,28 +1147,19 @@ smp_tlb_shootdown(u_int vector, vm_offse
 }
 
 static void
-smp_targeted_tlb_shootdown(cpumask_t mask, u_int vector, vm_offset_t addr1, vm_offset_t addr2)
+smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, vm_offset_t addr1, vm_offset_t addr2)
 {
-	int ncpu, othercpus;
+	int cpu, ncpu, othercpus;
 
 	othercpus = mp_ncpus - 1;
-	if (mask == (cpumask_t)-1) {
-		ncpu = othercpus;
-		if (ncpu < 1)
+	if (CPU_ISFULLSET(&mask)) {
+		if (othercpus < 1)
 			return;
 	} else {
-		mask &= ~PCPU_GET(cpumask);
-		if (mask == 0)
-			return;
-		ncpu = bitcount32(mask);
-		if (ncpu > othercpus) {
-			/* XXX this should be a panic offence */
-			printf("SMP: tlb shootdown to %d other cpus (only have %d)\n",
-			    ncpu, othercpus);
-			ncpu = othercpus;
-		}
-		/* XXX should be a panic, implied by mask == 0 above */
-		if (ncpu < 1)
+		sched_pin();
+		CPU_NAND(&mask, PCPU_PTR(cpumask));
+		sched_unpin();
+		if (CPU_EMPTY(&mask))
 			return;
 	}
 	if (!(read_rflags() & PSL_I))
@@ -1144,39 +1168,25 @@ smp_targeted_tlb_shootdown(cpumask_t mas
 	smp_tlb_addr1 = addr1;
 	smp_tlb_addr2 = addr2;
 	atomic_store_rel_int(&smp_tlb_wait, 0);
-	if (mask == (cpumask_t)-1)
+	if (CPU_ISFULLSET(&mask)) {
+		ncpu = othercpus;
 		ipi_all_but_self(vector);
-	else
-		ipi_selected(mask, vector);
+	} else {
+		ncpu = 0;
+		while ((cpu = cpusetobj_ffs(&mask)) != 0) {
+			cpu--;
+			CPU_CLR(cpu, &mask);
+			CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__,
+			    cpu, vector);
+			ipi_send_cpu(cpu, vector);
+			ncpu++;
+		}
+	}
 	while (smp_tlb_wait < ncpu)
 		ia32_pause();
 	mtx_unlock_spin(&smp_ipi_mtx);
 }
 
-/*
- * Send an IPI to specified CPU handling the bitmap logic.
- */
-static void
-ipi_send_cpu(int cpu, u_int ipi)
-{
-	u_int bitmap, old_pending, new_pending;
-
-	KASSERT(cpu_apic_ids[cpu] != -1, ("IPI to non-existent CPU %d", cpu));
-
-	if (IPI_IS_BITMAPED(ipi)) {
-		bitmap = 1 << ipi;
-		ipi = IPI_BITMAP_VECTOR;
-		do {
-			old_pending = cpu_ipi_pending[cpu];
-			new_pending = old_pending | bitmap;
-		} while  (!atomic_cmpset_int(&cpu_ipi_pending[cpu],
-		    old_pending, new_pending)); 
-		if (old_pending)
-			return;
-	}
-	lapic_ipi_vectored(ipi, cpu_apic_ids[cpu]);
-}
-
 void
 smp_cache_flush(void)
 {
@@ -1223,7 +1233,7 @@ smp_invlpg_range(vm_offset_t addr1, vm_o
 }
 
 void
-smp_masked_invltlb(cpumask_t mask)
+smp_masked_invltlb(cpuset_t mask)
 {
 
 	if (smp_started) {
@@ -1235,7 +1245,7 @@ smp_masked_invltlb(cpumask_t mask)
 }
 
 void
-smp_masked_invlpg(cpumask_t mask, vm_offset_t addr)
+smp_masked_invlpg(cpuset_t mask, vm_offset_t addr)
 {
 
 	if (smp_started) {
@@ -1247,7 +1257,7 @@ smp_masked_invlpg(cpumask_t mask, vm_off
 }
 
 void
-smp_masked_invlpg_range(cpumask_t mask, vm_offset_t addr1, vm_offset_t addr2)
+smp_masked_invlpg_range(cpuset_t mask, vm_offset_t addr1, vm_offset_t addr2)
 {
 
 	if (smp_started) {
@@ -1300,7 +1310,7 @@ ipi_bitmap_handler(struct trapframe fram
  * send an IPI to a set of cpus.
  */
 void
-ipi_selected(cpumask_t cpus, u_int ipi)
+ipi_selected(cpuset_t cpus, u_int ipi)
 {
 	int cpu;
 
@@ -1310,12 +1320,12 @@ ipi_selected(cpumask_t cpus, u_int ipi)
 	 * Set the mask of receiving CPUs for this purpose.
 	 */
 	if (ipi == IPI_STOP_HARD)
-		atomic_set_int(&ipi_nmi_pending, cpus);
+		CPU_OR_ATOMIC(&ipi_nmi_pending, &cpus);
 
-	CTR3(KTR_SMP, "%s: cpus: %x ipi: %x", __func__, cpus, ipi);
-	while ((cpu = ffs(cpus)) != 0) {
+	while ((cpu = cpusetobj_ffs(&cpus)) != 0) {
 		cpu--;
-		cpus &= ~(1 << cpu);
+		CPU_CLR(cpu, &cpus);
+		CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu, ipi);
 		ipi_send_cpu(cpu, ipi);
 	}
 }
@@ -1333,7 +1343,7 @@ ipi_cpu(int cpu, u_int ipi)
 	 * Set the mask of receiving CPUs for this purpose.
 	 */
 	if (ipi == IPI_STOP_HARD)
-		atomic_set_int(&ipi_nmi_pending, 1 << cpu);
+		CPU_SET_ATOMIC(cpu, &ipi_nmi_pending);
 
 	CTR3(KTR_SMP, "%s: cpu: %d ipi: %x", __func__, cpu, ipi);
 	ipi_send_cpu(cpu, ipi);
@@ -1346,8 +1356,10 @@ void
 ipi_all_but_self(u_int ipi)
 {
 
+	sched_pin();
 	if (IPI_IS_BITMAPED(ipi)) {
 		ipi_selected(PCPU_GET(other_cpus), ipi);
+		sched_unpin();
 		return;
 	}
 
@@ -1357,7 +1369,8 @@ ipi_all_but_self(u_int ipi)
 	 * Set the mask of receiving CPUs for this purpose.
 	 */
 	if (ipi == IPI_STOP_HARD)
-		atomic_set_int(&ipi_nmi_pending, PCPU_GET(other_cpus));
+		CPU_OR_ATOMIC(&ipi_nmi_pending, PCPU_PTR(other_cpus));
+	sched_unpin();
 
 	CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
 	lapic_ipi_vectored(ipi, APIC_IPI_DEST_OTHERS);
@@ -1366,7 +1379,7 @@ ipi_all_but_self(u_int ipi)
 int
 ipi_nmi_handler()
 {
-	cpumask_t cpumask;
+	cpuset_t cpumask;
 
 	/*
 	 * As long as there is not a simple way to know about a NMI's
@@ -1374,11 +1387,13 @@ ipi_nmi_handler()
 	 * the global pending bitword an IPI_STOP_HARD has been issued
 	 * and should be handled.
 	 */
+	sched_pin();
 	cpumask = PCPU_GET(cpumask);
-	if ((ipi_nmi_pending & cpumask) == 0)
+	sched_unpin();
+	if (!CPU_OVERLAP(&ipi_nmi_pending, &cpumask))
 		return (1);
 
-	atomic_clear_int(&ipi_nmi_pending, cpumask);
+	CPU_NAND_ATOMIC(&ipi_nmi_pending, &cpumask);
 	cpustop_handler();
 	return (0);
 }
@@ -1390,23 +1405,25 @@ ipi_nmi_handler()
 void
 cpustop_handler(void)
 {
-	cpumask_t cpumask;
+	cpuset_t cpumask;
 	u_int cpu;
 
+	sched_pin();
 	cpu = PCPU_GET(cpuid);
 	cpumask = PCPU_GET(cpumask);
+	sched_unpin();
 
 	savectx(&stoppcbs[cpu]);
 
 	/* Indicate that we are stopped */
-	atomic_set_int(&stopped_cpus, cpumask);
+	CPU_OR_ATOMIC(&stopped_cpus, &cpumask);
 
 	/* Wait for restart */
-	while (!(started_cpus & cpumask))
+	while (!CPU_OVERLAP(&started_cpus, &cpumask))
 	    ia32_pause();
 
-	atomic_clear_int(&started_cpus, cpumask);
-	atomic_clear_int(&stopped_cpus, cpumask);
+	CPU_NAND_ATOMIC(&started_cpus, &cpumask);
+	CPU_NAND_ATOMIC(&stopped_cpus, &cpumask);
 
 	if (cpu == 0 && cpustop_restartfunc != NULL) {
 		cpustop_restartfunc();
@@ -1421,7 +1438,7 @@ cpustop_handler(void)
 void
 cpususpend_handler(void)
 {
-	cpumask_t cpumask;
+	cpuset_t cpumask;
 	register_t cr3, rf;
 	u_int cpu;
 
@@ -1433,7 +1450,7 @@ cpususpend_handler(void)
 
 	if (savectx(susppcbs[cpu])) {
 		wbinvd();
-		atomic_set_int(&stopped_cpus, cpumask);
+		CPU_OR_ATOMIC(&stopped_cpus, &cpumask);
 	} else {
 		pmap_init_pat();
 		PCPU_SET(switchtime, 0);
@@ -1441,11 +1458,11 @@ cpususpend_handler(void)
 	}
 
 	/* Wait for resume */
-	while (!(started_cpus & cpumask))
+	while (!CPU_OVERLAP(&started_cpus, &cpumask))
 		ia32_pause();
 
-	atomic_clear_int(&started_cpus, cpumask);
-	atomic_clear_int(&stopped_cpus, cpumask);
+	CPU_NAND_ATOMIC(&started_cpus, &cpumask);
+	CPU_NAND_ATOMIC(&stopped_cpus, &cpumask);
 
 	/* Restore CR3 and enable interrupts */
 	load_cr3(cr3);
@@ -1473,30 +1490,30 @@ SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_
 static int
 sysctl_hlt_cpus(SYSCTL_HANDLER_ARGS)
 {
-	cpumask_t mask;
+	cpuset_t mask;
 	int error;
 
 	mask = hlt_cpus_mask;
-	error = sysctl_handle_int(oidp, &mask, 0, req);
+	error = sysctl_handle_opaque(oidp, &mask, sizeof(mask), req);
 	if (error || !req->newptr)
 		return (error);
 
-	if (logical_cpus_mask != 0 &&
-	    (mask & logical_cpus_mask) == logical_cpus_mask)
+	if (!CPU_EMPTY(&logical_cpus_mask) &&
+	    CPU_SUBSET(&mask, &logical_cpus_mask))
 		hlt_logical_cpus = 1;
 	else
 		hlt_logical_cpus = 0;
 
 	if (! hyperthreading_allowed)
-		mask |= hyperthreading_cpus_mask;
+		CPU_OR(&mask, &hyperthreading_cpus_mask);
 
-	if ((mask & all_cpus) == all_cpus)
-		mask &= ~(1<<0);
+	if (CPU_SUBSET(&mask, &all_cpus))
+		CPU_CLR(0, &mask);
 	hlt_cpus_mask = mask;
 	return (error);
 }
-SYSCTL_PROC(_machdep, OID_AUTO, hlt_cpus, CTLTYPE_INT|CTLFLAG_RW,
-    0, 0, sysctl_hlt_cpus, "IU",
+SYSCTL_PROC(_machdep, OID_AUTO, hlt_cpus,
+    CTLTYPE_STRUCT | CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 0, sysctl_hlt_cpus, "S",
     "Bitmap of CPUs to halt.  101 (binary) will halt CPUs 0 and 2.");
 
 static int
@@ -1510,15 +1527,15 @@ sysctl_hlt_logical_cpus(SYSCTL_HANDLER_A
 		return (error);
 
 	if (disable)
-		hlt_cpus_mask |= logical_cpus_mask;
+		CPU_OR(&hlt_cpus_mask, &logical_cpus_mask);
 	else
-		hlt_cpus_mask &= ~logical_cpus_mask;
+		CPU_NAND(&hlt_cpus_mask, &logical_cpus_mask);
 
 	if (! hyperthreading_allowed)
-		hlt_cpus_mask |= hyperthreading_cpus_mask;
+		CPU_OR(&hlt_cpus_mask, &hyperthreading_cpus_mask);
 
-	if ((hlt_cpus_mask & all_cpus) == all_cpus)
-		hlt_cpus_mask &= ~(1<<0);
+	if (CPU_SUBSET(&hlt_cpus_mask, &all_cpus))
+		CPU_CLR(0, &hlt_cpus_mask);
 
 	hlt_logical_cpus = disable;
 	return (error);
@@ -1545,18 +1562,18 @@ sysctl_hyperthreading_allowed(SYSCTL_HAN
 #endif
 
 	if (allowed)
-		hlt_cpus_mask &= ~hyperthreading_cpus_mask;
+		CPU_NAND(&hlt_cpus_mask, &hyperthreading_cpus_mask);
 	else
-		hlt_cpus_mask |= hyperthreading_cpus_mask;
+		CPU_OR(&hlt_cpus_mask, &hyperthreading_cpus_mask);
 
-	if (logical_cpus_mask != 0 &&
-	    (hlt_cpus_mask & logical_cpus_mask) == logical_cpus_mask)
+	if (!CPU_EMPTY(&logical_cpus_mask) &&
+	    CPU_SUBSET(&hlt_cpus_mask, &logical_cpus_mask))
 		hlt_logical_cpus = 1;
 	else
 		hlt_logical_cpus = 0;
 
-	if ((hlt_cpus_mask & all_cpus) == all_cpus)
-		hlt_cpus_mask &= ~(1<<0);
+	if (CPU_SUBSET(&hlt_cpus_mask, &all_cpus))

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list