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 [email protected] .

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 ***
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to