Add kcpuset(9) - a reworked dynamic CPU set implementation for kernel.
Suitable for use during the early boot. MD and other implementations should be replaced with this interface. Discussed on: tech-kern@
This commit is contained in:
parent
f398b121d3
commit
52b220e91d
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cpuset.c,v 1.16 2010/09/21 02:03:29 rmind Exp $ */
|
||||
/* $NetBSD: cpuset.c,v 1.17 2011/08/07 13:33:02 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -32,7 +32,7 @@
|
|||
#ifndef _STANDALONE
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: cpuset.c,v 1.16 2010/09/21 02:03:29 rmind Exp $");
|
||||
__RCSID("$NetBSD: cpuset.c,v 1.17 2011/08/07 13:33:02 rmind Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -64,24 +64,11 @@ struct _cpuset {
|
|||
uint32_t bits[0];
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct _kcpuset {
|
||||
unsigned int nused;
|
||||
struct _kcpuset *next;
|
||||
uint32_t bits[0];
|
||||
};
|
||||
#define KCPUSET_SIZE(n) (sizeof( \
|
||||
struct { \
|
||||
unsigned int nused; \
|
||||
struct _kcpuset *next; \
|
||||
uint32_t bits[0]; \
|
||||
}) + sizeof(uint32_t) * (n))
|
||||
#endif
|
||||
#ifndef _KERNEL
|
||||
|
||||
static size_t cpuset_size = 0;
|
||||
static size_t cpuset_nentries = 0;
|
||||
|
||||
#ifndef _KERNEL
|
||||
size_t
|
||||
/*ARGSUSED*/
|
||||
_cpuset_size(const cpuset_t *c)
|
||||
|
@ -161,150 +148,5 @@ _cpuset_destroy(cpuset_t *c)
|
|||
free(c);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
kcpuset_t *
|
||||
kcpuset_create(void)
|
||||
{
|
||||
kcpuset_t *c;
|
||||
|
||||
if (cpuset_size == 0) {
|
||||
cpuset_nentries = CPUSET_NENTRIES(MAXCPUS);
|
||||
cpuset_size = KCPUSET_SIZE(cpuset_nentries);
|
||||
}
|
||||
c = kmem_zalloc(cpuset_size, KM_SLEEP);
|
||||
c->next = NULL;
|
||||
c->nused = 1;
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
kcpuset_destroy(kcpuset_t *c)
|
||||
{
|
||||
kcpuset_t *nc;
|
||||
|
||||
while (c) {
|
||||
KASSERT(c->nused == 0);
|
||||
nc = c->next;
|
||||
kmem_free(c, cpuset_size);
|
||||
c = nc;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
kcpuset_copy(kcpuset_t *d, const kcpuset_t *s)
|
||||
{
|
||||
|
||||
KASSERT(d->nused == 1);
|
||||
memcpy(d->bits, s->bits, cpuset_nentries * sizeof(s->bits[0]));
|
||||
}
|
||||
|
||||
void
|
||||
kcpuset_use(kcpuset_t *c)
|
||||
{
|
||||
|
||||
atomic_inc_uint(&c->nused);
|
||||
}
|
||||
|
||||
void
|
||||
kcpuset_unuse(kcpuset_t *c, kcpuset_t **lst)
|
||||
{
|
||||
|
||||
if (atomic_dec_uint_nv(&c->nused) != 0)
|
||||
return;
|
||||
KASSERT(c->nused == 0);
|
||||
KASSERT(c->next == NULL);
|
||||
if (lst == NULL) {
|
||||
kcpuset_destroy(c);
|
||||
return;
|
||||
}
|
||||
c->next = *lst;
|
||||
*lst = c;
|
||||
}
|
||||
|
||||
int
|
||||
kcpuset_copyin(const cpuset_t *u, kcpuset_t *k, size_t len)
|
||||
{
|
||||
|
||||
KASSERT(k->nused > 0);
|
||||
KASSERT(k->next == NULL);
|
||||
if (len != CPUSET_SIZE(cpuset_nentries))
|
||||
return EINVAL;
|
||||
return copyin(u->bits, k->bits, cpuset_nentries * sizeof(k->bits[0]));
|
||||
}
|
||||
|
||||
int
|
||||
kcpuset_copyout(const kcpuset_t *k, cpuset_t *u, size_t len)
|
||||
{
|
||||
|
||||
KASSERT(k->nused > 0);
|
||||
KASSERT(k->next == NULL);
|
||||
if (len != CPUSET_SIZE(cpuset_nentries))
|
||||
return EINVAL;
|
||||
return copyout(k->bits, u->bits, cpuset_nentries * sizeof(u->bits[0]));
|
||||
}
|
||||
|
||||
void
|
||||
kcpuset_zero(kcpuset_t *c)
|
||||
{
|
||||
|
||||
KASSERT(c->nused > 0);
|
||||
KASSERT(c->next == NULL);
|
||||
memset(c->bits, 0, cpuset_nentries * sizeof(c->bits[0]));
|
||||
}
|
||||
|
||||
void
|
||||
kcpuset_fill(kcpuset_t *c)
|
||||
{
|
||||
|
||||
KASSERT(c->nused > 0);
|
||||
KASSERT(c->next == NULL);
|
||||
memset(c->bits, ~0, cpuset_nentries * sizeof(c->bits[0]));
|
||||
}
|
||||
|
||||
void
|
||||
kcpuset_set(cpuid_t i, kcpuset_t *c)
|
||||
{
|
||||
const unsigned long j = i >> CPUSET_SHIFT;
|
||||
|
||||
KASSERT(c->next == NULL);
|
||||
KASSERT(j < cpuset_nentries);
|
||||
c->bits[j] |= 1 << (i & CPUSET_MASK);
|
||||
}
|
||||
|
||||
int
|
||||
kcpuset_isset(cpuid_t i, const kcpuset_t *c)
|
||||
{
|
||||
const unsigned long j = i >> CPUSET_SHIFT;
|
||||
|
||||
KASSERT(c != NULL);
|
||||
KASSERT(c->nused > 0);
|
||||
KASSERT(c->next == NULL);
|
||||
KASSERT(j < cpuset_nentries);
|
||||
return ((1 << (i & CPUSET_MASK)) & c->bits[j]) != 0;
|
||||
}
|
||||
|
||||
bool
|
||||
kcpuset_iszero(const kcpuset_t *c)
|
||||
{
|
||||
unsigned long j;
|
||||
|
||||
for (j = 0; j < cpuset_nentries; j++)
|
||||
if (c->bits[j] != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
kcpuset_match(const kcpuset_t *c1, const kcpuset_t *c2)
|
||||
{
|
||||
unsigned long j;
|
||||
|
||||
for (j = 0; j < cpuset_nentries; j++)
|
||||
if ((c1->bits[j] & c2->bits[j]) != c2->bits[j])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.1657 2011/08/06 17:17:39 jruoho Exp $
|
||||
# $NetBSD: mi,v 1.1658 2011/08/07 13:33:02 rmind Exp $
|
||||
#
|
||||
# Note: don't delete entries from here - mark them as "obsolete" instead.
|
||||
#
|
||||
|
@ -2385,6 +2385,7 @@
|
|||
./usr/include/sys/ipc.h comp-c-include
|
||||
./usr/include/sys/joystick.h comp-c-include
|
||||
./usr/include/sys/kcore.h comp-c-include
|
||||
./usr/include/sys/kcpuset.h comp-c-include
|
||||
./usr/include/sys/kernel.h comp-obsolete obsolete
|
||||
./usr/include/sys/keylock.h comp-obsolete obsolete
|
||||
./usr/include/sys/kgdb.h comp-c-include
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files,v 1.1022 2011/07/30 17:01:04 christos Exp $
|
||||
# $NetBSD: files,v 1.1023 2011/08/07 13:33:01 rmind Exp $
|
||||
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
|
||||
|
||||
version 20100430
|
||||
|
@ -1530,6 +1530,7 @@ file kern/subr_extent.c
|
|||
file kern/subr_hash.c
|
||||
file kern/subr_humanize.c
|
||||
file kern/subr_iostat.c
|
||||
file kern/subr_kcpuset.c
|
||||
file kern/subr_kmem.c
|
||||
file kern/subr_kobj.c
|
||||
file kern/subr_kobj_vfs.c
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: init_main.c,v 1.434 2011/07/30 17:01:04 christos Exp $ */
|
||||
/* $NetBSD: init_main.c,v 1.435 2011/08/07 13:33:01 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
|
||||
|
@ -97,7 +97,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.434 2011/07/30 17:01:04 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.435 2011/08/07 13:33:01 rmind Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -167,6 +167,7 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.434 2011/07/30 17:01:04 christos Exp
|
|||
#include <sys/event.h>
|
||||
#include <sys/lockf.h>
|
||||
#include <sys/once.h>
|
||||
#include <sys/kcpuset.h>
|
||||
#include <sys/ksyms.h>
|
||||
#include <sys/uidinfo.h>
|
||||
#include <sys/kprintf.h>
|
||||
|
@ -310,6 +311,7 @@ main(void)
|
|||
evcnt_init();
|
||||
|
||||
uvm_init();
|
||||
kcpuset_sysinit();
|
||||
|
||||
prop_kern_init();
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_cpu.c,v 1.47 2011/06/29 06:22:21 matt Exp $ */
|
||||
/* $NetBSD: kern_cpu.c,v 1.48 2011/08/07 13:33:01 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
|
||||
|
@ -56,7 +56,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_cpu.c,v 1.47 2011/06/29 06:22:21 matt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_cpu.c,v 1.48 2011/08/07 13:33:01 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -107,6 +107,9 @@ kmutex_t cpu_lock __cacheline_aligned;
|
|||
int ncpu __read_mostly;
|
||||
int ncpuonline __read_mostly;
|
||||
bool mp_online __read_mostly;
|
||||
|
||||
kcpuset_t * kcpuset_attached __read_mostly;
|
||||
|
||||
struct cpuqueue cpu_queue __cacheline_aligned
|
||||
= CIRCLEQ_HEAD_INITIALIZER(cpu_queue);
|
||||
|
||||
|
@ -131,8 +134,11 @@ mi_cpu_attach(struct cpu_info *ci)
|
|||
if (__predict_false(cpu_infos == NULL)) {
|
||||
cpu_infos =
|
||||
kmem_zalloc(sizeof(cpu_infos[0]) * maxcpus, KM_SLEEP);
|
||||
kcpuset_create(&kcpuset_attached);
|
||||
kcpuset_zero(kcpuset_attached);
|
||||
}
|
||||
cpu_infos[cpu_index(ci)] = ci;
|
||||
kcpuset_set(kcpuset_attached, ci->ci_index);
|
||||
|
||||
sched_cpuattach(ci);
|
||||
|
||||
|
@ -315,7 +321,7 @@ cpu_xc_offline(struct cpu_info *ci)
|
|||
for (CPU_INFO_FOREACH(cii, mci)) {
|
||||
mspc = &mci->ci_schedstate;
|
||||
if ((mspc->spc_flags & SPCF_OFFLINE) == 0 &&
|
||||
kcpuset_isset(cpu_index(mci), l->l_affinity))
|
||||
kcpuset_isset(l->l_affinity, cpu_index(mci)))
|
||||
break;
|
||||
}
|
||||
if (mci == NULL) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_runq.c,v 1.30 2010/03/03 00:47:30 yamt Exp $ */
|
||||
/* $NetBSD: kern_runq.c,v 1.31 2011/08/07 13:33:01 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007, 2008 Mindaugas Rasiukevicius <rmind at NetBSD org>
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_runq.c,v 1.30 2010/03/03 00:47:30 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_runq.c,v 1.31 2011/08/07 13:33:01 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -352,7 +352,7 @@ sched_migratable(const struct lwp *l, struct cpu_info *ci)
|
|||
|
||||
/* Affinity bind */
|
||||
if (__predict_false(l->l_flag & LW_AFFINITY))
|
||||
return kcpuset_isset(cpu_index(ci), l->l_affinity);
|
||||
return kcpuset_isset(l->l_affinity, cpu_index(ci));
|
||||
|
||||
/* Processor-set */
|
||||
return (spc->spc_psid == l->l_psid);
|
||||
|
|
|
@ -0,0 +1,386 @@
|
|||
/* $NetBSD: subr_kcpuset.c,v 1.1 2011/08/07 13:33:01 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Mindaugas Rasiukevicius.
|
||||
*
|
||||
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Kernel CPU set implementation.
|
||||
*
|
||||
* Interface can be used by kernel subsystems as a unified dynamic CPU
|
||||
* bitset implementation handling many CPUs. Facility also supports early
|
||||
* use by MD code on boot, as it fixups bitsets on further boot.
|
||||
*
|
||||
* TODO:
|
||||
* - Handle "reverse" bitset on fixup/grow.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_kcpuset.c,v 1.1 2011/08/07 13:33:01 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <sys/atomic.h>
|
||||
#include <sys/sched.h>
|
||||
#include <sys/kcpuset.h>
|
||||
#include <sys/pool.h>
|
||||
|
||||
/* Number of CPUs to support. */
|
||||
#define KC_MAXCPUS roundup2(MAXCPUS, 32)
|
||||
|
||||
/*
|
||||
* Structure of dynamic CPU set in the kernel.
|
||||
*/
|
||||
struct kcpuset {
|
||||
uint32_t bits[0];
|
||||
};
|
||||
|
||||
typedef struct kcpuset_impl {
|
||||
/* Reference count. */
|
||||
u_int kc_refcnt;
|
||||
/* Next to free, if non-NULL (used when multiple references). */
|
||||
struct kcpuset * kc_next;
|
||||
/* Actual variable-sized field of bits. */
|
||||
struct kcpuset kc_field;
|
||||
} kcpuset_impl_t;
|
||||
|
||||
#define KC_BITS_OFF (offsetof(struct kcpuset_impl, kc_field))
|
||||
#define KC_GETSTRUCT(b) ((kcpuset_impl_t *)((char *)(b) - KC_BITS_OFF))
|
||||
|
||||
/* Sizes of a single bitset. */
|
||||
#define KC_SHIFT 5
|
||||
#define KC_MASK 31
|
||||
|
||||
/* An array of noted early kcpuset creations and data. */
|
||||
#define KC_SAVE_NITEMS 8
|
||||
|
||||
/* Structures for early boot mechanism (must be statically initialised). */
|
||||
static kcpuset_t ** kc_noted_early[KC_SAVE_NITEMS];
|
||||
static uint32_t kc_bits_early[KC_SAVE_NITEMS];
|
||||
static int kc_last_idx = 0;
|
||||
static bool kc_initialised = false;
|
||||
|
||||
#define KC_BITSIZE_EARLY sizeof(kc_bits_early[0])
|
||||
#define KC_NFIELDS_EARLY (KC_BITSIZE_EARLY >> KC_SHIFT)
|
||||
|
||||
/*
|
||||
* The size of whole bitset fields and amount of fields.
|
||||
* The whole size must statically initialise for early case.
|
||||
*/
|
||||
static size_t kc_bitsize __read_mostly = KC_BITSIZE_EARLY;
|
||||
static size_t kc_nfields __read_mostly = KC_NFIELDS_EARLY;
|
||||
|
||||
static pool_cache_t kc_cache __read_mostly;
|
||||
|
||||
static kcpuset_t * kcpuset_create_raw(void);
|
||||
|
||||
/*
|
||||
* kcpuset_sysinit: initialize the subsystem, transfer early boot cases
|
||||
* to dynamically allocated sets.
|
||||
*/
|
||||
void
|
||||
kcpuset_sysinit(void)
|
||||
{
|
||||
kcpuset_t *kc_dynamic[KC_SAVE_NITEMS], *kcp;
|
||||
int i, s;
|
||||
|
||||
/* Set a kcpuset_t sizes. */
|
||||
kc_nfields = (KC_MAXCPUS >> KC_SHIFT);
|
||||
kc_bitsize = sizeof(uint32_t) * kc_nfields;
|
||||
|
||||
kc_cache = pool_cache_init(sizeof(kcpuset_impl_t) + kc_bitsize,
|
||||
coherency_unit, 0, 0, "kcpuset", NULL, IPL_NONE, NULL, NULL, NULL);
|
||||
|
||||
/* First, pre-allocate kcpuset entries. */
|
||||
for (i = 0; i < kc_last_idx; i++) {
|
||||
kcp = kcpuset_create_raw();
|
||||
kcpuset_zero(kcp);
|
||||
kc_dynamic[i] = kcp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare to convert all early noted kcpuset uses to dynamic sets.
|
||||
* All processors, except the one we are currently running (primary),
|
||||
* must not be spinned yet. Since MD facilities can use kcpuset,
|
||||
* raise the IPL to high.
|
||||
*/
|
||||
KASSERT(mp_online == false);
|
||||
|
||||
s = splhigh();
|
||||
for (i = 0; i < kc_last_idx; i++) {
|
||||
/*
|
||||
* Transfer the bits from early static storage to the kcpuset.
|
||||
*/
|
||||
KASSERT(kc_bitsize >= KC_BITSIZE_EARLY);
|
||||
memcpy(kc_dynamic[i], &kc_bits_early[i], KC_BITSIZE_EARLY);
|
||||
|
||||
/*
|
||||
* Store the new pointer, pointing to the allocated kcpuset.
|
||||
* Note: we are not in an interrupt context and it is the only
|
||||
* CPU running - thus store is safe (e.g. no need for pointer
|
||||
* variable to be volatile).
|
||||
*/
|
||||
*kc_noted_early[i] = kc_dynamic[i];
|
||||
}
|
||||
kc_initialised = true;
|
||||
kc_last_idx = 0;
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* kcpuset_early_ptr: note an early boot use by saving the pointer and
|
||||
* returning a pointer to a static, temporary bit field.
|
||||
*/
|
||||
static kcpuset_t *
|
||||
kcpuset_early_ptr(kcpuset_t **kcptr)
|
||||
{
|
||||
kcpuset_t *kcp;
|
||||
int s;
|
||||
|
||||
s = splhigh();
|
||||
if (kc_last_idx < KC_SAVE_NITEMS) {
|
||||
/*
|
||||
* Save the pointer, return pointer to static early field.
|
||||
* Need to zero it out.
|
||||
*/
|
||||
kc_noted_early[kc_last_idx++] = kcptr;
|
||||
kcp = (kcpuset_t *)&kc_bits_early[kc_last_idx];
|
||||
memset(kcp, 0, KC_BITSIZE_EARLY);
|
||||
KASSERT(kc_bitsize == KC_BITSIZE_EARLY);
|
||||
} else {
|
||||
panic("kcpuset(9): all early-use entries exhausted; "
|
||||
"increase KC_SAVE_NITEMS\n");
|
||||
}
|
||||
splx(s);
|
||||
|
||||
return kcp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Routines to create or destroy the CPU set.
|
||||
* Early boot case is handled.
|
||||
*/
|
||||
|
||||
static kcpuset_t *
|
||||
kcpuset_create_raw(void)
|
||||
{
|
||||
kcpuset_impl_t *kc;
|
||||
|
||||
kc = pool_cache_get(kc_cache, PR_WAITOK);
|
||||
kc->kc_refcnt = 1;
|
||||
kc->kc_next = NULL;
|
||||
|
||||
/* Note: return pointer to the actual field of bits. */
|
||||
KASSERT((uint8_t *)kc + KC_BITS_OFF == (uint8_t *)&kc->kc_field);
|
||||
return &kc->kc_field;
|
||||
}
|
||||
|
||||
void
|
||||
kcpuset_create(kcpuset_t **retkcp)
|
||||
{
|
||||
|
||||
if (__predict_false(!kc_initialised)) {
|
||||
/* Early boot use - special case. */
|
||||
*retkcp = kcpuset_early_ptr(retkcp);
|
||||
return;
|
||||
}
|
||||
*retkcp = kcpuset_create_raw();
|
||||
}
|
||||
|
||||
void
|
||||
kcpuset_destroy(kcpuset_t *kcp)
|
||||
{
|
||||
kcpuset_impl_t *kc, *nkc;
|
||||
|
||||
KASSERT(kc_initialised);
|
||||
KASSERT(kcp != NULL);
|
||||
|
||||
kc = KC_GETSTRUCT(kcp);
|
||||
do {
|
||||
nkc = KC_GETSTRUCT(kc->kc_next);
|
||||
pool_cache_put(kc_cache, kc);
|
||||
kc = nkc;
|
||||
} while (kc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Routines to copy or reference/unreference the CPU set.
|
||||
* Note: early boot case is not supported by these routines.
|
||||
*/
|
||||
|
||||
void
|
||||
kcpuset_copy(kcpuset_t *dkcp, kcpuset_t *skcp)
|
||||
{
|
||||
|
||||
KASSERT(kc_initialised);
|
||||
KASSERT(KC_GETSTRUCT(dkcp)->kc_refcnt == 1);
|
||||
memcpy(dkcp, skcp, kc_bitsize);
|
||||
}
|
||||
|
||||
void
|
||||
kcpuset_use(kcpuset_t *kcp)
|
||||
{
|
||||
kcpuset_impl_t *kc = KC_GETSTRUCT(kcp);
|
||||
|
||||
KASSERT(kc_initialised);
|
||||
atomic_inc_uint(&kc->kc_refcnt);
|
||||
}
|
||||
|
||||
void
|
||||
kcpuset_unuse(kcpuset_t *kcp, kcpuset_t **lst)
|
||||
{
|
||||
kcpuset_impl_t *kc = KC_GETSTRUCT(kcp);
|
||||
|
||||
KASSERT(kc_initialised);
|
||||
KASSERT(kc->kc_refcnt > 0);
|
||||
|
||||
if (atomic_dec_uint_nv(&kc->kc_refcnt) != 0) {
|
||||
return;
|
||||
}
|
||||
KASSERT(kc->kc_next == NULL);
|
||||
if (lst == NULL) {
|
||||
kcpuset_destroy(kcp);
|
||||
return;
|
||||
}
|
||||
kc->kc_next = *lst;
|
||||
*lst = kcp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Routines to transfer the CPU set from / to userspace.
|
||||
* Note: early boot case is not supported by these routines.
|
||||
*/
|
||||
|
||||
int
|
||||
kcpuset_copyin(const cpuset_t *ucp, kcpuset_t *kcp, size_t len)
|
||||
{
|
||||
kcpuset_impl_t *kc = KC_GETSTRUCT(kcp);
|
||||
|
||||
KASSERT(kc_initialised);
|
||||
KASSERT(kc->kc_refcnt > 0);
|
||||
KASSERT(kc->kc_next == NULL);
|
||||
(void)kc;
|
||||
|
||||
if (len != kc_bitsize) { /* XXX */
|
||||
return EINVAL;
|
||||
}
|
||||
return copyin(ucp, kcp, kc_bitsize);
|
||||
}
|
||||
|
||||
int
|
||||
kcpuset_copyout(kcpuset_t *kcp, cpuset_t *ucp, size_t len)
|
||||
{
|
||||
kcpuset_impl_t *kc = KC_GETSTRUCT(kcp);
|
||||
|
||||
KASSERT(kc_initialised);
|
||||
KASSERT(kc->kc_refcnt > 0);
|
||||
KASSERT(kc->kc_next == NULL);
|
||||
(void)kc;
|
||||
|
||||
if (len != kc_bitsize) { /* XXX */
|
||||
return EINVAL;
|
||||
}
|
||||
return copyout(kcp, ucp, kc_bitsize);
|
||||
}
|
||||
|
||||
/*
|
||||
* Routines to change bit field - zero, fill, set, unset, etc.
|
||||
*/
|
||||
|
||||
void
|
||||
kcpuset_zero(kcpuset_t *kcp)
|
||||
{
|
||||
|
||||
KASSERT(!kc_initialised || KC_GETSTRUCT(kcp)->kc_refcnt > 0);
|
||||
KASSERT(!kc_initialised || KC_GETSTRUCT(kcp)->kc_next == NULL);
|
||||
memset(kcp, 0, kc_bitsize);
|
||||
}
|
||||
|
||||
void
|
||||
kcpuset_fill(kcpuset_t *kcp)
|
||||
{
|
||||
|
||||
KASSERT(!kc_initialised || KC_GETSTRUCT(kcp)->kc_refcnt > 0);
|
||||
KASSERT(!kc_initialised || KC_GETSTRUCT(kcp)->kc_next == NULL);
|
||||
memset(kcp, ~0, kc_bitsize);
|
||||
}
|
||||
|
||||
void
|
||||
kcpuset_set(kcpuset_t *kcp, cpuid_t i)
|
||||
{
|
||||
const size_t j = i >> KC_SHIFT;
|
||||
|
||||
KASSERT(!kc_initialised || KC_GETSTRUCT(kcp)->kc_next == NULL);
|
||||
KASSERT(j < kc_nfields);
|
||||
|
||||
kcp->bits[j] |= 1 << (i & KC_MASK);
|
||||
}
|
||||
|
||||
void
|
||||
kcpuset_clear(kcpuset_t *kcp, cpuid_t i)
|
||||
{
|
||||
const size_t j = i >> KC_SHIFT;
|
||||
|
||||
KASSERT(!kc_initialised || KC_GETSTRUCT(kcp)->kc_next == NULL);
|
||||
KASSERT(j < kc_nfields);
|
||||
|
||||
kcp->bits[j] &= ~(1 << (i & KC_MASK));
|
||||
}
|
||||
|
||||
int
|
||||
kcpuset_isset(kcpuset_t *kcp, cpuid_t i)
|
||||
{
|
||||
const size_t j = i >> KC_SHIFT;
|
||||
|
||||
KASSERT(kcp != NULL);
|
||||
KASSERT(!kc_initialised || KC_GETSTRUCT(kcp)->kc_refcnt > 0);
|
||||
KASSERT(!kc_initialised || KC_GETSTRUCT(kcp)->kc_next == NULL);
|
||||
KASSERT(j < kc_nfields);
|
||||
|
||||
return ((1 << (i & KC_MASK)) & kcp->bits[j]) != 0;
|
||||
}
|
||||
|
||||
bool
|
||||
kcpuset_iszero(kcpuset_t *kcp)
|
||||
{
|
||||
|
||||
for (size_t j = 0; j < kc_nfields; j++) {
|
||||
if (kcp->bits[j] != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
kcpuset_match(const kcpuset_t *kcp1, const kcpuset_t *kcp2)
|
||||
{
|
||||
|
||||
return memcmp(kcp1, kcp2, kc_bitsize) == 0;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: subr_pserialize.c,v 1.2 2011/08/01 15:26:31 he Exp $ */
|
||||
/* $NetBSD: subr_pserialize.c,v 1.3 2011/08/07 13:33:01 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
|
||||
|
@ -38,7 +38,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_pserialize.c,v 1.2 2011/08/01 15:26:31 he Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_pserialize.c,v 1.3 2011/08/07 13:33:01 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
|
@ -103,8 +103,8 @@ pserialize_create(void)
|
|||
|
||||
psz = kmem_zalloc(sizeof(struct pserialize), KM_SLEEP);
|
||||
cv_init(&psz->psz_notifier, "psrlz");
|
||||
psz->psz_target = kcpuset_create();
|
||||
psz->psz_pass = kcpuset_create();
|
||||
kcpuset_create(&psz->psz_target);
|
||||
kcpuset_create(&psz->psz_pass);
|
||||
psz->psz_owner = NULL;
|
||||
|
||||
return psz;
|
||||
|
@ -147,7 +147,6 @@ pserialize_perform(pserialize_t psz)
|
|||
return;
|
||||
}
|
||||
KASSERT(psz->psz_owner == NULL);
|
||||
KASSERT(kcpuset_iszero(psz->psz_target));
|
||||
KASSERT(ncpu > 0);
|
||||
|
||||
/*
|
||||
|
@ -157,7 +156,7 @@ pserialize_perform(pserialize_t psz)
|
|||
* other processors.
|
||||
*/
|
||||
psz->psz_owner = curlwp;
|
||||
kcpuset_fill(psz->psz_target);
|
||||
kcpuset_copy(psz->psz_target, kcpuset_attached);
|
||||
kcpuset_zero(psz->psz_pass);
|
||||
|
||||
mutex_spin_enter(&psz_lock);
|
||||
|
@ -234,7 +233,7 @@ pserialize_switchpoint(void)
|
|||
for (psz = TAILQ_FIRST(&psz_queue1); psz != NULL; psz = next) {
|
||||
next = TAILQ_NEXT(psz, psz_chain);
|
||||
if (!kcpuset_match(psz->psz_pass, psz->psz_target)) {
|
||||
kcpuset_set(cid, psz->psz_pass);
|
||||
kcpuset_set(psz->psz_pass, cid);
|
||||
continue;
|
||||
}
|
||||
kcpuset_zero(psz->psz_pass);
|
||||
|
@ -248,7 +247,7 @@ pserialize_switchpoint(void)
|
|||
for (psz = TAILQ_FIRST(&psz_queue0); psz != NULL; psz = next) {
|
||||
next = TAILQ_NEXT(psz, psz_chain);
|
||||
if (!kcpuset_match(psz->psz_pass, psz->psz_target)) {
|
||||
kcpuset_set(cid, psz->psz_pass);
|
||||
kcpuset_set(psz->psz_pass, cid);
|
||||
continue;
|
||||
}
|
||||
kcpuset_zero(psz->psz_pass);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sys_pset.c,v 1.15 2010/07/01 02:38:31 rmind Exp $ */
|
||||
/* $NetBSD: sys_pset.c,v 1.16 2011/08/07 13:33:01 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008, Mindaugas Rasiukevicius <rmind at NetBSD org>
|
||||
|
@ -36,7 +36,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_pset.c,v 1.15 2010/07/01 02:38:31 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_pset.c,v 1.16 2011/08/07 13:33:01 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
|
@ -373,7 +373,7 @@ sys_pset_assign(struct lwp *l, const struct sys_pset_assign_args *uap,
|
|||
lwp_unlock(t);
|
||||
continue;
|
||||
}
|
||||
if (kcpuset_isset(cpu_index(ci), t->l_affinity)) {
|
||||
if (kcpuset_isset(t->l_affinity, cpu_index(ci))) {
|
||||
lwp_unlock(t);
|
||||
mutex_exit(proc_lock);
|
||||
mutex_exit(&cpu_lock);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: sys_sched.c,v 1.35 2010/07/01 02:38:31 rmind Exp $ */
|
||||
/* $NetBSD: sys_sched.c,v 1.36 2011/08/07 13:33:01 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008, Mindaugas Rasiukevicius <rmind at NetBSD org>
|
||||
* Copyright (c) 2008, 2011 Mindaugas Rasiukevicius <rmind at NetBSD org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -42,7 +42,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_sched.c,v 1.35 2010/07/01 02:38:31 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_sched.c,v 1.36 2011/08/07 13:33:01 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
|
@ -298,12 +298,16 @@ out:
|
|||
static int
|
||||
genkcpuset(kcpuset_t **dset, const cpuset_t *sset, size_t size)
|
||||
{
|
||||
kcpuset_t *kset;
|
||||
int error;
|
||||
|
||||
*dset = kcpuset_create();
|
||||
error = kcpuset_copyin(sset, *dset, size);
|
||||
if (error != 0)
|
||||
kcpuset_unuse(*dset, NULL);
|
||||
kcpuset_create(&kset);
|
||||
error = kcpuset_copyin(sset, kset, size);
|
||||
if (error) {
|
||||
kcpuset_unuse(kset, NULL);
|
||||
} else {
|
||||
*dset = kset;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -320,7 +324,7 @@ sys__sched_setaffinity(struct lwp *l,
|
|||
syscallarg(size_t) size;
|
||||
syscallarg(const cpuset_t *) cpuset;
|
||||
} */
|
||||
kcpuset_t *cpuset, *cpulst = NULL;
|
||||
kcpuset_t *kcset, *kcpulst = NULL;
|
||||
struct cpu_info *ici, *ci;
|
||||
struct proc *p;
|
||||
struct lwp *t;
|
||||
|
@ -330,7 +334,7 @@ sys__sched_setaffinity(struct lwp *l,
|
|||
u_int lcnt;
|
||||
int error;
|
||||
|
||||
error = genkcpuset(&cpuset, SCARG(uap, cpuset), SCARG(uap, size));
|
||||
error = genkcpuset(&kcset, SCARG(uap, cpuset), SCARG(uap, size));
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -349,7 +353,7 @@ sys__sched_setaffinity(struct lwp *l,
|
|||
for (CPU_INFO_FOREACH(cii, ici)) {
|
||||
struct schedstate_percpu *ispc;
|
||||
|
||||
if (kcpuset_isset(cpu_index(ici), cpuset) == 0)
|
||||
if (kcpuset_isset(kcset, cpu_index(ici)) == 0)
|
||||
continue;
|
||||
|
||||
ispc = &ici->ci_schedstate;
|
||||
|
@ -375,8 +379,8 @@ sys__sched_setaffinity(struct lwp *l,
|
|||
goto out;
|
||||
}
|
||||
/* Empty set */
|
||||
kcpuset_unuse(cpuset, &cpulst);
|
||||
cpuset = NULL;
|
||||
kcpuset_unuse(kcset, &kcpulst);
|
||||
kcset = NULL;
|
||||
}
|
||||
|
||||
if (SCARG(uap, pid) != 0) {
|
||||
|
@ -433,33 +437,42 @@ sys__sched_setaffinity(struct lwp *l,
|
|||
lwp_unlock(t);
|
||||
continue;
|
||||
}
|
||||
if (cpuset) {
|
||||
if (kcset) {
|
||||
/* Set the affinity flag and new CPU set */
|
||||
t->l_flag |= LW_AFFINITY;
|
||||
kcpuset_use(cpuset);
|
||||
kcpuset_use(kcset);
|
||||
if (t->l_affinity != NULL)
|
||||
kcpuset_unuse(t->l_affinity, &cpulst);
|
||||
t->l_affinity = cpuset;
|
||||
kcpuset_unuse(t->l_affinity, &kcpulst);
|
||||
t->l_affinity = kcset;
|
||||
/* Migrate to another CPU, unlocks LWP */
|
||||
lwp_migrate(t, ci);
|
||||
} else {
|
||||
/* Unset the affinity flag */
|
||||
t->l_flag &= ~LW_AFFINITY;
|
||||
if (t->l_affinity != NULL)
|
||||
kcpuset_unuse(t->l_affinity, &cpulst);
|
||||
kcpuset_unuse(t->l_affinity, &kcpulst);
|
||||
t->l_affinity = NULL;
|
||||
lwp_unlock(t);
|
||||
}
|
||||
lcnt++;
|
||||
}
|
||||
mutex_exit(p->p_lock);
|
||||
if (lcnt == 0)
|
||||
if (lcnt == 0) {
|
||||
error = ESRCH;
|
||||
}
|
||||
out:
|
||||
mutex_exit(&cpu_lock);
|
||||
if (cpuset != NULL)
|
||||
kcpuset_unuse(cpuset, &cpulst);
|
||||
kcpuset_destroy(cpulst);
|
||||
|
||||
/*
|
||||
* Drop the initial reference (LWPs, if any, have the ownership now),
|
||||
* and destroy whatever is in the G/C list, if filled.
|
||||
*/
|
||||
if (kcset) {
|
||||
kcpuset_unuse(kcset, &kcpulst);
|
||||
}
|
||||
if (kcpulst) {
|
||||
kcpuset_destroy(kcpulst);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -477,10 +490,10 @@ sys__sched_getaffinity(struct lwp *l,
|
|||
syscallarg(cpuset_t *) cpuset;
|
||||
} */
|
||||
struct lwp *t;
|
||||
kcpuset_t *cpuset;
|
||||
kcpuset_t *kcset;
|
||||
int error;
|
||||
|
||||
error = genkcpuset(&cpuset, SCARG(uap, cpuset), SCARG(uap, size));
|
||||
error = genkcpuset(&kcset, SCARG(uap, cpuset), SCARG(uap, size));
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -500,15 +513,16 @@ sys__sched_getaffinity(struct lwp *l,
|
|||
lwp_lock(t);
|
||||
if (t->l_flag & LW_AFFINITY) {
|
||||
KASSERT(t->l_affinity != NULL);
|
||||
kcpuset_copy(cpuset, t->l_affinity);
|
||||
} else
|
||||
kcpuset_zero(cpuset);
|
||||
kcpuset_copy(kcset, t->l_affinity);
|
||||
} else {
|
||||
kcpuset_zero(kcset);
|
||||
}
|
||||
lwp_unlock(t);
|
||||
mutex_exit(t->l_proc->p_lock);
|
||||
|
||||
error = kcpuset_copyout(cpuset, SCARG(uap, cpuset), SCARG(uap, size));
|
||||
error = kcpuset_copyout(kcset, SCARG(uap, cpuset), SCARG(uap, size));
|
||||
out:
|
||||
kcpuset_unuse(cpuset, NULL);
|
||||
kcpuset_unuse(kcset, NULL);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.136 2011/07/17 20:54:54 joerg Exp $
|
||||
# $NetBSD: Makefile,v 1.137 2011/08/07 13:33:02 rmind Exp $
|
||||
|
||||
.include <bsd.sys.mk>
|
||||
|
||||
|
@ -19,7 +19,7 @@ INCS= acct.h agpio.h aio.h ansi.h aout_mids.h ataio.h atomic.h audioio.h \
|
|||
flashio.h float_ieee754.h fstypes.h gcq.h gmon.h gpio.h hash.h \
|
||||
ieee754.h inttypes.h ioccom.h ioctl.h ioctl_compat.h iostat.h ipc.h \
|
||||
joystick.h \
|
||||
kcore.h kgdb.h kmem.h ksem.h ksyms.h ktrace.h \
|
||||
kcore.h kcpuset.h kgdb.h kmem.h ksem.h ksyms.h ktrace.h \
|
||||
localedef.h lock.h lockf.h lwp.h lwpctl.h \
|
||||
malloc.h mallocvar.h mbuf.h md4.h md5.h midiio.h \
|
||||
mman.h module.h mount.h mqueue.h msg.h msgbuf.h mtio.h mutex.h \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cpu.h,v 1.32 2010/12/20 04:27:35 christos Exp $ */
|
||||
/* $NetBSD: cpu.h,v 1.33 2011/08/07 13:33:02 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007 YAMAMOTO Takashi,
|
||||
|
@ -89,6 +89,7 @@ CIRCLEQ_HEAD(cpuqueue, cpu_info);
|
|||
extern kmutex_t cpu_lock;
|
||||
extern u_int maxcpus;
|
||||
extern struct cpuqueue cpu_queue;
|
||||
extern kcpuset_t *kcpuset_attached;
|
||||
|
||||
static inline u_int
|
||||
cpu_index(struct cpu_info *ci)
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/* $NetBSD: kcpuset.h,v 1.1 2011/08/07 13:33:02 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008, 2011 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas and Mindaugas Rasiukevicius.
|
||||
*
|
||||
* 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_KCPUSET_H_
|
||||
#define _SYS_KCPUSET_H_
|
||||
|
||||
struct kcpuset;
|
||||
typedef struct kcpuset kcpuset_t;
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
void kcpuset_sysinit(void);
|
||||
|
||||
void kcpuset_create(kcpuset_t **);
|
||||
void kcpuset_destroy(kcpuset_t *);
|
||||
void kcpuset_copy(kcpuset_t *, kcpuset_t *);
|
||||
|
||||
void kcpuset_use(kcpuset_t *);
|
||||
void kcpuset_unuse(kcpuset_t *, kcpuset_t **);
|
||||
|
||||
int kcpuset_copyin(const cpuset_t *, kcpuset_t *, size_t);
|
||||
int kcpuset_copyout(kcpuset_t *, cpuset_t *, size_t);
|
||||
|
||||
void kcpuset_zero(kcpuset_t *);
|
||||
void kcpuset_fill(kcpuset_t *);
|
||||
void kcpuset_set(kcpuset_t *, cpuid_t);
|
||||
void kcpuset_clear(kcpuset_t *, cpuid_t);
|
||||
|
||||
int kcpuset_isset(kcpuset_t *, cpuid_t);
|
||||
bool kcpuset_iszero(kcpuset_t *);
|
||||
bool kcpuset_match(const kcpuset_t *, const kcpuset_t *);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _SYS_KCPUSET_H_ */
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: lwp.h,v 1.152 2011/05/19 03:07:29 rmind Exp $ */
|
||||
/* $NetBSD: lwp.h,v 1.153 2011/08/07 13:33:02 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001, 2006, 2007, 2008, 2009, 2010
|
||||
|
@ -37,6 +37,7 @@
|
|||
#include <sys/time.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/callout.h>
|
||||
#include <sys/kcpuset.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/signalvar.h>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sched.h,v 1.72 2010/04/16 03:21:49 rmind Exp $ */
|
||||
/* $NetBSD: sched.h,v 1.73 2011/08/07 13:33:02 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001, 2002, 2007, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -96,25 +96,8 @@ __BEGIN_DECLS
|
|||
* Interface of CPU-sets.
|
||||
*/
|
||||
typedef struct _cpuset cpuset_t;
|
||||
typedef struct _kcpuset kcpuset_t; /* XXX: lwp.h included from userland */
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
kcpuset_t *kcpuset_create(void);
|
||||
void kcpuset_destroy(kcpuset_t *);
|
||||
void kcpuset_copy(kcpuset_t *, const kcpuset_t *);
|
||||
void kcpuset_use(kcpuset_t *);
|
||||
void kcpuset_unuse(kcpuset_t *, kcpuset_t **);
|
||||
int kcpuset_copyin(const cpuset_t *, kcpuset_t *, size_t);
|
||||
int kcpuset_copyout(const kcpuset_t *, cpuset_t *, size_t);
|
||||
void kcpuset_zero(kcpuset_t *);
|
||||
void kcpuset_fill(kcpuset_t *);
|
||||
void kcpuset_set(cpuid_t, kcpuset_t *);
|
||||
int kcpuset_isset(cpuid_t, const kcpuset_t *);
|
||||
bool kcpuset_iszero(const kcpuset_t *);
|
||||
bool kcpuset_match(const kcpuset_t *, const kcpuset_t *);
|
||||
|
||||
#else
|
||||
#ifndef _KERNEL
|
||||
|
||||
#define cpuset_create() _cpuset_create()
|
||||
#define cpuset_destroy(c) _cpuset_destroy(c)
|
||||
|
|
Loading…
Reference in New Issue