Remove bits of the old NUMA.
Remove numactl(1), edit numa(4) to bring it some closer to reality, provide libc ABI shims for old NUMA syscalls. Noted and reviewed by: brooks (previous version) Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D16142
This commit is contained in:
parent
0d26206d04
commit
b3042426d0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=336182
@ -38,6 +38,12 @@
|
|||||||
# xargs -n1 | sort | uniq -d;
|
# xargs -n1 | sort | uniq -d;
|
||||||
# done
|
# done
|
||||||
|
|
||||||
|
# 20180710: old numa cleanup
|
||||||
|
OLD_FILES+=usr/include/sys/numa.h
|
||||||
|
OLD_FILES+=usr/share/man/man2/numa_getaffinity.2.gz
|
||||||
|
OLD_FILES+=usr/share/man/man2/numa_setaffinity.2.gz
|
||||||
|
OLD_FILES+=usr/share/man/man1/numactl.1.gz
|
||||||
|
OLD_FILES+=usr/bin/numactl
|
||||||
# 20180630: new clang import which bumps version from 6.0.0 to 6.0.1.
|
# 20180630: new clang import which bumps version from 6.0.0 to 6.0.1.
|
||||||
OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/allocator_interface.h
|
OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/allocator_interface.h
|
||||||
OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/asan_interface.h
|
OLD_FILES+=usr/lib/clang/6.0.0/include/sanitizer/asan_interface.h
|
||||||
|
@ -258,7 +258,6 @@ MAN+= abort2.2 \
|
|||||||
nanosleep.2 \
|
nanosleep.2 \
|
||||||
nfssvc.2 \
|
nfssvc.2 \
|
||||||
ntp_adjtime.2 \
|
ntp_adjtime.2 \
|
||||||
numa_getaffinity.2 \
|
|
||||||
open.2 \
|
open.2 \
|
||||||
pathconf.2 \
|
pathconf.2 \
|
||||||
pdfork.2 \
|
pdfork.2 \
|
||||||
@ -430,7 +429,6 @@ MLINKS+=mount.2 nmount.2 \
|
|||||||
MLINKS+=mq_receive.2 mq_timedreceive.2
|
MLINKS+=mq_receive.2 mq_timedreceive.2
|
||||||
MLINKS+=mq_send.2 mq_timedsend.2
|
MLINKS+=mq_send.2 mq_timedsend.2
|
||||||
MLINKS+=ntp_adjtime.2 ntp_gettime.2
|
MLINKS+=ntp_adjtime.2 ntp_gettime.2
|
||||||
MLINKS+=numa_getaffinity.2 numa_setaffinity.2
|
|
||||||
MLINKS+=open.2 openat.2
|
MLINKS+=open.2 openat.2
|
||||||
MLINKS+=pathconf.2 fpathconf.2
|
MLINKS+=pathconf.2 fpathconf.2
|
||||||
MLINKS+=pathconf.2 lpathconf.2
|
MLINKS+=pathconf.2 lpathconf.2
|
||||||
|
@ -54,3 +54,5 @@ __sym_compat(symbol, __compat_enosys ## symbol, version)
|
|||||||
|
|
||||||
__compat_nosys(netbsd_lchown, FBSD_1.0);
|
__compat_nosys(netbsd_lchown, FBSD_1.0);
|
||||||
__compat_nosys(netbsd_msync, FBSD_1.0);
|
__compat_nosys(netbsd_msync, FBSD_1.0);
|
||||||
|
__compat_nosys(numa_getaffinity, FBSD_1.4);
|
||||||
|
__compat_nosys(numa_setaffinity, FBSD_1.4);
|
||||||
|
@ -1,197 +0,0 @@
|
|||||||
.\" Copyright (c) 2008 Christian Brueffer
|
|
||||||
.\" Copyright (c) 2008 Jeffrey Roberson
|
|
||||||
.\" Copyright (c) 2015 Adrian Chadd
|
|
||||||
.\" All rights reserved.
|
|
||||||
.\"
|
|
||||||
.\" Redistribution and use in source and binary forms, with or without
|
|
||||||
.\" modification, are permitted provided that the following conditions
|
|
||||||
.\" are met:
|
|
||||||
.\" 1. Redistributions of source code must retain the above copyright
|
|
||||||
.\" notice, this list of conditions and the following disclaimer.
|
|
||||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
.\" notice, this list of conditions and the following disclaimer in the
|
|
||||||
.\" documentation and/or other materials provided with the distribution.
|
|
||||||
.\"
|
|
||||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
.\" SUCH DAMAGE.
|
|
||||||
.\"
|
|
||||||
.\" $FreeBSD$
|
|
||||||
.\"
|
|
||||||
.Dd May 7, 2015
|
|
||||||
.Dt NUMA_GETAFFINITY 2
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm numa_getaffinity ,
|
|
||||||
.Nm numa_setaffinity
|
|
||||||
.Nd manage NUMA affinity
|
|
||||||
.Sh LIBRARY
|
|
||||||
.Lb libc
|
|
||||||
.Sh SYNOPSIS
|
|
||||||
.In sys/param.h
|
|
||||||
.In sys/numa.h
|
|
||||||
.Ft int
|
|
||||||
.Fn numa_getaffinity "cpuwhich_t which" "id_t id" "struct vm_domain_policy_entry *policy"
|
|
||||||
.Ft int
|
|
||||||
.Fn numa_setaffinity "cpuwhich_t which" "id_t id" "const struct vm_domain_policy_entry *policy"
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
.Fn numa_getaffinity
|
|
||||||
and
|
|
||||||
.Fn numa_setaffinity
|
|
||||||
allow the manipulation of NUMA policies available to processes and threads.
|
|
||||||
These functions may manipulate NUMA policies that contain many processes
|
|
||||||
or affect only a single object.
|
|
||||||
.Pp
|
|
||||||
Valid values for the
|
|
||||||
.Fa which
|
|
||||||
argument are documented in
|
|
||||||
.Xr cpuset 2 .
|
|
||||||
These arguments specify which object set are used.
|
|
||||||
Only
|
|
||||||
.Dv CPU_WHICH_TID
|
|
||||||
and
|
|
||||||
.Dv CPU_WHICH_PID
|
|
||||||
can be manipulated.
|
|
||||||
.Pp
|
|
||||||
The
|
|
||||||
.Fa policy
|
|
||||||
entry contains a vm_domain_policy_entry with the following fields:
|
|
||||||
.Bd -literal
|
|
||||||
struct vm_domain_policy_entry {
|
|
||||||
vm_domain_policy_type_t policy; /* VM policy */
|
|
||||||
int domain; /* VM domain, if applicable */
|
|
||||||
}
|
|
||||||
.Ed
|
|
||||||
.Fa vm_domain_policy_type_t policy
|
|
||||||
is one these:
|
|
||||||
.Bl -tag -width VM_POLICY_NONE
|
|
||||||
.It Dv VM_POLICY_NONE
|
|
||||||
Reset the domain back to none.
|
|
||||||
Any parent object NUMA domain policy will apply.
|
|
||||||
The only valid value for
|
|
||||||
.Dv domain
|
|
||||||
is -1.
|
|
||||||
.It Dv VM_POLICY_ROUND_ROBIN
|
|
||||||
Select round-robin policy.
|
|
||||||
Pages will be allocated round-robin from each VM domain in order.
|
|
||||||
The only valid value for
|
|
||||||
.Dv domain
|
|
||||||
is -1.
|
|
||||||
.It Dv VM_POLICY_FIXED_DOMAIN
|
|
||||||
Select fixed-domain only policy.
|
|
||||||
Pages will be allocated from the given
|
|
||||||
.Dv domain
|
|
||||||
which must be set to a valid VM domain.
|
|
||||||
Pages will not be allocated from another domain if
|
|
||||||
.Dv domain
|
|
||||||
is out of free pages.
|
|
||||||
.It Dv VM_POLICY_FIXED_DOMAIN_ROUND_ROBIN
|
|
||||||
Select fixed-domain only policy.
|
|
||||||
Pages will be allocated from
|
|
||||||
.Dv domain
|
|
||||||
which must be set to a valid VM domain.
|
|
||||||
If page allocation fails, pages will be round-robin
|
|
||||||
allocated from another domain if
|
|
||||||
.Dv domain
|
|
||||||
is out of free pages.
|
|
||||||
.It Dv VM_POLICY_FIRST_TOUCH
|
|
||||||
Select first-touch policy.
|
|
||||||
Pages will be allocated from the NUMA domain which the thread
|
|
||||||
is currently scheduled upon.
|
|
||||||
Pages will not be allocated from another domain if the current domain
|
|
||||||
is out of free pages.
|
|
||||||
The only valid value for
|
|
||||||
.Dv domain
|
|
||||||
is -1.
|
|
||||||
.It Dv VM_POLICY_FIRST_TOUCH_ROUND_ROBIN
|
|
||||||
Select first-touch policy.
|
|
||||||
Pages will be allocated from the NUMA domain which the thread
|
|
||||||
is currently scheduled upon.
|
|
||||||
Pages will be allocated round-robin from another domain if the
|
|
||||||
current domain is out of free pages.
|
|
||||||
The only valid value for
|
|
||||||
.Dv domain
|
|
||||||
is -1.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
Note that the VM might assign some pages from other domains.
|
|
||||||
For example, if an existing page allocation is covered by a superpage
|
|
||||||
allocation.
|
|
||||||
.Pp
|
|
||||||
.Fn numa_getaffinity
|
|
||||||
retrieves the
|
|
||||||
NUMA policy from the object specified by
|
|
||||||
.Fa which
|
|
||||||
and
|
|
||||||
.Fa id
|
|
||||||
and stores it in the space provided by
|
|
||||||
.Fa policy .
|
|
||||||
.Pp
|
|
||||||
.Fn numa_setaffinity
|
|
||||||
attempts to set the NUMA policy for the object specified by
|
|
||||||
.Fa which
|
|
||||||
and
|
|
||||||
.Fa id
|
|
||||||
to the policy in
|
|
||||||
.Fa policy .
|
|
||||||
.Sh RETURN VALUES
|
|
||||||
.Rv -std
|
|
||||||
.Sh ERRORS
|
|
||||||
.Va errno
|
|
||||||
can contain these error codes:
|
|
||||||
.Bl -tag -width Er
|
|
||||||
.It Bq Er EINVAL
|
|
||||||
The
|
|
||||||
.Fa level
|
|
||||||
or
|
|
||||||
.Fa which
|
|
||||||
argument was not a valid value.
|
|
||||||
.It Bq Er EINVAL
|
|
||||||
The
|
|
||||||
.Fa policy
|
|
||||||
argument specified when calling
|
|
||||||
.Fn numa_setaffinity
|
|
||||||
did not contain a valid policy.
|
|
||||||
.It Bq Er EFAULT
|
|
||||||
The policy pointer passed was invalid.
|
|
||||||
.It Bq Er ESRCH
|
|
||||||
The object specified by the
|
|
||||||
.Fa id
|
|
||||||
and
|
|
||||||
.Fa which
|
|
||||||
arguments could not be found.
|
|
||||||
.It Bq Er ERANGE
|
|
||||||
The
|
|
||||||
.Fa domain
|
|
||||||
in the given policy
|
|
||||||
was out of the range of possible VM domains available.
|
|
||||||
.It Bq Er EPERM
|
|
||||||
The calling process did not have the credentials required to complete the
|
|
||||||
operation.
|
|
||||||
.El
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr cpuset 1 ,
|
|
||||||
.Xr numactl 1 ,
|
|
||||||
.Xr cpuset 2 ,
|
|
||||||
.Xr cpuset_getaffinity 2 ,
|
|
||||||
.Xr cpuset_getid 2 ,
|
|
||||||
.Xr cpuset_setaffinity 2 ,
|
|
||||||
.Xr cpuset_setid 2 ,
|
|
||||||
.Xr pthread_affinity_np 3 ,
|
|
||||||
.Xr pthread_attr_affinity_np 3 ,
|
|
||||||
.Xr numa 4
|
|
||||||
.Sh HISTORY
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
family of system calls first appeared in
|
|
||||||
.Fx 11.0 .
|
|
||||||
.Sh AUTHORS
|
|
||||||
.An Adrian Chadd Aq Mt adrian@FreeBSD.org
|
|
@ -24,7 +24,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd May 10, 2015
|
.Dd July 10, 2018
|
||||||
.Dt NUMA 4
|
.Dt NUMA 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -34,7 +34,6 @@
|
|||||||
.Cd options SMP
|
.Cd options SMP
|
||||||
.Cd options MAXMEMDOM=16
|
.Cd options MAXMEMDOM=16
|
||||||
.Pp
|
.Pp
|
||||||
.In sys/numa.h
|
|
||||||
.In sys/cpuset.h
|
.In sys/cpuset.h
|
||||||
.In sys/bus.h
|
.In sys/bus.h
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
@ -51,20 +50,21 @@ that is connected to one of the other processors.
|
|||||||
.Pp
|
.Pp
|
||||||
.Nm
|
.Nm
|
||||||
is enabled when the
|
is enabled when the
|
||||||
.Cd MAXMEMDOM
|
.Cd NUMA
|
||||||
option is used in a kernel configuration
|
option is used in a kernel configuration
|
||||||
file and is set to a value greater than 1.
|
file and the
|
||||||
|
.Cd MAXMEMDOM
|
||||||
|
option is set to a value greater than 1.
|
||||||
.Pp
|
.Pp
|
||||||
Thread and process
|
Thread and process
|
||||||
.Nm
|
.Nm
|
||||||
policies are controlled with the
|
policies are controlled with the
|
||||||
.Xr numa_setaffinity 2
|
.Xr cpuset_getdomain 2
|
||||||
and
|
and
|
||||||
.Xr numa_getaffinity 2
|
.Xr cpuset_setdomain 2
|
||||||
syscalls.
|
syscalls.
|
||||||
.Pp
|
|
||||||
The
|
The
|
||||||
.Xr numactl 1
|
.Xr cpuset 1
|
||||||
tool is available for starting processes with a non-default
|
tool is available for starting processes with a non-default
|
||||||
policy, or to change the policy of an existing thread or process.
|
policy, or to change the policy of an existing thread or process.
|
||||||
.Pp
|
.Pp
|
||||||
@ -83,15 +83,6 @@ MIB variables:
|
|||||||
.It Va vm.ndomains
|
.It Va vm.ndomains
|
||||||
The number of VM domains which have been detected.
|
The number of VM domains which have been detected.
|
||||||
.Pp
|
.Pp
|
||||||
.It Va vm.default_policy
|
|
||||||
The default VM domain allocation policy.
|
|
||||||
Defaults to "first-touch-rr".
|
|
||||||
The valid values are "first-touch", "first-touch-rr",
|
|
||||||
"rr", where "rr" is a short-hand for "round-robin."
|
|
||||||
See
|
|
||||||
.Xr numa_setaffinity 2
|
|
||||||
for more information about the available policies.
|
|
||||||
.Pp
|
|
||||||
.It Va vm.phys_locality
|
.It Va vm.phys_locality
|
||||||
A table indicating the relative cost of each VM domain to each other.
|
A table indicating the relative cost of each VM domain to each other.
|
||||||
A value of 10 indicates equal cost.
|
A value of 10 indicates equal cost.
|
||||||
@ -111,36 +102,11 @@ domains are mapped into a contiguous, non-sparse
|
|||||||
VM domain space, starting from 0.
|
VM domain space, starting from 0.
|
||||||
Thus, VM domain information (for example, the domain identifier) is not
|
Thus, VM domain information (for example, the domain identifier) is not
|
||||||
necessarily the same as is found in the hardware specific information.
|
necessarily the same as is found in the hardware specific information.
|
||||||
.Pp
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
allocation policies are implemented as a policy and iterator in
|
|
||||||
.Pa sys/vm/vm_domain.c
|
|
||||||
and
|
|
||||||
.Pa sys/vm/vm_domain.h .
|
|
||||||
Policy information is available in both struct thread and struct proc.
|
Policy information is available in both struct thread and struct proc.
|
||||||
Processes inherit
|
|
||||||
.Nm
|
|
||||||
policy from parent processes and threads inherit
|
|
||||||
.Nm
|
|
||||||
policy from parent threads.
|
|
||||||
Note that threads do not explicitly inherit their
|
|
||||||
.Nm
|
|
||||||
policy from processes.
|
|
||||||
Instead, if no thread policy is set, the system
|
|
||||||
will fall back to the process policy.
|
|
||||||
.Pp
|
|
||||||
For now,
|
|
||||||
.Nm
|
|
||||||
domain policies only influence physical page allocation in
|
|
||||||
.Pa sys/vm/vm_phys.c .
|
|
||||||
This is useful for userland memory allocation, but not for kernel
|
|
||||||
and driver memory allocation.
|
|
||||||
These features will be implemented in future work.
|
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr numactl 1 ,
|
.Xr cpuset 1 ,
|
||||||
.Xr numa_getaffinity 2 ,
|
.Xr cpuset_getaffinity 2 ,
|
||||||
.Xr numa_setaffinity 2 ,
|
.Xr cpuset_setaffinity 2 ,
|
||||||
.Xr bus_get_domain 9
|
.Xr bus_get_domain 9
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
.Nm
|
.Nm
|
||||||
@ -156,13 +122,15 @@ The
|
|||||||
.Xr numa_getaffinity 2
|
.Xr numa_getaffinity 2
|
||||||
and
|
and
|
||||||
.Xr numa_setaffinity 2
|
.Xr numa_setaffinity 2
|
||||||
syscalls first appeared in
|
syscalls and the
|
||||||
.Fx 11.0 .
|
|
||||||
.Pp
|
|
||||||
The
|
|
||||||
.Xr numactl 1
|
.Xr numactl 1
|
||||||
tool first appeared in
|
tool first appeared in
|
||||||
.Fx 11.0 .
|
.Fx 11.0
|
||||||
|
and were removed in
|
||||||
|
.Fx 12.0 .
|
||||||
|
Current implementation appeared in
|
||||||
|
.Fx 12.0 .
|
||||||
|
.Pp
|
||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
This manual page written by
|
This manual page written by
|
||||||
.An Adrian Chadd Aq Mt adrian@FreeBSD.org .
|
.An Adrian Chadd Aq Mt adrian@FreeBSD.org .
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015 Adrian Chadd <adrian@FreeBSD.org>.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of the University nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* $FreeBSD$
|
|
||||||
*/
|
|
||||||
#ifndef __SYS_NUMA_H__
|
|
||||||
#define __SYS_NUMA_H__
|
|
||||||
|
|
||||||
#include <sys/_vm_domain.h>
|
|
||||||
|
|
||||||
extern int numa_setaffinity(cpuwhich_t which, id_t id,
|
|
||||||
struct vm_domain_policy_entry *vd);
|
|
||||||
extern int numa_getaffinity(cpuwhich_t which, id_t id,
|
|
||||||
struct vm_domain_policy_entry *vd);
|
|
||||||
|
|
||||||
#endif /* __SYS_NUMA_H__ */
|
|
@ -104,7 +104,6 @@ SUBDIR= alias \
|
|||||||
nfsstat \
|
nfsstat \
|
||||||
nice \
|
nice \
|
||||||
nl \
|
nl \
|
||||||
numactl \
|
|
||||||
nohup \
|
nohup \
|
||||||
opieinfo \
|
opieinfo \
|
||||||
opiekey \
|
opiekey \
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
# $FreeBSD$
|
|
||||||
|
|
||||||
PROG= numactl
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
@ -1,17 +0,0 @@
|
|||||||
# $FreeBSD$
|
|
||||||
# Autogenerated - do NOT edit!
|
|
||||||
|
|
||||||
DIRDEPS = \
|
|
||||||
gnu/lib/csu \
|
|
||||||
include \
|
|
||||||
include/xlocale \
|
|
||||||
lib/${CSU_DIR} \
|
|
||||||
lib/libc \
|
|
||||||
lib/libcompiler_rt \
|
|
||||||
|
|
||||||
|
|
||||||
.include <dirdeps.mk>
|
|
||||||
|
|
||||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
|
||||||
# local dependencies - needed for -jN in clean tree
|
|
||||||
.endif
|
|
@ -1,132 +0,0 @@
|
|||||||
.\" Copyright (c) 2015 Adrian Chadd <adrian@FreeBSD.org>
|
|
||||||
.\" All rights reserved.
|
|
||||||
.\"
|
|
||||||
.\" Redistribution and use in source and binary forms, with or without
|
|
||||||
.\" modification, are permitted provided that the following conditions
|
|
||||||
.\" are met:
|
|
||||||
.\" 1. Redistributions of source code must retain the above copyright
|
|
||||||
.\" notice, this list of conditions and the following disclaimer.
|
|
||||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
.\" notice, this list of conditions and the following disclaimer in the
|
|
||||||
.\" documentation and/or other materials provided with the distribution.
|
|
||||||
.\"
|
|
||||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
.\" SUCH DAMAGE.
|
|
||||||
.\"
|
|
||||||
.\" $FreeBSD$
|
|
||||||
.\"
|
|
||||||
.Dd May 9, 2015
|
|
||||||
.Dt NUMACTL 1
|
|
||||||
.Os
|
|
||||||
.Sh NAME
|
|
||||||
.Nm numactl
|
|
||||||
.Nd "manage NUMA policy configuration"
|
|
||||||
.Sh SYNOPSIS
|
|
||||||
.Nm
|
|
||||||
.Op Fl l Ar policy
|
|
||||||
.Op Fl m Ar domain
|
|
||||||
.Op Fl c Ar domain
|
|
||||||
.Ar cmd ...
|
|
||||||
.Nm
|
|
||||||
.Fl g
|
|
||||||
.Op Fl p Ar pid
|
|
||||||
.Op Fl t Ar tid
|
|
||||||
.Nm
|
|
||||||
.Fl s
|
|
||||||
.Op Fl l Ar policy
|
|
||||||
.Op Fl m Ar domain
|
|
||||||
.Op Fl c Ar domain
|
|
||||||
.Op Fl p Ar pid
|
|
||||||
.Op Fl t Ar tid
|
|
||||||
.Sh DESCRIPTION
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
command can be used to assign NUMA policies to processes/threads,
|
|
||||||
run commands with a given NUMA policy, and query information
|
|
||||||
about NUMA policies on running processes.
|
|
||||||
.Pp
|
|
||||||
.Nm
|
|
||||||
requires a target to modify or query.
|
|
||||||
The target may be specified as a command, process id or a thread id.
|
|
||||||
Using
|
|
||||||
.Fl -get
|
|
||||||
the target's NUMA policy may be queried.
|
|
||||||
Using
|
|
||||||
.Fl -set
|
|
||||||
the target's NUMA policy may be queried.
|
|
||||||
If no target is specified,
|
|
||||||
.Nm
|
|
||||||
operates on itself.
|
|
||||||
Not all combinations of operations and targets are supported.
|
|
||||||
For example,
|
|
||||||
you may not set the id of an existing set or query and launch a command
|
|
||||||
at the same time.
|
|
||||||
.Pp
|
|
||||||
Each process and thread has a NUMA policy.
|
|
||||||
By default the policy is NONE.
|
|
||||||
If a thread policy is NONE, then the policy will fall back to the process.
|
|
||||||
If the process policy is NONE, then the policy will fall back to the
|
|
||||||
system default.
|
|
||||||
The policy may be queried by using
|
|
||||||
.Fl -get.
|
|
||||||
.Pp
|
|
||||||
The options are as follows:
|
|
||||||
.Bl -tag -width ".Fl -cpudomain Ar domain"
|
|
||||||
.It Fl -cpudomain Ar domain , Fl c Ar domain
|
|
||||||
Set the given CPU scheduling policy.
|
|
||||||
Constrain the object (tid, pid, command) to run on CPUs
|
|
||||||
that belong to the given domain.
|
|
||||||
.It Fl -get , Fl g
|
|
||||||
Retrieve the NUMA policy for the given thread or process id.
|
|
||||||
.It Fl -set , Fl s
|
|
||||||
Set the NUMA policy for the given thread or process id.
|
|
||||||
.It Fl -memdomain Ar domain , Fl m Ar domain
|
|
||||||
Constrain the object (tid, pid, command) to the given
|
|
||||||
domain.
|
|
||||||
This is only valid for fixed-domain and fixed-domain-rr.
|
|
||||||
It must not be set for other policies.
|
|
||||||
.It Fl -mempolicy Ar policy , Fl l Ar policy
|
|
||||||
Set the given memory allocation policy.
|
|
||||||
Valid policies are none, rr, fixed-domain, fixed-domain-rr,
|
|
||||||
first-touch, and first-touch-rr.
|
|
||||||
A memdomain argument is required for fixed-domain and
|
|
||||||
fixed-domain-rr.
|
|
||||||
.It Fl -pid Ar pid , Fl p Ar pid
|
|
||||||
Operate on the given pid.
|
|
||||||
.It Fl -tid Ar tid , Fl t Ar tid
|
|
||||||
Operate on the given tid.
|
|
||||||
.El
|
|
||||||
.Sh EXIT STATUS
|
|
||||||
.Ex -std
|
|
||||||
.Sh EXAMPLES
|
|
||||||
Create a
|
|
||||||
.Pa /bin/sh
|
|
||||||
process with memory coming from domain 0, but
|
|
||||||
CPUs coming from domain 1:
|
|
||||||
.Dl numactl --mempolicy=fixed-domain --memdomain=0 --cpudomain=1 /bin/sh
|
|
||||||
.Pp
|
|
||||||
Query the NUMA policy for the
|
|
||||||
.Aq sh pid :
|
|
||||||
.Dl numactl --get --pid=<sh pid>
|
|
||||||
.Pp
|
|
||||||
Set the NUMA policy for the given TID to round-robin:
|
|
||||||
.Dl numactl --set --mempolicy=rr --tid=<tid>
|
|
||||||
.Sh SEE ALSO
|
|
||||||
.Xr cpuset 2 ,
|
|
||||||
.Xr numa 4
|
|
||||||
.Sh HISTORY
|
|
||||||
The
|
|
||||||
.Nm
|
|
||||||
command first appeared in
|
|
||||||
.Fx 11.0 .
|
|
||||||
.Sh AUTHORS
|
|
||||||
.An Adrian Chadd Aq Mt adrian@FreeBSD.org
|
|
@ -1,314 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2015 Adrian Chadd <adrian@FreeBSD.org>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
|
||||||
__FBSDID("$FreeBSD$");
|
|
||||||
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include <sys/cpuset.h>
|
|
||||||
#include <sys/domainset.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <err.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <libgen.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sysexits.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static struct option longopts[] = {
|
|
||||||
{ "tid", required_argument, NULL, 't' },
|
|
||||||
{ "pid", required_argument, NULL, 'p' },
|
|
||||||
{ "memdomain", required_argument, NULL, 'm' },
|
|
||||||
{ "cpudomain", required_argument, NULL, 'c' },
|
|
||||||
{ "mempolicy", required_argument, NULL, 'l' },
|
|
||||||
{ "set", no_argument, NULL, 's' },
|
|
||||||
{ "get", no_argument, NULL, 'g' },
|
|
||||||
{ NULL, 0, NULL, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
policy_to_str(int policy)
|
|
||||||
{
|
|
||||||
|
|
||||||
switch (policy) {
|
|
||||||
case DOMAINSET_POLICY_INVALID:
|
|
||||||
return ("invalid");
|
|
||||||
case DOMAINSET_POLICY_ROUNDROBIN:
|
|
||||||
return ("round-robin");
|
|
||||||
case DOMAINSET_POLICY_FIRSTTOUCH:
|
|
||||||
return ("first-touch");
|
|
||||||
case DOMAINSET_POLICY_PREFER:
|
|
||||||
return ("prefer");
|
|
||||||
default:
|
|
||||||
return ("unknown");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
domain_print(domainset_t *mask)
|
|
||||||
{
|
|
||||||
int once;
|
|
||||||
int bit;
|
|
||||||
|
|
||||||
for (once = 0, bit = 0; bit < DOMAINSET_SETSIZE; bit++) {
|
|
||||||
if (DOMAINSET_ISSET(bit, mask)) {
|
|
||||||
if (once == 0) {
|
|
||||||
printf("%d", bit);
|
|
||||||
once = 1;
|
|
||||||
} else
|
|
||||||
printf(", %d", bit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
parse_policy(int *policy, const char *str)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (strcmp(str, "rr") == 0) {
|
|
||||||
*policy = DOMAINSET_POLICY_ROUNDROBIN;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(str, "first-touch-rr") == 0) {
|
|
||||||
*policy = DOMAINSET_POLICY_FIRSTTOUCH;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(str, "first-touch") == 0) {
|
|
||||||
*policy = DOMAINSET_POLICY_FIRSTTOUCH;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(str, "fixed-domain") == 0) {
|
|
||||||
*policy = DOMAINSET_POLICY_PREFER;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(str, "fixed-domain-rr") == 0) {
|
|
||||||
*policy = DOMAINSET_POLICY_PREFER;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
usage(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
printf("usage: numactl --get [--tid/-t <tid>] [--pid/-p <pid>]\n");
|
|
||||||
printf(" numactl --set [--tid=<tid>] [--pid/-p<pid>]\n");
|
|
||||||
printf(" [--mempolicy/-l <policy>] [--memdomain/"
|
|
||||||
"-m <domain>]\n");
|
|
||||||
printf(" [--cpudomain/-c <domain>]\n");
|
|
||||||
printf(" numactl [--mempolicy/-l <policy>] [--memdomain/-m "
|
|
||||||
"<domain>]\n");
|
|
||||||
printf(" [--cpudomain/-c <domain>] <cmd> ...\n");
|
|
||||||
|
|
||||||
exit(EX_USAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
set_numa_domain_cpuaffinity(int cpu_domain, cpuwhich_t which, id_t id)
|
|
||||||
{
|
|
||||||
cpuset_t set;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
error = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_DOMAIN,
|
|
||||||
cpu_domain, sizeof(set), &set);
|
|
||||||
if (error != 0)
|
|
||||||
err(1, "cpuset_getaffinity");
|
|
||||||
error = cpuset_setaffinity(CPU_LEVEL_WHICH, which, id, sizeof(set),
|
|
||||||
&set);
|
|
||||||
if (error != 0)
|
|
||||||
err(1, "cpuset_setaffinity");
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Attempt to maintain compatability with old style syscalls.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
numa_setaffinity(cpuwhich_t which, id_t id, int policy, int domain)
|
|
||||||
{
|
|
||||||
domainset_t mask;
|
|
||||||
int p;
|
|
||||||
|
|
||||||
DOMAINSET_ZERO(&mask);
|
|
||||||
if (policy == DOMAINSET_POLICY_PREFER)
|
|
||||||
DOMAINSET_SET(domain, &mask);
|
|
||||||
else if (cpuset_getdomain(CPU_LEVEL_ROOT, CPU_WHICH_PID, -1,
|
|
||||||
sizeof(mask), &mask, &p) != 0)
|
|
||||||
err(EXIT_FAILURE, "getdomain");
|
|
||||||
return cpuset_setdomain(CPU_LEVEL_WHICH, which, id, sizeof(mask),
|
|
||||||
&mask, policy);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
lwpid_t tid;
|
|
||||||
pid_t pid;
|
|
||||||
cpuwhich_t which;
|
|
||||||
id_t id;
|
|
||||||
int error;
|
|
||||||
int is_set, is_get;
|
|
||||||
int mem_policy_set;
|
|
||||||
int ch;
|
|
||||||
int cpu_domain;
|
|
||||||
int policy;
|
|
||||||
int domain;
|
|
||||||
|
|
||||||
id = -1;
|
|
||||||
which = -1;
|
|
||||||
is_set = 0;
|
|
||||||
is_get = 0;
|
|
||||||
mem_policy_set = 0;
|
|
||||||
tid = -1;
|
|
||||||
pid = -1;
|
|
||||||
cpu_domain = -1;
|
|
||||||
domain = -1;
|
|
||||||
policy = DOMAINSET_POLICY_INVALID;
|
|
||||||
|
|
||||||
while ((ch = getopt_long(argc, argv, "c:gl:m:p:st:", longopts,
|
|
||||||
NULL)) != -1) {
|
|
||||||
switch (ch) {
|
|
||||||
case 'c':
|
|
||||||
cpu_domain = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 'g':
|
|
||||||
is_get = 1;
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
if (parse_policy(&policy, optarg) != 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Could not parse policy: '%s'\n", optarg);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
mem_policy_set = 1;
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
domain = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
pid = atoi(optarg);
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
is_set = 1;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
tid = atoi(optarg);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
/* Handle the user wishing to run a command */
|
|
||||||
if (argc) {
|
|
||||||
/* Ensure that a policy was set */
|
|
||||||
if (mem_policy_set == 0) {
|
|
||||||
fprintf(stderr, "Error: no policy given\n");
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set current memory process policy, will be inherited */
|
|
||||||
if (numa_setaffinity(CPU_WHICH_PID, -1, policy, domain) != 0)
|
|
||||||
err(1, "numa_setaffinity");
|
|
||||||
|
|
||||||
/* If a CPU domain policy was given, include that too */
|
|
||||||
if (cpu_domain != -1)
|
|
||||||
(void) set_numa_domain_cpuaffinity(cpu_domain,
|
|
||||||
CPU_WHICH_PID, -1);
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
execvp(*argv, argv);
|
|
||||||
err(errno == ENOENT ? 127 : 126, "%s", *argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Figure out which */
|
|
||||||
if (tid != -1) {
|
|
||||||
which = CPU_WHICH_TID;
|
|
||||||
id = tid;
|
|
||||||
} else if (pid != -1) {
|
|
||||||
which = CPU_WHICH_PID;
|
|
||||||
id = pid;
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Error: one of tid or pid must be given\n");
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sanity checks */
|
|
||||||
if (is_set && is_get) {
|
|
||||||
fprintf(stderr, "Error: can't set both 'set' and 'get'\n");
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_set && ! mem_policy_set) {
|
|
||||||
fprintf(stderr, "Error: --set given, but no policy\n");
|
|
||||||
usage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If it's get, then get the policy and return */
|
|
||||||
if (is_get) {
|
|
||||||
domainset_t mask;
|
|
||||||
|
|
||||||
error = cpuset_getdomain(CPU_LEVEL_WHICH, which, id,
|
|
||||||
sizeof(mask), &mask, &policy);
|
|
||||||
if (error != 0)
|
|
||||||
err(1, "cpuset_getdomain");
|
|
||||||
printf(" Policy: %s; domain: ",
|
|
||||||
policy_to_str(policy));
|
|
||||||
domain_print(&mask);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assume it's set */
|
|
||||||
|
|
||||||
/* Syscall */
|
|
||||||
error = numa_setaffinity(which, id, policy, domain);
|
|
||||||
if (error != 0)
|
|
||||||
err(1, "numa_setaffinity");
|
|
||||||
|
|
||||||
/* If a CPU domain policy was given, include that too */
|
|
||||||
if (cpu_domain != -1)
|
|
||||||
(void) set_numa_domain_cpuaffinity(cpu_domain, which, id);
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user