Module Name:    src
Committed By:   matt
Date:           Wed Jun 10 22:31:00 UTC 2015

Modified Files:
        src/sys/arch/evbmips/cavium: machdep.c
        src/sys/arch/mips/cavium: octeon_cpunode.c octeonvar.h
        src/sys/arch/mips/include: cpu.h pmap.h types.h
        src/sys/arch/mips/mips: cpu_subr.c ipifuncs.c locore_octeon.S pmap.c
            pmap_tlb.c
        src/sys/arch/mips/rmi: rmixl_cpu.c rmixl_intr.c
Removed Files:
        src/sys/arch/mips/include: cpuset.h

Log Message:
Transition from __cpuset_t to kcpuset_t *.  This brings the local pmap one
step closer to uvm/pmap, its eventual replacement.  Tested on ERLITE MP kernel.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/evbmips/cavium/machdep.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/mips/cavium/octeon_cpunode.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/mips/cavium/octeonvar.h
cvs rdiff -u -r1.115 -r1.116 src/sys/arch/mips/include/cpu.h
cvs rdiff -u -r1.3 -r0 src/sys/arch/mips/include/cpuset.h
cvs rdiff -u -r1.64 -r1.65 src/sys/arch/mips/include/pmap.h
cvs rdiff -u -r1.56 -r1.57 src/sys/arch/mips/include/types.h
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/mips/mips/cpu_subr.c
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/mips/mips/ipifuncs.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/mips/mips/locore_octeon.S
cvs rdiff -u -r1.214 -r1.215 src/sys/arch/mips/mips/pmap.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/mips/mips/pmap_tlb.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/mips/rmi/rmixl_cpu.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/mips/rmi/rmixl_intr.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/evbmips/cavium/machdep.c
diff -u src/sys/arch/evbmips/cavium/machdep.c:1.4 src/sys/arch/evbmips/cavium/machdep.c:1.5
--- src/sys/arch/evbmips/cavium/machdep.c:1.4	Thu Jun  4 05:21:09 2015
+++ src/sys/arch/evbmips/cavium/machdep.c	Wed Jun 10 22:31:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.4 2015/06/04 05:21:09 matt Exp $	*/
+/*	$NetBSD: machdep.c,v 1.5 2015/06/10 22:31:00 matt Exp $	*/
 
 /*
  * Copyright 2001, 2002 Wasabi Systems, Inc.
@@ -111,8 +111,10 @@
  *	from: Utah Hdr: machdep.c 1.63 91/04/24
  */
 
+#include "opt_multiprocessor.h"
+
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.4 2015/06/04 05:21:09 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.5 2015/06/10 22:31:00 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -172,8 +174,6 @@ int	netboot;
 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
 int mem_cluster_cnt;
 
-
-void	configure(void);
 void	mach_init(uint64_t, uint64_t, uint64_t, uint64_t);
 
 struct octeon_config octeon_configuration;
@@ -233,6 +233,7 @@ mach_init(uint64_t arg0, uint64_t arg1, 
 	mips_init_lwp0_uarea();
 
 	boothowto = RB_AUTOBOOT;
+	boothowto |= AB_VERBOSE;
 
 #if defined(DDB)
 	if (boothowto & RB_KDB)
@@ -266,7 +267,7 @@ mach_init_vector(void)
 {
 
 	/* Make sure exception base at 0 (MIPS_COP_0_EBASE) */
-	asm volatile("mtc0 %0, $15, 1" : : "r"(0x80000000) );
+	__asm __volatile("mtc0 %0, $15, 1" : : "r"(0x80000000) );
 
 	/*
 	 * Set up the exception vectors and CPU-specific function
@@ -275,11 +276,7 @@ mach_init_vector(void)
 	 * first printf() after that is called).
 	 * Also clears the I+D caches.
 	 */
-#if MULTIPROCESSOR
 	mips_vector_init(NULL, true);
-#else
-	mips_vector_init(NULL, false);
-#endif
 }
 
 void
@@ -380,6 +377,11 @@ int	waittime = -1;
 void
 cpu_startup(void)
 {
+#ifdef MULTIPROCESSOR
+	// Create a kcpuset so we can see on which CPUs the kernel was started.
+	kcpuset_create(&cpus_booted, true);
+#endif
+
 	/*
 	 * Do the common startup items.
 	 */

Index: src/sys/arch/mips/cavium/octeon_cpunode.c
diff -u src/sys/arch/mips/cavium/octeon_cpunode.c:1.4 src/sys/arch/mips/cavium/octeon_cpunode.c:1.5
--- src/sys/arch/mips/cavium/octeon_cpunode.c:1.4	Tue Jun  9 12:10:08 2015
+++ src/sys/arch/mips/cavium/octeon_cpunode.c	Wed Jun 10 22:31:00 2015
@@ -40,6 +40,7 @@ __KERNEL_RCSID(0, "$NetBSD");
 #include <sys/device.h>
 #include <sys/lwp.h>
 #include <sys/cpu.h>
+#include <sys/atomic.h>
 #include <sys/wdog.h>
 
 #include <uvm/uvm.h>
@@ -47,7 +48,6 @@ __KERNEL_RCSID(0, "$NetBSD");
 #include <dev/sysmon/sysmonvar.h>
 
 #include <mips/cache.h>
-#include <mips/cpuset.h>
 #include <mips/mips_opcode.h>
 #include <mips/mips3_clock.h>
 
@@ -78,7 +78,7 @@ CFATTACH_DECL_NEW(cpunode, sizeof(struct
 CFATTACH_DECL_NEW(cpu_cpunode, 0,
     cpu_cpunode_match, cpu_cpunode_attach, NULL, NULL);
 
-volatile __cpuset_t cpus_booted = 1;
+kcpuset_t *cpus_booted;
 
 void octeon_reset_vector(void);
 
@@ -123,7 +123,9 @@ cpunode_mainbus_attach(device_t parent, 
 	if (cvmctl & CP0_CVMCTL_REPUN)
 		aprint_normal(", unaligned-access ok");
 #ifdef MULTIPROCESSOR
-	aprint_normal(", booted %#" PRIx64, cpus_booted);
+	uint32_t booted[1];
+	kcpuset_export_u32(cpus_booted, booted, sizeof(booted));
+	aprint_normal(", booted %#" PRIx32, booted[0]);
 #endif
 	aprint_normal("\n");
 
@@ -290,7 +292,7 @@ cpu_cpunode_attach(device_t parent, devi
 	}
 #ifdef MULTIPROCESSOR
 	KASSERTMSG(cpunum == 1, "cpunum %d", cpunum);
-	if (!CPUSET_HAS_P(cpus_booted, cpunum)) {
+	if (!kcpuset_isset(cpus_booted, cpunum)) {
 		aprint_naive(" disabled\n");
 		aprint_normal(" disabled (unresponsive)\n");
 		return;
@@ -303,10 +305,10 @@ cpu_cpunode_attach(device_t parent, devi
 	cpu_cpunode_attach_common(self, ci);
 
 	KASSERT(ci->ci_data.cpu_idlelwp != NULL);
-	for (int i = 0; i < 100 && !CPUSET_HAS_P(cpus_hatched, cpunum); i++) {
+	for (int i = 0; i < 100 && !kcpuset_isset(cpus_hatched, cpunum); i++) {
 		delay(10000);
 	}
-	if (!CPUSET_HAS_P(cpus_hatched, cpunum)) {
+	if (!kcpuset_isset(cpus_hatched, cpunum)) {
 #ifdef DDB
 		aprint_verbose_dev(self, "hatch failed ci=%p flags=%#"PRIx64"\n", ci, ci->ci_flags);
 		cpu_Debugger();

Index: src/sys/arch/mips/cavium/octeonvar.h
diff -u src/sys/arch/mips/cavium/octeonvar.h:1.3 src/sys/arch/mips/cavium/octeonvar.h:1.4
--- src/sys/arch/mips/cavium/octeonvar.h:1.3	Sat Jun  6 20:52:16 2015
+++ src/sys/arch/mips/cavium/octeonvar.h	Wed Jun 10 22:31:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: octeonvar.h,v 1.3 2015/06/06 20:52:16 matt Exp $	*/
+/*	$NetBSD: octeonvar.h,v 1.4 2015/06/10 22:31:00 matt Exp $	*/
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -34,6 +34,7 @@
 
 #include <sys/bus.h>
 #include <sys/evcnt.h>
+#include <sys/kcpuset.h>
 #include <mips/locore.h>
 #include <dev/pci/pcivar.h>
 
@@ -224,6 +225,7 @@ struct octeon_fau_map {
 #ifdef _KERNEL
 extern struct octeon_config	octeon_configuration;
 #ifdef MULTIPROCESSOR
+extern kcpuset_t *cpus_booted;
 extern struct cpu_softc		octeon_cpu1_softc;
 #endif
 

Index: src/sys/arch/mips/include/cpu.h
diff -u src/sys/arch/mips/include/cpu.h:1.115 src/sys/arch/mips/include/cpu.h:1.116
--- src/sys/arch/mips/include/cpu.h:1.115	Sun Jun  7 06:07:49 2015
+++ src/sys/arch/mips/include/cpu.h	Wed Jun 10 22:31:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.115 2015/06/07 06:07:49 matt Exp $	*/
+/*	$NetBSD: cpu.h,v 1.116 2015/06/10 22:31:00 matt Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -55,6 +55,7 @@
 #include <sys/cpu_data.h>
 #include <sys/device_if.h>
 #include <sys/evcnt.h>
+#include <sys/kcpuset.h>
 
 typedef struct cpu_watchpoint {
 	register_t	cw_addr;
@@ -460,9 +461,9 @@ extern struct mips_options mips_options;
 void cpu_broadcast_ipi(int);
 
 /*
- * Send an inter-processor interupt to CPUs in cpuset (excludes curcpu())
+ * Send an inter-processor interupt to CPUs in kcpuset (excludes curcpu())
  */
-void cpu_multicast_ipi(__cpuset_t, int);
+void cpu_multicast_ipi(const kcpuset_t *, int);
 
 /*
  * Send an inter-processor interupt to another CPU.
@@ -560,16 +561,16 @@ void	cpu_halt(void);
 void	cpu_halt_others(void);
 void	cpu_pause(struct reg *);
 void	cpu_pause_others(void);
-void	cpu_resume(int);
+void	cpu_resume(cpuid_t);
 void	cpu_resume_others(void);
-int	cpu_is_paused(int);
+bool	cpu_is_paused(cpuid_t);
 void	cpu_debug_dump(void);
 
-extern volatile __cpuset_t cpus_running;
-extern volatile __cpuset_t cpus_hatched;
-extern volatile __cpuset_t cpus_paused;
-extern volatile __cpuset_t cpus_resumed;
-extern volatile __cpuset_t cpus_halted;
+extern kcpuset_t *cpus_running;
+extern kcpuset_t *cpus_hatched;
+extern kcpuset_t *cpus_paused;
+extern kcpuset_t *cpus_resumed;
+extern kcpuset_t *cpus_halted;
 #endif
 
 /* copy.S */

Index: src/sys/arch/mips/include/pmap.h
diff -u src/sys/arch/mips/include/pmap.h:1.64 src/sys/arch/mips/include/pmap.h:1.65
--- src/sys/arch/mips/include/pmap.h:1.64	Sun Jun  7 06:07:49 2015
+++ src/sys/arch/mips/include/pmap.h	Wed Jun 10 22:31:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.h,v 1.64 2015/06/07 06:07:49 matt Exp $	*/
+/*	$NetBSD: pmap.h,v 1.65 2015/06/10 22:31:00 matt Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -79,9 +79,9 @@
 #endif
 
 #include <sys/evcnt.h>
+#include <sys/kcpuset.h>
 
 #include <mips/cpuregs.h>	/* for KSEG0 below */
-//#include <mips/pte.h>
 
 /*
  * The user address space is 2Gb (0x0 - 0x80000000).
@@ -174,8 +174,8 @@ struct pmap_asid_info {
  */
 struct pmap {
 #ifdef MULTIPROCESSOR
-	volatile uint32_t	pm_active;	/* pmap was active on ... */
-	volatile uint32_t	pm_onproc;	/* pmap is active on ... */
+	kcpuset_t		*pm_active;	/* pmap was active on ... */
+	kcpuset_t		*pm_onproc;	/* pmap is active on ... */
 	volatile u_int		pm_shootdown_pending;
 #endif
 	union segtab		*pm_segtab;	/* pointers to pages of PTEs */
@@ -207,7 +207,7 @@ struct pmap_tlb_info {
 #ifdef MULTIPROCESSOR
 	pmap_t ti_victim;
 	uint32_t ti_synci_page_bitmap;	/* page indices needing a syncicache */
-	uint32_t ti_cpu_mask;		/* bitmask of CPUs sharing this TLB */
+	kcpuset_t *ti_kcpuset;		/* bitmask of CPUs sharing this TLB */
 	enum tlb_invalidate_op ti_tlbinvop;
 	u_int ti_index;
 #define tlbinfo_index(ti)	((ti)->ti_index)
@@ -264,7 +264,7 @@ bool	pmap_tlb_shootdown_bystanders(pmap_
 void	pmap_tlb_info_attach(struct pmap_tlb_info *, struct cpu_info *);
 void	pmap_tlb_syncicache_ast(struct cpu_info *);
 void	pmap_tlb_syncicache_wanted(struct cpu_info *);
-void	pmap_tlb_syncicache(vaddr_t, uint32_t);
+void	pmap_tlb_syncicache(vaddr_t, const kcpuset_t *);
 #endif
 void	pmap_tlb_info_init(struct pmap_tlb_info *);
 void	pmap_tlb_info_evcnt_attach(struct pmap_tlb_info *);

Index: src/sys/arch/mips/include/types.h
diff -u src/sys/arch/mips/include/types.h:1.56 src/sys/arch/mips/include/types.h:1.57
--- src/sys/arch/mips/include/types.h:1.56	Sat Jun  6 17:45:49 2015
+++ src/sys/arch/mips/include/types.h	Wed Jun 10 22:31:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: types.h,v 1.56 2015/06/06 17:45:49 macallan Exp $	*/
+/*	$NetBSD: types.h,v 1.57 2015/06/10 22:31:00 matt Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -131,15 +131,6 @@ typedef struct label_t {
 #define	PCU_UNIT_COUNT	2
 #endif
 
-#if defined(__mips_o32)
-typedef __uint32_t		__cpuset_t;
-#define	__CPUSET_MAXNUMCPU	32
-#define	PRIxCPUSET		PRIx32
-#else
-typedef __uint64_t		__cpuset_t;
-#define	__CPUSET_MAXNUMCPU	64
-#define	PRIxCPUSET		PRIx64
-#endif
 typedef	volatile unsigned int	__cpu_simple_lock_t;
 
 #define	__SIMPLELOCK_LOCKED	1

Index: src/sys/arch/mips/mips/cpu_subr.c
diff -u src/sys/arch/mips/mips/cpu_subr.c:1.23 src/sys/arch/mips/mips/cpu_subr.c:1.24
--- src/sys/arch/mips/mips/cpu_subr.c:1.23	Sat Jun  6 21:03:45 2015
+++ src/sys/arch/mips/mips/cpu_subr.c	Wed Jun 10 22:31:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu_subr.c,v 1.23 2015/06/06 21:03:45 matt Exp $	*/
+/*	$NetBSD: cpu_subr.c,v 1.24 2015/06/10 22:31:00 matt Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.23 2015/06/06 21:03:45 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.24 2015/06/10 22:31:00 matt Exp $");
 
 #include "opt_cputype.h"
 #include "opt_ddb.h"
@@ -47,6 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v
 #include <sys/bitops.h>
 #include <sys/idle.h>
 #include <sys/xcall.h>
+#include <sys/kernel.h>
 #include <sys/ipi.h>
 
 #include <uvm/uvm.h>
@@ -58,7 +59,6 @@ __KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v
 #include <mips/frame.h>
 #include <mips/userret.h>
 #include <mips/pte.h>
-#include <mips/cpuset.h>
 
 #if defined(DDB) || defined(KGDB)
 #ifdef DDB 
@@ -106,14 +106,13 @@ struct cpu_info * cpuid_infos[MAXCPUS] =
 	[0] = &cpu_info_store,
 };
 
-volatile __cpuset_t cpus_running = 1;
-volatile __cpuset_t cpus_hatched = 1;
-volatile __cpuset_t cpus_paused = 0;
-volatile __cpuset_t cpus_resumed = 0;
-volatile __cpuset_t cpus_halted = 0;
+kcpuset_t *cpus_halted;
+kcpuset_t *cpus_hatched;
+kcpuset_t *cpus_paused;
+kcpuset_t *cpus_resumed;
+kcpuset_t *cpus_running;
 
-static int  cpu_ipi_wait(volatile __cpuset_t *, u_long);
-static void cpu_ipi_error(const char *, __cpuset_t, __cpuset_t);
+static void cpu_ipi_wait(const char *, const kcpuset_t *, const kcpuset_t *);
 
 struct cpu_info *
 cpu_info_alloc(struct pmap_tlb_info *ti, cpuid_t cpu_id, cpuid_t cpu_package_id,
@@ -307,6 +306,21 @@ cpu_startup_common(void)
 
 	pmap_tlb_info_evcnt_attach(&pmap_tlb0_info);
 
+#ifdef MULTIPROCESSOR
+	kcpuset_create(&cpus_halted, true);
+		KASSERT(cpus_halted != NULL);
+	kcpuset_create(&cpus_hatched, true);
+		KASSERT(cpus_hatched != NULL);
+	kcpuset_create(&cpus_paused, true);
+		KASSERT(cpus_paused != NULL);
+	kcpuset_create(&cpus_resumed, true);
+		KASSERT(cpus_resumed != NULL);
+	kcpuset_create(&cpus_running, true);
+		KASSERT(cpus_running != NULL);
+	kcpuset_set(cpus_hatched, cpu_number());
+	kcpuset_set(cpus_running, cpu_number());
+#endif
+
 	cpu_hwrena_setup();
 
 	/*
@@ -637,26 +651,26 @@ cpu_intr_p(void)
 void
 cpu_broadcast_ipi(int tag)
 {
-	(void)cpu_multicast_ipi(
-		CPUSET_EXCEPT(cpus_running, cpu_index(curcpu())), tag);
+	// No reason to remove ourselves since multicast_ipi will do that for us
+	cpu_multicast_ipi(cpus_running, tag);
 }
 
 void
-cpu_multicast_ipi(__cpuset_t cpuset, int tag)
+cpu_multicast_ipi(const kcpuset_t *kcp, int tag)
 {
-	CPU_INFO_ITERATOR cii;
-	struct cpu_info *ci;
+	struct cpu_info * const ci = curcpu();
+	kcpuset_t *kcp2;
 
-	CPUSET_DEL(cpuset, cpu_index(curcpu()));
-	if (CPUSET_EMPTY_P(cpuset))
+	if (kcpuset_match(cpus_running, ci->ci_data.cpu_kcpuset))
 		return;
 
-	for (CPU_INFO_FOREACH(cii, ci)) {
-		if (CPUSET_HAS_P(cpuset, cpu_index(ci))) {
-			CPUSET_DEL(cpuset, cpu_index(ci));
-			(void)cpu_send_ipi(ci, tag);
-		}
+	kcpuset_clone(&kcp2, kcp);
+	kcpuset_remove(kcp2, ci->ci_data.cpu_kcpuset);
+	for (cpuid_t cii; (cii = kcpuset_ffs(kcp2)) != 0; ) {
+		kcpuset_clear(kcp2, --cii);
+		(void)cpu_send_ipi(cpu_lookup(cii), tag);
 	}
+	kcpuset_destroy(kcp2);
 }
 
 int
@@ -667,30 +681,35 @@ cpu_send_ipi(struct cpu_info *ci, int ta
 }
 
 static void
-cpu_ipi_error(const char *s, __cpuset_t succeeded, __cpuset_t expected)
-{
-	CPUSET_SUB(expected, succeeded);
-	if (!CPUSET_EMPTY_P(expected)) {
-		printf("Failed to %s:", s);
-		do {
-			int index = CPUSET_NEXT(expected);
-			CPUSET_DEL(expected, index);
-			printf(" cpu%d", index);
-		} while (!CPUSET_EMPTY_P(expected));
-		printf("\n");
-	}
-}
-
-static int
-cpu_ipi_wait(volatile __cpuset_t *watchset, u_long mask)
+cpu_ipi_wait(const char *s, const kcpuset_t *watchset, const kcpuset_t *wanted)
 {
-	u_long limit = curcpu()->ci_cpu_freq/10;/* some finite amount of time */
+	bool done = false;
+	kcpuset_t *kcp;
+	kcpuset_create(&kcp, false);
+	
+	/* some finite amount of time */
 
-	while (limit--)
-		if (*watchset == mask)
-			return 0;		/* success */
+	for (u_long limit = curcpu()->ci_cpu_freq/10; !done && limit--; ) {
+		kcpuset_copy(kcp, watchset);
+		kcpuset_intersect(kcp, wanted);
+		done = kcpuset_match(kcp, wanted);
+	}
+
+	if (!done) {
+		cpuid_t cii;
+		kcpuset_copy(kcp, wanted);
+		kcpuset_remove(kcp, watchset);
+		if ((cii = kcpuset_ffs(kcp)) != 0) {
+			printf("Failed to %s:", s);
+			do {
+				kcpuset_clear(kcp, --cii);
+				printf(" cpu%lu", cii);
+			} while ((cii = kcpuset_ffs(kcp)) != 0);
+			printf("\n");
+		}
+	}
 
-	return 1;				/* timed out */
+	kcpuset_destroy(kcp);
 }
 
 /*
@@ -699,10 +718,10 @@ cpu_ipi_wait(volatile __cpuset_t *watchs
 void
 cpu_halt(void)
 {
-	int index = cpu_index(curcpu());
+	cpuid_t cii = cpu_index(curcpu());
 
-	printf("cpu%d: shutting down\n", index);
-	CPUSET_ADD(cpus_halted, index);
+	printf("cpu%lu: shutting down\n", cii);
+	kcpuset_atomic_set(cpus_halted, cii);
 	spl0();		/* allow interrupts e.g. further ipi ? */
 	for (;;) ;	/* spin */
 
@@ -715,24 +734,29 @@ cpu_halt(void)
 void
 cpu_halt_others(void)
 {
-	__cpuset_t cpumask, cpuset;
+	kcpuset_t *kcp;
 
-	CPUSET_ASSIGN(cpuset, cpus_running);
-	CPUSET_DEL(cpuset, cpu_index(curcpu()));
-	CPUSET_ASSIGN(cpumask, cpuset);
-	CPUSET_SUB(cpuset, cpus_halted);
-
-	if (CPUSET_EMPTY_P(cpuset))
+	// If we are the only CPU running, there's nothing to do.
+	if (kcpuset_match(cpus_running, curcpu()->ci_data.cpu_kcpuset))
 		return;
 
-	cpu_multicast_ipi(cpuset, IPI_HALT);
-	if (cpu_ipi_wait(&cpus_halted, cpumask))
-		cpu_ipi_error("halt", cpumask, cpus_halted);
+	// Get all running CPUs
+	kcpuset_clone(&kcp, cpus_running);
+	// Remove ourself
+	kcpuset_remove(kcp, curcpu()->ci_data.cpu_kcpuset);
+	// Remove any halted CPUs
+	kcpuset_remove(kcp, cpus_halted);
+	// If there are CPUs left, send the IPIs
+	if (!kcpuset_iszero(kcp)) {
+		cpu_multicast_ipi(kcp, IPI_HALT);
+		cpu_ipi_wait("halt", cpus_halted, kcp);
+	}
+	kcpuset_destroy(kcp);
 
 	/*
 	 * TBD
 	 * Depending on available firmware methods, other cpus will
-	 * either shut down themselfs, or spin and wait for us to
+	 * either shut down themselves, or spin and wait for us to
 	 * stop them.
 	 */
 }
@@ -744,23 +768,24 @@ void
 cpu_pause(struct reg *regsp)
 {
 	int s = splhigh();
-	int index = cpu_index(curcpu());
+	cpuid_t cii = cpu_index(curcpu());
 
-	for (;;) {
-		CPUSET_ADD(cpus_paused, index);
+	if (__predict_false(cold))
+		return;
+
+	do {
+		kcpuset_atomic_set(cpus_paused, cii);
 		do {
 			;
-		} while (CPUSET_HAS_P(cpus_paused, index));
-		CPUSET_ADD(cpus_resumed, index);
-
+		} while (kcpuset_isset(cpus_paused, cii));
+		kcpuset_atomic_set(cpus_resumed, cii);
 #if defined(DDB)
 		if (ddb_running_on_this_cpu_p())
 			cpu_Debugger();
 		if (ddb_running_on_any_cpu_p())
 			continue;
 #endif
-		break;
-	}
+	} while (false);
 
 	splx(s);
 }
@@ -771,30 +796,41 @@ cpu_pause(struct reg *regsp)
 void
 cpu_pause_others(void)
 {
-	__cpuset_t cpuset;
-
-	CPUSET_ASSIGN(cpuset, cpus_running);
-	CPUSET_DEL(cpuset, cpu_index(curcpu()));
+	struct cpu_info * const ci = curcpu();
+	kcpuset_t *kcp;
 
-	if (CPUSET_EMPTY_P(cpuset))
+	if (cold || kcpuset_match(cpus_running, ci->ci_data.cpu_kcpuset))
 		return;
 
-	cpu_multicast_ipi(cpuset, IPI_SUSPEND);
-	if (cpu_ipi_wait(&cpus_paused, cpuset))
-		cpu_ipi_error("pause", cpus_paused, cpuset);
+	kcpuset_clone(&kcp, cpus_running);
+	kcpuset_remove(kcp, ci->ci_data.cpu_kcpuset);
+	kcpuset_remove(kcp, cpus_paused);
+
+	cpu_broadcast_ipi(IPI_SUSPEND);
+	cpu_ipi_wait("pause", cpus_paused, kcp);
+
+	kcpuset_destroy(kcp);
 }
 
 /*
  * Resume a single cpu
  */
 void
-cpu_resume(int index)
+cpu_resume(cpuid_t cii)
 {
-	CPUSET_CLEAR(cpus_resumed);
-	CPUSET_DEL(cpus_paused, index);
+	kcpuset_t *kcp;
+
+	if (__predict_false(cold))
+		return;
+
+	kcpuset_create(&kcp, true);
+	kcpuset_set(kcp, cii);
+	kcpuset_atomicly_remove(cpus_resumed, cpus_resumed);
+	kcpuset_atomic_clear(cpus_paused, cii);
+
+	cpu_ipi_wait("resume", cpus_resumed, kcp);
 
-	if (cpu_ipi_wait(&cpus_resumed, CPUSET_SINGLE(index)))
-		cpu_ipi_error("resume", cpus_resumed, CPUSET_SINGLE(index));
+	kcpuset_destroy(kcp);
 }
 
 /*
@@ -803,22 +839,26 @@ cpu_resume(int index)
 void
 cpu_resume_others(void)
 {
-	__cpuset_t cpuset;
+	kcpuset_t *kcp;
+
+	if (__predict_false(cold))
+		return;
 
-	CPUSET_CLEAR(cpus_resumed);
-	CPUSET_ASSIGN(cpuset, cpus_paused);
-	CPUSET_CLEAR(cpus_paused);
+	kcpuset_atomicly_remove(cpus_resumed, cpus_resumed);
+	kcpuset_clone(&kcp, cpus_paused);
+	kcpuset_atomicly_remove(cpus_paused, cpus_paused);
 
 	/* CPUs awake on cpus_paused clear */
-	if (cpu_ipi_wait(&cpus_resumed, cpuset))
-		cpu_ipi_error("resume", cpus_resumed, cpuset);
+	cpu_ipi_wait("resume", cpus_resumed, kcp);
+
+	kcpuset_destroy(kcp);
 }
 
-int
-cpu_is_paused(int index)
+bool
+cpu_is_paused(cpuid_t cii)
 {
 
-	return CPUSET_HAS_P(cpus_paused, index);
+	return !cold && kcpuset_isset(cpus_paused, cii);
 }
 
 #ifdef DDB
@@ -831,11 +871,11 @@ cpu_debug_dump(void)
 
 	db_printf("CPU CPUID STATE CPUINFO            CPL INT MTX IPIS\n");
 	for (CPU_INFO_FOREACH(cii, ci)) {
-		hatched = (CPUSET_HAS_P(cpus_hatched, cpu_index(ci)) ? 'H' : '-');
-		running = (CPUSET_HAS_P(cpus_running, cpu_index(ci)) ? 'R' : '-');
-		paused  = (CPUSET_HAS_P(cpus_paused,  cpu_index(ci)) ? 'P' : '-');
-		resumed = (CPUSET_HAS_P(cpus_resumed, cpu_index(ci)) ? 'r' : '-');
-		halted  = (CPUSET_HAS_P(cpus_halted,  cpu_index(ci)) ? 'h' : '-');
+		hatched = (kcpuset_isset(cpus_hatched, cpu_index(ci)) ? 'H' : '-');
+		running = (kcpuset_isset(cpus_running, cpu_index(ci)) ? 'R' : '-');
+		paused  = (kcpuset_isset(cpus_paused,  cpu_index(ci)) ? 'P' : '-');
+		resumed = (kcpuset_isset(cpus_resumed, cpu_index(ci)) ? 'r' : '-');
+		halted  = (kcpuset_isset(cpus_halted,  cpu_index(ci)) ? 'h' : '-');
 		db_printf("%3d 0x%03lx %c%c%c%c%c %p "
 			"%3d %3d %3d "
 			"0x%02" PRIx64 "/0x%02" PRIx64 "\n",
@@ -893,12 +933,12 @@ cpu_hatch(struct cpu_info *ci)
 	/*
 	 * Announce we are hatched
 	 */
-	CPUSET_ADD(cpus_hatched, cpu_index(ci));
+	kcpuset_atomic_set(cpus_hatched, cpu_index(ci));
 
 	/*
 	 * Now wait to be set free!
 	 */
-	while (! CPUSET_HAS_P(cpus_running, cpu_index(ci))) {
+	while (! kcpuset_isset(cpus_running, cpu_index(ci))) {
 		/* spin, spin, spin */
 	}
 
@@ -924,6 +964,9 @@ cpu_hatch(struct cpu_info *ci)
 	KASSERTMSG(ci->ci_cpl == IPL_NONE, "cpl %d", ci->ci_cpl);
 	KASSERT(mips_cp0_status_read() & MIPS_SR_INT_IE);
 
+	kcpuset_atomic_set(pmap_kernel()->pm_onproc, cpu_index(ci));
+	kcpuset_atomic_set(pmap_kernel()->pm_active, cpu_index(ci));
+
 	/*
 	 * And do a tail call to idle_loop
 	 */
@@ -943,15 +986,15 @@ cpu_boot_secondary_processors(void)
 		/*
 		 * Skip this CPU if it didn't sucessfully hatch.
 		 */
-		if (! CPUSET_HAS_P(cpus_hatched, cpu_index(ci)))
+		if (!kcpuset_isset(cpus_hatched, cpu_index(ci)))
 			continue;
 
 		ci->ci_data.cpu_cc_skew = mips3_cp0_count_read();
 		atomic_or_ulong(&ci->ci_flags, CPUF_RUNNING);
-		CPUSET_ADD(cpus_running, cpu_index(ci));
+		kcpuset_set(cpus_running, cpu_index(ci));
 		// Spin until the cpu calls idle_loop
 		for (u_int i = 0; i < 100; i++) {
-			if (kcpuset_isset(kcpuset_running, cpu_index(ci)))
+			if (kcpuset_isset(cpus_running, cpu_index(ci)))
 				break;
 			delay(1000);
 		}

Index: src/sys/arch/mips/mips/ipifuncs.c
diff -u src/sys/arch/mips/mips/ipifuncs.c:1.9 src/sys/arch/mips/mips/ipifuncs.c:1.10
--- src/sys/arch/mips/mips/ipifuncs.c:1.9	Sat Jun  6 04:35:14 2015
+++ src/sys/arch/mips/mips/ipifuncs.c	Wed Jun 10 22:31:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipifuncs.c,v 1.9 2015/06/06 04:35:14 matt Exp $	*/
+/*	$NetBSD: ipifuncs.c,v 1.10 2015/06/10 22:31:00 matt Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
 #include "opt_ddb.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.9 2015/06/06 04:35:14 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.10 2015/06/10 22:31:00 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -44,7 +44,6 @@ __KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v
 #include <uvm/uvm_extern.h>
 
 #include <mips/cache.h>
-#include <mips/cpuset.h>
 #ifdef DDB
 #include <mips/db_machdep.h>
 #endif
@@ -102,7 +101,7 @@ ipi_halt(void)
 {
 	const u_int my_cpu = cpu_number();
 	printf("cpu%u: shutting down\n", my_cpu);
-	CPUSET_ADD(cpus_halted, my_cpu);
+	kcpuset_set(cpus_halted, my_cpu);
 	splhigh();
 	for (;;)
 		;

Index: src/sys/arch/mips/mips/locore_octeon.S
diff -u src/sys/arch/mips/mips/locore_octeon.S:1.6 src/sys/arch/mips/mips/locore_octeon.S:1.7
--- src/sys/arch/mips/mips/locore_octeon.S:1.6	Mon Jun  8 14:24:20 2015
+++ src/sys/arch/mips/mips/locore_octeon.S	Wed Jun 10 22:31:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore_octeon.S,v 1.6 2015/06/08 14:24:20 matt Exp $	*/
+/*	$NetBSD: locore_octeon.S,v 1.7 2015/06/10 22:31:00 matt Exp $	*/
 
 /*
  * Copyright (c) 2007 Internet Initiative Japan, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <mips/asm.h>
-RCSID("$NetBSD: locore_octeon.S,v 1.6 2015/06/08 14:24:20 matt Exp $")
+RCSID("$NetBSD: locore_octeon.S,v 1.7 2015/06/10 22:31:00 matt Exp $")
 
 #include "cpunode.h"			/* for NWDOG */
 #include "opt_cputype.h"
@@ -136,19 +136,22 @@ NESTED_NOPROFILE(octeon_cpu_spinup, 0, r
 	b	1b
 	 nop
 
-	// Indicate we've gotten this far
-2:	PTR_LA	a0, _C_LABEL(cpus_booted)
-	li	a1, 1
-	jal	_C_LABEL(atomic_or_64)
-	 sllv	a1, a1, s0
+	// Indicate this CPU was started by u-boot
+2:	PTR_LA	t0, _C_LABEL(cpus_booted) # get addr for kcpuset
+3:	sync
+	PTR_L	a0, (t0)		# get kcpuset
+	beqz	a0, 3b			# loop until not NULL
+	 nop
+	jal	_C_LABEL(kcpuset_atomic_set)
+	 move	a1, s1			# pass it our cpu number
 
 	// Wait until cpuid_infos[cpunum] is not NULL.
 	PTR_LA	a1, _C_LABEL(cpuid_infos)
 	dsll	v0, s0, PTR_SCALESHIFT	# cpunum -> array index
 	PTR_ADD	t0, a1, v0		# add to array start
-3:	sync
+4:	sync
 	PTR_L	a1, (t0)		# get cpu_info pointer
-	beqz	a1, 3b			# loop until non-NULL
+	beqz	a1, 4b			# loop until non-NULL
 	 nop
 
 	j	_C_LABEL(cpu_trampoline)

Index: src/sys/arch/mips/mips/pmap.c
diff -u src/sys/arch/mips/mips/pmap.c:1.214 src/sys/arch/mips/mips/pmap.c:1.215
--- src/sys/arch/mips/mips/pmap.c:1.214	Sun May 11 07:53:28 2014
+++ src/sys/arch/mips/mips/pmap.c	Wed Jun 10 22:31:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.214 2014/05/11 07:53:28 skrll Exp $	*/
+/*	$NetBSD: pmap.c,v 1.215 2015/06/10 22:31:00 matt Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.214 2014/05/11 07:53:28 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.215 2015/06/10 22:31:00 matt Exp $");
 
 /*
  *	Manages physical address maps.
@@ -116,6 +116,8 @@ __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.2
 #include "opt_multiprocessor.h"
 #include "opt_mips_cache.h"
 
+#define __MUTEX_PRIVATE
+
 #ifdef MULTIPROCESSOR
 #define PMAP_NO_PV_UNCACHED
 #endif
@@ -265,10 +267,6 @@ struct pmap_kernel kernel_pmap_store = {
 	.kernel_pmap = {
 		.pm_count = 1,
 		.pm_segtab = (void *)(MIPS_KSEG2_START + 0x1eadbeef),
-#ifdef MULTIPROCESSOR
-		.pm_active = 1,
-		.pm_onproc = 1,
-#endif
 	},
 };
 struct pmap * const kernel_pmap_ptr = &kernel_pmap_store.kernel_pmap;
@@ -375,12 +373,14 @@ pmap_page_syncicache(struct vm_page *pg)
 	struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
 #ifdef MULTIPROCESSOR
 	pv_entry_t pv = &md->pvh_first;
-	uint32_t onproc = 0;
+	kcpuset_t *onproc;
+	kcpuset_create(&onproc, true);
+	KASSERT(onproc != NULL);
 	(void)PG_MD_PVLIST_LOCK(md, false);
 	if (pv->pv_pmap != NULL) {
 		for (; pv != NULL; pv = pv->pv_next) {
-			onproc |= pv->pv_pmap->pm_onproc;
-			if (onproc == cpus_running)
+			kcpuset_merge(onproc, pv->pv_pmap->pm_onproc);
+			if (kcpuset_match(onproc, cpus_running))
 				break;
 		}
 	}
@@ -388,6 +388,7 @@ pmap_page_syncicache(struct vm_page *pg)
 	kpreempt_disable();
 	pmap_tlb_syncicache(trunc_page(md->pvh_first.pv_va), onproc);
 	kpreempt_enable();
+	kcpuset_destroy(onproc);
 #else
 	if (MIPS_HAS_R4K_MMU) {
 		if (PG_MD_CACHED_P(md)) {
@@ -485,6 +486,15 @@ pmap_bootstrap(void)
 
 	pmap_page_colormask = (uvmexp.ncolors -1) << PAGE_SHIFT;
 
+#ifdef MULTIPROCESSOR
+	pmap_t pm = pmap_kernel();
+	kcpuset_create(&pm->pm_onproc, true);
+	kcpuset_create(&pm->pm_active, true);
+	KASSERT(pm->pm_onproc != NULL);
+	KASSERT(pm->pm_active != NULL);
+	kcpuset_set(pm->pm_onproc, cpu_number());
+	kcpuset_set(pm->pm_active, cpu_number());
+#endif
 	pmap_tlb_info_init(&pmap_tlb0_info);		/* init the lock */
 
 	/*
@@ -812,6 +822,12 @@ pmap_create(void)
 	memset(pmap, 0, PMAP_SIZE);
 
 	pmap->pm_count = 1;
+#ifdef MULTIPROCESSOR
+	kcpuset_create(&pmap->pm_onproc, true);
+	kcpuset_create(&pmap->pm_active, true);
+	KASSERT(pmap->pm_onproc != NULL);
+	KASSERT(pmap->pm_active != NULL);
+#endif
 
 	pmap_segtab_init(pmap);
 
@@ -841,6 +857,13 @@ pmap_destroy(pmap_t pmap)
 	pmap_tlb_asid_release_all(pmap);
 	pmap_segtab_destroy(pmap);
 
+#ifdef MULTIPROCESSOR
+	kcpuset_destroy(pmap->pm_onproc);
+	kcpuset_destroy(pmap->pm_active);
+	pmap->pm_onproc = NULL;
+	pmap->pm_active = NULL;
+#endif
+
 	pool_put(&pmap_pmap_pool, pmap);
 	kpreempt_enable();
 }
@@ -1716,9 +1739,9 @@ pmap_remove_all(struct pmap *pmap)
 	 * tlb_invalidate_addrs().
 	 */
 #ifdef MULTIPROCESSOR
-	const uint32_t cpu_mask = 1 << cpu_index(curcpu());
-	KASSERT((pmap->pm_onproc & ~cpu_mask) == 0);
-	if (pmap->pm_onproc & cpu_mask)
+	// This should be the last CPU with this pmap onproc
+	KASSERT(!kcpuset_isotherset(pmap->pm_onproc, cpu_index(curcpu())));
+	if (kcpuset_isset(pmap->pm_onproc, cpu_index(curcpu())))
 		pmap_tlb_asid_deactivate(pmap);
 #endif
 	pmap_tlb_asid_release_all(pmap);
@@ -2408,6 +2431,7 @@ pmap_pvlist_lock_init(void)
 	if (sizeof(kmutex_t) > cache_line_size) {
 		cache_line_size = roundup2(sizeof(kmutex_t), cache_line_size);
 	}
+	memset((void *)lock_page, 0, PAGE_SIZE);
 	const size_t nlocks = PAGE_SIZE / cache_line_size;
 	KASSERT((nlocks & (nlocks - 1)) == 0);
 	/*
@@ -2415,7 +2439,7 @@ pmap_pvlist_lock_init(void)
 	 */
 	for (size_t i = 0; i < nlocks; lock_va += cache_line_size, i++) {
 		kmutex_t * const lock = (kmutex_t *)lock_va;
-		mutex_init(lock, MUTEX_DEFAULT, IPL_VM);
+		mutex_init(lock, MUTEX_DEFAULT, IPL_HIGH);
 		pli->pli_locks[i] = lock;
 	}
 	pli->pli_lock_mask = nlocks - 1;
@@ -2447,9 +2471,16 @@ pmap_pvlist_lock(struct vm_page_md *md, 
 		}
 	}
 
+	KASSERTMSG(lock >= pli->pli_locks[0],
+	    "lock %p < start %p", lock, pli->pli_locks);
+	KASSERTMSG(lock <= pli->pli_locks[pli->pli_lock_mask],
+	    "lock %p > end %p", lock, &pli->pli_locks[pli->pli_lock_mask]);
+
 	/*
 	 * Now finally lock the pvlists.
 	 */
+	KASSERTMSG(lock->mtx_ipl._spl == IPL_HIGH,
+	    "%p ipl %d", lock, lock->mtx_ipl._spl);
 	mutex_spin_enter(lock);
 
 	/*
@@ -2469,7 +2500,7 @@ pmap_pvlist_lock(struct vm_page_md *md, 
 static void
 pmap_pvlist_lock_init(void)
 {
-	mutex_init(&pmap_pvlist_mutex, MUTEX_DEFAULT, IPL_VM);
+	mutex_init(&pmap_pvlist_mutex, MUTEX_DEFAULT, IPL_HIGH);
 }
 #endif /* MULTIPROCESSOR */
 

Index: src/sys/arch/mips/mips/pmap_tlb.c
diff -u src/sys/arch/mips/mips/pmap_tlb.c:1.8 src/sys/arch/mips/mips/pmap_tlb.c:1.9
--- src/sys/arch/mips/mips/pmap_tlb.c:1.8	Tue Sep 27 01:02:34 2011
+++ src/sys/arch/mips/mips/pmap_tlb.c	Wed Jun 10 22:31:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap_tlb.c,v 1.8 2011/09/27 01:02:34 jym Exp $	*/
+/*	$NetBSD: pmap_tlb.c,v 1.9 2015/06/10 22:31:00 matt Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: pmap_tlb.c,v 1.8 2011/09/27 01:02:34 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap_tlb.c,v 1.9 2015/06/10 22:31:00 matt Exp $");
 
 /*
  * Manages address spaces in a TLB.
@@ -156,7 +156,6 @@ struct pmap_tlb_info pmap_tlb0_info = {
 	.ti_lock = &pmap_tlb0_mutex,
 	.ti_pais = LIST_HEAD_INITIALIZER(pmap_tlb_info.ti_pais),
 #ifdef MULTIPROCESSOR
-	.ti_cpu_mask = 1,
 	.ti_tlbinvop = TLBINV_NOBODY,
 #endif
 };
@@ -191,7 +190,7 @@ pmap_pai_reset(struct pmap_tlb_info *ti,
 	 */
 	KASSERT(pai->pai_asid);
 #ifdef MULTIPROCESSOR
-	KASSERT((pm->pm_onproc & ti->ti_cpu_mask) == 0);
+	KASSERT(!kcpuset_intersecting_p(pm->pm_onproc, ti->ti_kcpuset));
 #endif
 	LIST_REMOVE(pai, pai_link);
 #ifdef DIAGNOSTIC
@@ -212,7 +211,7 @@ pmap_pai_reset(struct pmap_tlb_info *ti,
 	 * The bits in pm_active belonging to this TLB can only be changed
 	 * while this TLB's lock is held.
 	 */
-	atomic_and_32(&pm->pm_active, ~ti->ti_cpu_mask);
+	kcpuset_atomicly_remove(pm->pm_active, ti->ti_kcpuset);
 #endif /* MULTIPROCESSOR */
 }
 
@@ -265,6 +264,9 @@ pmap_tlb_info_init(struct pmap_tlb_info 
 			}
 		}
 #ifdef MULTIPROCESSOR
+		kcpuset_create(&ti->ti_kcpuset, true);
+		KASSERT(ti->ti_kcpuset != NULL);
+		kcpuset_set(ti->ti_kcpuset, cpu_number());
 		const u_int icache_way_pages =
 			mips_cache_info.mci_picache_way_size >> PGSHIFT;
 		KASSERT(icache_way_pages <= 8*sizeof(pmap_tlb_synci_page_mask));
@@ -288,7 +290,8 @@ pmap_tlb_info_init(struct pmap_tlb_info 
 	ti->ti_asids_free = ti->ti_asid_max;
 	ti->ti_tlbinvop = TLBINV_NOBODY,
 	ti->ti_victim = NULL;
-	ti->ti_cpu_mask = 0;
+	kcpuset_create(&ti->ti_kcpuset, true);
+	KASSERT(ti->ti_kcpuset != NULL);
 	ti->ti_index = pmap_ntlbs++;
 	snprintf(ti->ti_name, sizeof(ti->ti_name), "tlb%u", ti->ti_index);
 
@@ -313,8 +316,7 @@ pmap_tlb_info_attach(struct pmap_tlb_inf
 	KASSERT(cold);
 
 	TLBINFO_LOCK(ti);
-	uint32_t cpu_mask = 1 << cpu_index(ci);
-	ti->ti_cpu_mask |= cpu_mask;
+	kcpuset_set(ti->ti_kcpuset, cpu_index(ci));
 	ci->ci_tlb_info = ti;
 	ci->ci_ksp_tlb_slot = ti->ti_wired++;
 	/*
@@ -326,8 +328,8 @@ pmap_tlb_info_attach(struct pmap_tlb_inf
 	 * Mark the kernel as active and "onproc" for this cpu.  We assume
 	 * we are the only CPU running so atomic ops are not needed.
 	 */
-	pmap_kernel()->pm_active |= cpu_mask;
-	pmap_kernel()->pm_onproc |= cpu_mask;
+	kcpuset_atomic_set(pmap_kernel()->pm_active, cpu_index(ci));
+	kcpuset_atomic_set(pmap_kernel()->pm_onproc, cpu_index(ci));
 	TLBINFO_UNLOCK(ti);
 }
 #endif /* MULTIPROCESSOR */
@@ -406,7 +408,7 @@ pmap_tlb_asid_reinitialize(struct pmap_t
 		next = LIST_NEXT(pai, pai_link);
 		KASSERT(pai->pai_asid != 0);
 #ifdef MULTIPROCESSOR
-		if (pm->pm_onproc & ti->ti_cpu_mask) {
+		if (kcpuset_intersecting_p(pm->pm_onproc, ti->ti_kcpuset)) {
 			if (!TLBINFO_ASID_INUSE_P(ti, pai->pai_asid)) {
 				TLBINFO_ASID_MARK_USED(ti, pai->pai_asid);
 				ti->ti_asids_free--;
@@ -451,7 +453,7 @@ pmap_tlb_shootdown_process(void)
 		 */
 		struct pmap_asid_info * const pai = PMAP_PAI(ti->ti_victim, ti);
 		KASSERT(ti->ti_victim != pmap_kernel());
-		if (ti->ti_victim->pm_onproc & ti->ti_cpu_mask) {
+		if (kcpuset_intersecting_p(ti->ti_victim->pm_onproc, ti->ti_kcpuset)) {
 			/*
 			 * The victim is an active pmap so we will just
 			 * invalidate its TLB entries.
@@ -467,7 +469,7 @@ pmap_tlb_shootdown_process(void)
 			 * next called for this pmap, it will allocate a new
 			 * ASID.
 			 */
-			KASSERT((curpmap->pm_onproc & ti->ti_cpu_mask) == 0);
+			KASSERT(kcpuset_intersecting_p(curpmap->pm_onproc, ti->ti_kcpuset) == 0);
 			pmap_pai_reset(ti, pai, PAI_PMAP(pai, ti));
 		}
 		break;
@@ -534,29 +536,37 @@ pmap_tlb_shootdown_bystanders(pmap_t pm)
 	/*
 	 * We don't need to deal our own TLB.
 	 */
-	uint32_t pm_active = pm->pm_active & ~curcpu()->ci_tlb_info->ti_cpu_mask;
 	const bool kernel_p = (pm == pmap_kernel());
 	bool ipi_sent = false;
+	kcpuset_t *pm_active;
+
+	if (pmap_ntlbs == 1)
+		return false;
+
+	KASSERT(pm->pm_active != NULL);
+	kcpuset_clone(&pm_active, pm->pm_active);
+	KASSERT(pm_active != NULL);
+	kcpuset_remove(pm_active, curcpu()->ci_tlb_info->ti_kcpuset);
 
 	/*
 	 * If pm_active gets more bits set, then it's after all our changes
 	 * have been made so they will already be cognizant of them.
 	 */
 
-	for (size_t i = 0; pm_active != 0; i++) {
+	for (size_t i = 0; !kcpuset_iszero(pm_active); i++) {
 		KASSERT(i < pmap_ntlbs);
 		struct pmap_tlb_info * const ti = pmap_tlbs[i];
 		KASSERT(tlbinfo_index(ti) == i);
 		/*
 		 * Skip this TLB if there are no active mappings for it.
 		 */
-		if ((pm_active & ti->ti_cpu_mask) == 0)
+		if (!kcpuset_intersecting_p(pm_active, ti->ti_kcpuset) == 0)
 			continue;
 		struct pmap_asid_info * const pai = PMAP_PAI(pm, ti);
-		pm_active &= ~ti->ti_cpu_mask;
+		kcpuset_remove(pm_active, ti->ti_kcpuset);
 		TLBINFO_LOCK(ti);
-		const uint32_t onproc = (pm->pm_onproc & ti->ti_cpu_mask);
-		if (onproc != 0) {
+		cpuid_t j = kcpuset_ffs_intersecting(pm->pm_onproc, ti->ti_kcpuset);
+		if (j != 0) {
 			if (kernel_p) {
 				ti->ti_tlbinvop =
 				    TLBINV_KERNEL_MAP(ti->ti_tlbinvop);
@@ -588,13 +598,11 @@ pmap_tlb_shootdown_bystanders(pmap_t pm)
 			 * change now that we have released the lock but we
 			 * can tolerate spurious shootdowns.
 			 */
-			KASSERT(onproc != 0);
-			u_int j = ffs(onproc) - 1;
-			cpu_send_ipi(cpu_lookup(j), IPI_SHOOTDOWN);
+			cpu_send_ipi(cpu_lookup(j-1), IPI_SHOOTDOWN);
 			ipi_sent = true;
 			continue;
 		}
-		if (pm->pm_active & ti->ti_cpu_mask) {
+		if (kcpuset_intersecting_p(pm->pm_active, ti->ti_kcpuset)) {
 			/*
 			 * If this pmap has an ASID assigned but it's not
 			 * currently running, nuke its ASID.  Next time the
@@ -607,6 +615,7 @@ pmap_tlb_shootdown_bystanders(pmap_t pm)
 		}
 		TLBINFO_UNLOCK(ti);
 	}
+	kcpuset_destroy(pm_active);
 
 	return ipi_sent;
 }
@@ -668,8 +677,8 @@ pmap_tlb_asid_alloc(struct pmap_tlb_info
 	KASSERT(pai->pai_asid == 0);
 	KASSERT(pai->pai_link.le_prev == NULL);
 #ifdef MULTIPROCESSOR
-	KASSERT((pm->pm_onproc & ti->ti_cpu_mask) == 0);
-	KASSERT((pm->pm_active & ti->ti_cpu_mask) == 0);
+	KASSERT(!kcpuset_intersecting_p(pm->pm_onproc, ti->ti_kcpuset));
+	KASSERT(!kcpuset_intersecting_p(pm->pm_active, ti->ti_kcpuset));
 #endif
 	KASSERT(ti->ti_asids_free > 0);
 	KASSERT(ti->ti_asid_hint <= ti->ti_asid_max);
@@ -724,7 +733,7 @@ pmap_tlb_asid_alloc(struct pmap_tlb_info
 	 * The bits in pm_active belonging to this TLB can only be changed
 	 * while this TLBs lock is held.
 	 */
-	atomic_or_32(&pm->pm_active, ti->ti_cpu_mask);
+	kcpuset_atomicly_merge(pm->pm_active, ti->ti_kcpuset);
 #endif
 }
 
@@ -769,7 +778,7 @@ pmap_tlb_asid_acquire(pmap_t pm, struct 
 		 * The bits in pm_onproc belonging to this TLB can only
 		 * be changed while this TLBs lock is held.
 		 */
-		atomic_or_32(&pm->pm_onproc, 1 << cpu_index(ci));
+		kcpuset_atomic_set(pm->pm_onproc, cpu_index(ci));
 		/*
 		 * If this CPU has had exec pages changes that haven't been
 		 * icache synched, make sure to do that before returning to
@@ -782,6 +791,7 @@ pmap_tlb_asid_acquire(pmap_t pm, struct 
 		atomic_or_ulong(&ci->ci_flags, CPUF_USERPMAP);
 #endif /* MULTIPROCESSOR */
 		ci->ci_pmap_asid_cur = pai->pai_asid;
+		KASSERT(!cold);
 		tlb_set_asid(pai->pai_asid);
 		pmap_tlb_asid_check();
 	} else {
@@ -810,19 +820,18 @@ pmap_tlb_asid_deactivate(pmap_t pm)
 	 * deactivated the pmap and thusly onproc will be 0 so there's nothing
 	 * to do.
 	 */
-	if (pm != pmap_kernel() && pm->pm_onproc != 0) {
+	if (pm != pmap_kernel() && !kcpuset_iszero(pm->pm_onproc)) {
 		struct cpu_info * const ci = curcpu();
-		const uint32_t cpu_mask = 1 << cpu_index(ci);
 		KASSERT(!cpu_intr_p());
-		KASSERTMSG(pm->pm_onproc & cpu_mask,
-		    "%s: pmap %p onproc %#x doesn't include cpu %d (%p)",
+		KASSERTMSG(kcpuset_isset(pm->pm_onproc, cpu_index(ci)),
+		    "%s: pmap %p onproc %p doesn't include cpu %d (%p)",
 		    __func__, pm, pm->pm_onproc, cpu_index(ci), ci);
 		/*
 		 * The bits in pm_onproc that belong to this TLB can
 		 * be changed while this TLBs lock is not held as long
 		 * as we use atomic ops.
 		 */
-		atomic_and_32(&pm->pm_onproc, ~cpu_mask);
+		kcpuset_atomic_clear(pm->pm_onproc, cpu_index(ci));
 		atomic_and_ulong(&ci->ci_flags, ~CPUF_USERPMAP);
 	}
 #elif defined(DEBUG)
@@ -838,11 +847,11 @@ pmap_tlb_asid_release_all(struct pmap *p
 	KASSERT(pm != pmap_kernel());
 	KASSERT(kpreempt_disabled());
 #ifdef MULTIPROCESSOR
-	KASSERT(pm->pm_onproc == 0);
-	for (u_int i = 0; pm->pm_active != 0; i++) {
+	KASSERT(kcpuset_iszero(pm->pm_onproc));
+	for (u_int i = 0; !kcpuset_iszero(pm->pm_active); i++) {
 		KASSERT(i < pmap_ntlbs);
 		struct pmap_tlb_info * const ti = pmap_tlbs[i];
-		if (pm->pm_active & ti->ti_cpu_mask) {
+		if (kcpuset_intersecting_p(pm->pm_active, ti->ti_kcpuset)) {
 			struct pmap_asid_info * const pai = PMAP_PAI(pm, ti);
 			TLBINFO_LOCK(ti);
 			KASSERT(ti->ti_victim != pm);
@@ -907,7 +916,7 @@ pmap_tlb_syncicache_ast(struct cpu_info 
 }
 
 void
-pmap_tlb_syncicache(vaddr_t va, uint32_t page_onproc)
+pmap_tlb_syncicache(vaddr_t va, const kcpuset_t *page_onproc)
 {
 	KASSERT(kpreempt_disabled());
 	/*
@@ -929,10 +938,12 @@ pmap_tlb_syncicache(vaddr_t va, uint32_t
 	 * then become equal but that's a one in 4 billion cache and will
 	 * just cause an extra sync of the icache.
 	 */
-	const uint32_t cpu_mask = 1L << cpu_index(curcpu());
+	struct cpu_info * const ci = curcpu();
 	const uint32_t page_mask =
 	    1L << ((va >> PGSHIFT) & pmap_tlb_synci_page_mask);
-	uint32_t onproc = 0;
+	kcpuset_t *onproc;
+	kcpuset_create(&onproc, true);
+	KASSERT(onproc != NULL);
 	for (size_t i = 0; i < pmap_ntlbs; i++) {
 		struct pmap_tlb_info * const ti = pmap_tlbs[0];
 		TLBINFO_LOCK(ti);
@@ -949,7 +960,7 @@ pmap_tlb_syncicache(vaddr_t va, uint32_t
 
 			if (orig_page_bitmap == old_page_bitmap) {
 				if (old_page_bitmap == 0) {
-					onproc |= ti->ti_cpu_mask;
+					kcpuset_merge(onproc, ti->ti_kcpuset);
 				} else {
 					ti->ti_evcnt_synci_deferred.ev_count++;
 				}
@@ -960,24 +971,24 @@ pmap_tlb_syncicache(vaddr_t va, uint32_t
 #if 0
 		printf("%s: %s: %x to %x on cpus %#x\n", __func__,
 		    ti->ti_name, page_mask, ti->ti_synci_page_bitmap,
-		     onproc & page_onproc & ti->ti_cpu_mask);
+		     onproc & page_onproc & ti->ti_kcpuset);
 #endif
 		TLBINFO_UNLOCK(ti);
 	}
-	onproc &= page_onproc;
-	if (__predict_false(onproc != 0)) {
+	kcpuset_intersect(onproc, page_onproc);
+	if (__predict_false(!kcpuset_iszero(onproc))) {
 		/*
 		 * If the cpu need to sync this page, tell the current lwp
 		 * to sync the icache before it returns to userspace.
 		 */
-		if (onproc & cpu_mask) {
-			if (curcpu()->ci_flags & CPUF_USERPMAP) {
+		if (kcpuset_isset(onproc, cpu_index(ci))) {
+			if (ci->ci_flags & CPUF_USERPMAP) {
 				curlwp->l_md.md_astpending = 1;	/* force call to ast() */
-				curcpu()->ci_evcnt_synci_onproc_rqst.ev_count++;
+				ci->ci_evcnt_synci_onproc_rqst.ev_count++;
 			} else {
-				curcpu()->ci_evcnt_synci_deferred_rqst.ev_count++;
+				ci->ci_evcnt_synci_deferred_rqst.ev_count++;
 			}
-			onproc ^= cpu_mask;
+			kcpuset_clear(onproc, cpu_index(ci));
 		}
 
 		/*
@@ -986,12 +997,15 @@ pmap_tlb_syncicache(vaddr_t va, uint32_t
 		 * We might cause some spurious icache syncs but that's not
 		 * going to break anything.
 		 */
-		for (u_int n = ffs(onproc);
-		     onproc != 0;
-		     onproc >>= n, onproc <<= n, n = ffs(onproc)) {
-			cpu_send_ipi(cpu_lookup(n-1), IPI_SYNCICACHE);
+		for (cpuid_t n = kcpuset_ffs(onproc);
+		     n-- != 0;
+		     n = kcpuset_ffs(onproc)) {
+			kcpuset_clear(onproc, n);
+			cpu_send_ipi(cpu_lookup(n), IPI_SYNCICACHE);
 		}
 	}
+
+	kcpuset_destroy(onproc);
 }
 
 void

Index: src/sys/arch/mips/rmi/rmixl_cpu.c
diff -u src/sys/arch/mips/rmi/rmixl_cpu.c:1.7 src/sys/arch/mips/rmi/rmixl_cpu.c:1.8
--- src/sys/arch/mips/rmi/rmixl_cpu.c:1.7	Mon Jun  1 22:55:13 2015
+++ src/sys/arch/mips/rmi/rmixl_cpu.c	Wed Jun 10 22:31:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: rmixl_cpu.c,v 1.7 2015/06/01 22:55:13 matt Exp $	*/
+/*	$NetBSD: rmixl_cpu.c,v 1.8 2015/06/10 22:31:00 matt Exp $	*/
 
 /*
  * Copyright 2002 Wasabi Systems, Inc.
@@ -38,7 +38,7 @@
 #include "locators.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rmixl_cpu.c,v 1.7 2015/06/01 22:55:13 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rmixl_cpu.c,v 1.8 2015/06/10 22:31:00 matt Exp $");
 
 #include "opt_multiprocessor.h"
 #include "opt_ddb.h"
@@ -218,13 +218,12 @@ cpu_rmixl_attach(device_t parent, device
 			return;
 		}
 
-		const u_long cpu_mask = 1L << cpu_index(ci);
 		for (size_t i=0; i < 10000; i++) {
-			if ((cpus_hatched & cpu_mask) != 0)
+			if (!kcpuset_isset(cpus_hatched, cpu_index(ci)))
 				 break;
 			DELAY(100);
 		}
-		if ((cpus_hatched & cpu_mask) == 0) {
+		if (!kcpuset_isset(cpus_hatched, cpu_index(ci))) {
 			aprint_error(": failed to hatch\n");
 			return;
 		}

Index: src/sys/arch/mips/rmi/rmixl_intr.c
diff -u src/sys/arch/mips/rmi/rmixl_intr.c:1.8 src/sys/arch/mips/rmi/rmixl_intr.c:1.9
--- src/sys/arch/mips/rmi/rmixl_intr.c:1.8	Tue Sep 27 01:02:34 2011
+++ src/sys/arch/mips/rmi/rmixl_intr.c	Wed Jun 10 22:31:00 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: rmixl_intr.c,v 1.8 2011/09/27 01:02:34 jym Exp $	*/
+/*	$NetBSD: rmixl_intr.c,v 1.9 2015/06/10 22:31:00 matt Exp $	*/
 
 /*-
  * Copyright (c) 2007 Ruslan Ermilov and Vsevolod Lobko.
@@ -64,7 +64,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rmixl_intr.c,v 1.8 2011/09/27 01:02:34 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rmixl_intr.c,v 1.9 2015/06/10 22:31:00 matt Exp $");
 
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
@@ -81,7 +81,6 @@ __KERNEL_RCSID(0, "$NetBSD: rmixl_intr.c
 #include <sys/mutex.h>
 #include <sys/systm.h>
 
-#include <mips/cpuset.h>
 #include <mips/locore.h>
 
 #include <mips/rmi/rmixlreg.h>
@@ -958,7 +957,7 @@ rmixl_send_ipi(struct cpu_info *ci, int 
 	uint64_t req = 1 << tag;
 	uint32_t r;
 
-	if (! CPUSET_HAS_P(cpus_running, cpu_index(ci)))
+	if (!kcpuset_isset(cpus_running, cpu_index(ci)))
 		return -1;
 
 	KASSERT((tag >= 0) && (tag < NIPIS));

Reply via email to