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
@ -38,6 +38,12 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# 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.
|
||||
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
|
||||
|
@ -258,7 +258,6 @@ MAN+= abort2.2 \
|
||||
nanosleep.2 \
|
||||
nfssvc.2 \
|
||||
ntp_adjtime.2 \
|
||||
numa_getaffinity.2 \
|
||||
open.2 \
|
||||
pathconf.2 \
|
||||
pdfork.2 \
|
||||
@ -430,7 +429,6 @@ MLINKS+=mount.2 nmount.2 \
|
||||
MLINKS+=mq_receive.2 mq_timedreceive.2
|
||||
MLINKS+=mq_send.2 mq_timedsend.2
|
||||
MLINKS+=ntp_adjtime.2 ntp_gettime.2
|
||||
MLINKS+=numa_getaffinity.2 numa_setaffinity.2
|
||||
MLINKS+=open.2 openat.2
|
||||
MLINKS+=pathconf.2 fpathconf.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_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$
|
||||
.\"
|
||||
.Dd May 10, 2015
|
||||
.Dd July 10, 2018
|
||||
.Dt NUMA 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -34,7 +34,6 @@
|
||||
.Cd options SMP
|
||||
.Cd options MAXMEMDOM=16
|
||||
.Pp
|
||||
.In sys/numa.h
|
||||
.In sys/cpuset.h
|
||||
.In sys/bus.h
|
||||
.Sh DESCRIPTION
|
||||
@ -51,20 +50,21 @@ that is connected to one of the other processors.
|
||||
.Pp
|
||||
.Nm
|
||||
is enabled when the
|
||||
.Cd MAXMEMDOM
|
||||
.Cd NUMA
|
||||
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
|
||||
Thread and process
|
||||
.Nm
|
||||
policies are controlled with the
|
||||
.Xr numa_setaffinity 2
|
||||
.Xr cpuset_getdomain 2
|
||||
and
|
||||
.Xr numa_getaffinity 2
|
||||
.Xr cpuset_setdomain 2
|
||||
syscalls.
|
||||
.Pp
|
||||
The
|
||||
.Xr numactl 1
|
||||
.Xr cpuset 1
|
||||
tool is available for starting processes with a non-default
|
||||
policy, or to change the policy of an existing thread or process.
|
||||
.Pp
|
||||
@ -83,15 +83,6 @@ MIB variables:
|
||||
.It Va vm.ndomains
|
||||
The number of VM domains which have been detected.
|
||||
.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
|
||||
A table indicating the relative cost of each VM domain to each other.
|
||||
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.
|
||||
Thus, VM domain information (for example, the domain identifier) is not
|
||||
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.
|
||||
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
|
||||
.Xr numactl 1 ,
|
||||
.Xr numa_getaffinity 2 ,
|
||||
.Xr numa_setaffinity 2 ,
|
||||
.Xr cpuset 1 ,
|
||||
.Xr cpuset_getaffinity 2 ,
|
||||
.Xr cpuset_setaffinity 2 ,
|
||||
.Xr bus_get_domain 9
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
@ -156,13 +122,15 @@ The
|
||||
.Xr numa_getaffinity 2
|
||||
and
|
||||
.Xr numa_setaffinity 2
|
||||
syscalls first appeared in
|
||||
.Fx 11.0 .
|
||||
.Pp
|
||||
The
|
||||
syscalls and the
|
||||
.Xr numactl 1
|
||||
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
|
||||
This manual page written by
|
||||
.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 \
|
||||
nice \
|
||||
nl \
|
||||
numactl \
|
||||
nohup \
|
||||
opieinfo \
|
||||
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