summaryrefslogtreecommitdiffstats
path: root/sys/sys
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2011-05-05 14:39:14 +0000
committerattilio <attilio@FreeBSD.org>2011-05-05 14:39:14 +0000
commitfe4de567b50f7ca317b16f69b7b3a7de693025af (patch)
treee5d54bcefbf1fe0c4c6804bdc5c4852b1b64518a /sys/sys
parentd3d3db9bac709a7fa4319bf5e8c8fb4e05918772 (diff)
downloadFreeBSD-src-fe4de567b50f7ca317b16f69b7b3a7de693025af.zip
FreeBSD-src-fe4de567b50f7ca317b16f69b7b3a7de693025af.tar.gz
Commit the support for removing cpumask_t and replacing it directly with
cpuset_t objects. That is going to offer the underlying support for a simple bump of MAXCPU and then support for number of cpus > 32 (as it is today). Right now, cpumask_t is an int, 32 bits on all our supported architecture. cpumask_t on the other side is implemented as an array of longs, and easilly extendible by definition. The architectures touched by this commit are the following: - amd64 - i386 - pc98 - arm - ia64 - XEN while the others are still missing. Userland is believed to be fully converted with the changes contained here. Some technical notes: - This commit may be considered an ABI nop for all the architectures different from amd64 and ia64 (and sparc64 in the future) - per-cpu members, which are now converted to cpuset_t, needs to be accessed avoiding migration, because the size of cpuset_t should be considered unknown - size of cpuset_t objects is different from kernel and userland (this is primirally done in order to leave some more space in userland to cope with KBI extensions). If you need to access kernel cpuset_t from the userland please refer to example in this patch on how to do that correctly (kgdb may be a good source, for example). - Support for other architectures is going to be added soon - Only MAXCPU for amd64 is bumped now The patch has been tested by sbruno and Nicholas Esborn on opteron 4 x 12 pack CPUs. More testing on big SMP is expected to came soon. pluknet tested the patch with his 8-ways on both amd64 and i386. Tested by: pluknet, sbruno, gianni, Nicholas Esborn Reviewed by: jeff, jhb, sbruno
Diffstat (limited to 'sys/sys')
-rw-r--r--sys/sys/_cpuset.h52
-rw-r--r--sys/sys/_rmlock.h2
-rw-r--r--sys/sys/cpuset.h62
-rw-r--r--sys/sys/pcpu.h5
-rw-r--r--sys/sys/pmckern.h4
-rw-r--r--sys/sys/smp.h26
-rw-r--r--sys/sys/types.h1
7 files changed, 119 insertions, 33 deletions
diff --git a/sys/sys/_cpuset.h b/sys/sys/_cpuset.h
new file mode 100644
index 0000000..62a0e9d
--- /dev/null
+++ b/sys/sys/_cpuset.h
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2008, Jeffrey Roberson <jeff@freebsd.org>
+ * All rights reserved.
+ *
+ * Copyright (c) 2008 Nokia Corporation
+ * 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 unmodified, 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 ``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 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$
+ */
+
+#ifndef _SYS__CPUSET_H_
+#define _SYS__CPUSET_H_
+
+#ifdef _KERNEL
+#define CPU_SETSIZE MAXCPU
+#endif
+
+#define CPU_MAXSIZE (4 * MAXCPU)
+
+#ifndef CPU_SETSIZE
+#define CPU_SETSIZE CPU_MAXSIZE
+#endif
+
+#define _NCPUBITS (sizeof(long) * NBBY) /* bits per mask */
+#define _NCPUWORDS howmany(CPU_SETSIZE, _NCPUBITS)
+
+typedef struct _cpuset {
+ long __bits[howmany(CPU_SETSIZE, _NCPUBITS)];
+} cpuset_t;
+
+#endif /* !_SYS__CPUSET_H_ */
diff --git a/sys/sys/_rmlock.h b/sys/sys/_rmlock.h
index 75a159c..15d6c49 100644
--- a/sys/sys/_rmlock.h
+++ b/sys/sys/_rmlock.h
@@ -45,7 +45,7 @@ LIST_HEAD(rmpriolist,rm_priotracker);
struct rmlock {
struct lock_object lock_object;
- volatile cpumask_t rm_writecpus;
+ volatile cpuset_t rm_writecpus;
LIST_HEAD(,rm_priotracker) rm_activeReaders;
union {
struct mtx _rm_lock_mtx;
diff --git a/sys/sys/cpuset.h b/sys/sys/cpuset.h
index 3263991..e06df54 100644
--- a/sys/sys/cpuset.h
+++ b/sys/sys/cpuset.h
@@ -32,22 +32,9 @@
#ifndef _SYS_CPUSET_H_
#define _SYS_CPUSET_H_
-#ifdef _KERNEL
-#define CPU_SETSIZE MAXCPU
-#endif
+#include <sys/_cpuset.h>
-#define CPU_MAXSIZE (4 * MAXCPU)
-
-#ifndef CPU_SETSIZE
-#define CPU_SETSIZE CPU_MAXSIZE
-#endif
-
-#define _NCPUBITS (sizeof(long) * NBBY) /* bits per mask */
-#define _NCPUWORDS howmany(CPU_SETSIZE, _NCPUBITS)
-
-typedef struct _cpuset {
- long __bits[howmany(CPU_SETSIZE, _NCPUBITS)];
-} cpuset_t;
+#define CPUSETBUFSIZ ((2 + sizeof(long) * 2) * _NCPUWORDS)
#define __cpuset_mask(n) ((long)1 << ((n) % _NCPUBITS))
#define CPU_CLR(n, p) ((p)->__bits[(n)/_NCPUBITS] &= ~__cpuset_mask(n))
@@ -66,6 +53,11 @@ typedef struct _cpuset {
(p)->__bits[__i] = -1; \
} while (0)
+#define CPU_SETOF(n, p) do { \
+ CPU_ZERO(p); \
+ ((p)->__bits[(n)/_NCPUBITS] = __cpuset_mask(n)); \
+} while (0)
+
/* Is p empty. */
#define CPU_EMPTY(p) __extension__ ({ \
__size_t __i; \
@@ -75,6 +67,15 @@ typedef struct _cpuset {
__i == _NCPUWORDS; \
})
+/* Is p full set. */
+#define CPU_ISFULLSET(p) __extension__ ({ \
+ __size_t __i; \
+ for (__i = 0; __i < _NCPUWORDS; __i++) \
+ if ((p)->__bits[__i] != (long)-1) \
+ break; \
+ __i == _NCPUWORDS; \
+})
+
/* Is c a subset of p. */
#define CPU_SUBSET(p, c) __extension__ ({ \
__size_t __i; \
@@ -124,6 +125,35 @@ typedef struct _cpuset {
(d)->__bits[__i] &= ~(s)->__bits[__i]; \
} while (0)
+#ifdef _KERNEL
+#define CPU_CLR_ATOMIC(n, p) \
+ atomic_clear_long(&(p)->__bits[(n)/_NCPUBITS], __cpuset_mask(n))
+
+#define CPU_SET_ATOMIC(n, p) \
+ atomic_set_long(&(p)->__bits[(n)/_NCPUBITS], __cpuset_mask(n))
+
+#define CPU_OR_ATOMIC(d, s) do { \
+ __size_t __i; \
+ for (__i = 0; __i < _NCPUWORDS; __i++) \
+ atomic_set_long(&(d)->__bits[__i], \
+ (s)->__bits[__i]); \
+} while (0)
+
+#define CPU_NAND_ATOMIC(d, s) do { \
+ __size_t __i; \
+ for (__i = 0; __i < _NCPUWORDS; __i++) \
+ atomic_clear_long(&(d)->__bits[__i], \
+ (s)->__bits[__i]); \
+} while (0)
+
+#define CPU_COPY_STORE_REL(f, t) do { \
+ __size_t __i; \
+ for (__i = 0; __i < _NCPUWORDS; __i++) \
+ atomic_store_rel_long(&(t)->__bits[__i], \
+ (f)->__bits[__i]); \
+} while (0)
+#endif /* !_KERNEL */
+
/*
* Valid cpulevel_t values.
*/
@@ -184,6 +214,8 @@ void cpuset_rel(struct cpuset *);
int cpuset_setthread(lwpid_t id, cpuset_t *);
int cpuset_create_root(struct prison *, struct cpuset **);
int cpuset_setproc_update_set(struct proc *, struct cpuset *);
+int cpusetobj_ffs(const cpuset_t *);
+char *cpusetobj_strprint(char *, const cpuset_t *);
#else
__BEGIN_DECLS
diff --git a/sys/sys/pcpu.h b/sys/sys/pcpu.h
index ad1cf33..1b7f24f 100644
--- a/sys/sys/pcpu.h
+++ b/sys/sys/pcpu.h
@@ -37,6 +37,7 @@
#error "no assembler-serviceable parts inside"
#endif
+#include <sys/_cpuset.h>
#include <sys/queue.h>
#include <sys/vmmeter.h>
#include <sys/resource.h>
@@ -162,8 +163,8 @@ struct pcpu {
uint64_t pc_switchtime; /* cpu_ticks() at last csw */
int pc_switchticks; /* `ticks' at last csw */
u_int pc_cpuid; /* This cpu number */
- cpumask_t pc_cpumask; /* This cpu mask */
- cpumask_t pc_other_cpus; /* Mask of all other cpus */
+ cpuset_t pc_cpumask; /* This cpu mask */
+ cpuset_t pc_other_cpus; /* Mask of all other cpus */
SLIST_ENTRY(pcpu) pc_allcpu;
struct lock_list_entry *pc_spinlocks;
#ifdef KTR
diff --git a/sys/sys/pmckern.h b/sys/sys/pmckern.h
index 3e8c1ef..796c4ca 100644
--- a/sys/sys/pmckern.h
+++ b/sys/sys/pmckern.h
@@ -76,7 +76,7 @@ extern int (*pmc_intr)(int _cpu, struct trapframe *_frame);
extern struct sx pmc_sx;
/* Per-cpu flags indicating availability of sampling data */
-extern volatile cpumask_t pmc_cpumask;
+extern volatile cpuset_t pmc_cpumask;
/* Count of system-wide sampling PMCs in existence */
extern volatile int pmc_ss_count;
@@ -122,7 +122,7 @@ do { \
#define PMC_SYSTEM_SAMPLING_ACTIVE() (pmc_ss_count > 0)
/* Check if a CPU has recorded samples. */
-#define PMC_CPU_HAS_SAMPLES(C) (__predict_false(pmc_cpumask & (1 << (C))))
+#define PMC_CPU_HAS_SAMPLES(C) (__predict_false(CPU_ISSET(C, &pmc_cpumask)))
/*
* Helper functions.
diff --git a/sys/sys/smp.h b/sys/sys/smp.h
index 544cb95..410adfa 100644
--- a/sys/sys/smp.h
+++ b/sys/sys/smp.h
@@ -16,6 +16,8 @@
#ifndef LOCORE
+#include <sys/cpuset.h>
+
/*
* Topology of a NUMA or HTT system.
*
@@ -32,7 +34,7 @@
struct cpu_group {
struct cpu_group *cg_parent; /* Our parent group. */
struct cpu_group *cg_child; /* Optional children groups. */
- cpumask_t cg_mask; /* Mask of cpus in this group. */
+ cpuset_t cg_mask; /* Mask of cpus in this group. */
int8_t cg_count; /* Count of cpus in this group. */
int8_t cg_children; /* Number of children groups. */
int8_t cg_level; /* Shared cache level. */
@@ -71,10 +73,10 @@ struct cpu_group *smp_topo_find(struct cpu_group *top, int cpu);
extern void (*cpustop_restartfunc)(void);
extern int smp_active;
extern int smp_cpus;
-extern volatile cpumask_t started_cpus;
-extern volatile cpumask_t stopped_cpus;
-extern cpumask_t hlt_cpus_mask;
-extern cpumask_t logical_cpus_mask;
+extern volatile cpuset_t started_cpus;
+extern volatile cpuset_t stopped_cpus;
+extern cpuset_t hlt_cpus_mask;
+extern cpuset_t logical_cpus_mask;
#endif /* SMP */
extern u_int mp_maxid;
@@ -82,14 +84,14 @@ extern int mp_maxcpus;
extern int mp_ncpus;
extern volatile int smp_started;
-extern cpumask_t all_cpus;
+extern cpuset_t all_cpus;
/*
* Macro allowing us to determine whether a CPU is absent at any given
* time, thus permitting us to configure sparse maps of cpuid-dependent
* (per-CPU) structures.
*/
-#define CPU_ABSENT(x_cpu) ((all_cpus & (1 << (x_cpu))) == 0)
+#define CPU_ABSENT(x_cpu) (!CPU_ISSET(x_cpu, &all_cpus))
/*
* Macros to iterate over non-absent CPUs. CPU_FOREACH() takes an
@@ -158,11 +160,11 @@ void cpu_mp_setmaxid(void);
void cpu_mp_start(void);
void forward_signal(struct thread *);
-int restart_cpus(cpumask_t);
-int stop_cpus(cpumask_t);
-int stop_cpus_hard(cpumask_t);
+int restart_cpus(cpuset_t);
+int stop_cpus(cpuset_t);
+int stop_cpus_hard(cpuset_t);
#if defined(__amd64__)
-int suspend_cpus(cpumask_t);
+int suspend_cpus(cpuset_t);
#endif
void smp_rendezvous_action(void);
extern struct mtx smp_ipi_mtx;
@@ -173,7 +175,7 @@ void smp_rendezvous(void (*)(void *),
void (*)(void *),
void (*)(void *),
void *arg);
-void smp_rendezvous_cpus(cpumask_t,
+void smp_rendezvous_cpus(cpuset_t,
void (*)(void *),
void (*)(void *),
void (*)(void *),
diff --git a/sys/sys/types.h b/sys/sys/types.h
index c747d16..5cc005d 100644
--- a/sys/sys/types.h
+++ b/sys/sys/types.h
@@ -143,7 +143,6 @@ typedef __clockid_t clockid_t;
#define _CLOCKID_T_DECLARED
#endif
-typedef __cpumask_t cpumask_t;
typedef __critical_t critical_t; /* Critical section value */
typedef __int64_t daddr_t; /* disk address */
OpenPOWER on IntegriCloud