allow most commands to specify more than one cpu. now you can online or

offline (or identify, or intr/nointr) a list of cpus all together.
This commit is contained in:
mrg 2015-11-16 03:34:50 +00:00
parent f94c9137cf
commit d94f57291f
2 changed files with 78 additions and 64 deletions

View File

@ -1,6 +1,6 @@
.\" $NetBSD: cpuctl.8,v 1.14 2014/11/20 13:16:05 wiz Exp $
.\" $NetBSD: cpuctl.8,v 1.15 2015/11/16 03:34:50 mrg Exp $
.\"
.\" Copyright (c) 2007, 2008, 2012 The NetBSD Foundation, Inc.
.\" Copyright (c) 2007, 2008, 2012, 2015 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd November 20, 2014
.Dd November 15, 2015
.Dt CPUCTL 8
.Os
.Sh NAME
@ -47,44 +47,48 @@ The first argument,
.Ar command ,
specifies the action to take.
Valid commands are:
.Bl -tag -width XofflineXcpunoX
.It identify Ar cpu
.Bl -tag -width offline
.It identify Ar cpu Op Ar cpu ...
Output information on the specified CPU's features and capabilities.
Not available on all architectures.
.It list
For each CPU in the system, display the current state and time of the last
state change.
.It offline Ar cpuno
Set the specified CPU off line.
.It offline Ar cpu Op Ar cpu ...
Set the specified CPUs off line.
.Pp
Unbound LWPs (lightweight processes) will not be executed on the CPU
Unbound LWPs (lightweight processes) will not be executed on the CPUs
while it is off line.
Bound LWPs will continue to be executed on the CPU, and device interrupts
routed to the CPU will continue to be handled.
Bound LWPs will continue to be executed on the CPUs, and device interrupts
routed to the CPUs will continue to be handled.
A future release of the system may allow device interrupts to be re-routed
away from individual CPUs.
.Pp
At least one CPU in the system must remain on line.
.It online Ar cpuno
Set the specified CPU on line, making it available to run unbound LWPs.
.It online Ar cpu Op Ar cpu ...
Set the specified CPUs on line, making it available to run unbound LWPs.
.It ucode Xo
.Op Ar cpuno
.Op Ar cpu
.Op Ar file
.Xc
This applies the microcode patch to CPUs.
If
.Ar cpuno
.Ar cpu
is not specified or \-1, all CPUs are updated.
If
.Ar cpuno
.Ar cpu
is \-2, the current CPUs are updated.
The default filename is used if no filename is specified.
The
.Cm identify
command prints the installed version on that CPU.
command prints the installed version on the specified CPUs.
On success the
.Cm identify
command show different ucode versions before and after this command.
.It intr Ar cpu Op Ar cpu ...
Enable interrupts for the specified CPUs if supported.
.It nointr Ar cpu Op Ar cpu ...
Disable interrupts for the specified CPUs if supported.
.El
.Pp
Valid flags are:

View File

@ -1,7 +1,7 @@
/* $NetBSD: cpuctl.c,v 1.27 2015/11/16 02:04:32 mrg Exp $ */
/* $NetBSD: cpuctl.c,v 1.28 2015/11/16 03:34:50 mrg Exp $ */
/*-
* Copyright (c) 2007, 2008, 2009, 2012 The NetBSD Foundation, Inc.
* Copyright (c) 2007, 2008, 2009, 2012, 2015 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@ -31,7 +31,7 @@
#ifndef lint
#include <sys/cdefs.h>
__RCSID("$NetBSD: cpuctl.c,v 1.27 2015/11/16 02:04:32 mrg Exp $");
__RCSID("$NetBSD: cpuctl.c,v 1.28 2015/11/16 03:34:50 mrg Exp $");
#endif /* not lint */
#include <sys/param.h>
@ -148,12 +148,14 @@ cpu_online(char **argv)
{
cpustate_t cs;
cs.cs_id = getcpuid(*argv);
if (ioctl(fd, IOC_CPU_GETSTATE, &cs) < 0)
err(EXIT_FAILURE, "IOC_CPU_GETSTATE");
cs.cs_online = true;
if (ioctl(fd, IOC_CPU_SETSTATE, &cs) < 0)
err(EXIT_FAILURE, "IOC_CPU_SETSTATE");
for (; *argv; argv++) {
cs.cs_id = getcpuid(*argv);
if (ioctl(fd, IOC_CPU_GETSTATE, &cs) < 0)
err(EXIT_FAILURE, "IOC_CPU_GETSTATE");
cs.cs_online = true;
if (ioctl(fd, IOC_CPU_SETSTATE, &cs) < 0)
err(EXIT_FAILURE, "IOC_CPU_SETSTATE");
}
}
static void
@ -161,12 +163,14 @@ cpu_offline(char **argv)
{
cpustate_t cs;
cs.cs_id = getcpuid(*argv);
if (ioctl(fd, IOC_CPU_GETSTATE, &cs) < 0)
err(EXIT_FAILURE, "IOC_CPU_GETSTATE");
cs.cs_online = false;
if (ioctl(fd, IOC_CPU_SETSTATE, &cs) < 0)
err(EXIT_FAILURE, "IOC_CPU_SETSTATE");
for (; *argv; argv++) {
cs.cs_id = getcpuid(*argv);
if (ioctl(fd, IOC_CPU_GETSTATE, &cs) < 0)
err(EXIT_FAILURE, "IOC_CPU_GETSTATE");
cs.cs_online = false;
if (ioctl(fd, IOC_CPU_SETSTATE, &cs) < 0)
err(EXIT_FAILURE, "IOC_CPU_SETSTATE");
}
}
static void
@ -174,12 +178,14 @@ cpu_intr(char **argv)
{
cpustate_t cs;
cs.cs_id = getcpuid(*argv);
if (ioctl(fd, IOC_CPU_GETSTATE, &cs) < 0)
err(EXIT_FAILURE, "IOC_CPU_GETSTATE");
cs.cs_intr = true;
if (ioctl(fd, IOC_CPU_SETSTATE, &cs) < 0)
err(EXIT_FAILURE, "IOC_CPU_SETSTATE");
for (; *argv; argv++) {
cs.cs_id = getcpuid(*argv);
if (ioctl(fd, IOC_CPU_GETSTATE, &cs) < 0)
err(EXIT_FAILURE, "IOC_CPU_GETSTATE");
cs.cs_intr = true;
if (ioctl(fd, IOC_CPU_SETSTATE, &cs) < 0)
err(EXIT_FAILURE, "IOC_CPU_SETSTATE");
}
}
static void
@ -187,16 +193,18 @@ cpu_nointr(char **argv)
{
cpustate_t cs;
cs.cs_id = getcpuid(*argv);
if (ioctl(fd, IOC_CPU_GETSTATE, &cs) < 0)
err(EXIT_FAILURE, "IOC_CPU_GETSTATE");
cs.cs_intr = false;
if (ioctl(fd, IOC_CPU_SETSTATE, &cs) < 0) {
if (errno == EOPNOTSUPP) {
warnx("interrupt control not supported on "
"this platform");
} else
err(EXIT_FAILURE, "IOC_CPU_SETSTATE");
for (; *argv; argv++) {
cs.cs_id = getcpuid(*argv);
if (ioctl(fd, IOC_CPU_GETSTATE, &cs) < 0)
err(EXIT_FAILURE, "IOC_CPU_GETSTATE");
cs.cs_intr = false;
if (ioctl(fd, IOC_CPU_SETSTATE, &cs) < 0) {
if (errno == EOPNOTSUPP) {
warnx("interrupt control not supported on "
"this platform");
} else
err(EXIT_FAILURE, "IOC_CPU_SETSTATE");
}
}
}
@ -255,27 +263,29 @@ cpu_identify(char **argv)
cpuset_t *cpuset;
np = sysconf(_SC_NPROCESSORS_CONF);
id = getcpuid(*argv);
snprintf(name, sizeof(name), "cpu%u", id);
for (; *argv; argv++) {
id = getcpuid(*argv);
snprintf(name, sizeof(name), "cpu%u", id);
if (np != 1) {
cpuset = cpuset_create();
if (cpuset == NULL)
err(EXIT_FAILURE, "cpuset_create");
cpuset_zero(cpuset);
cpuset_set(id, cpuset);
if (_sched_setaffinity(0, 0, cpuset_size(cpuset), cpuset) < 0) {
if (errno == EPERM) {
printf("Cannot bind to target CPU. Output "
"may not accurately describe the target.\n"
"Run as root to allow binding.\n\n");
} else {
err(EXIT_FAILURE, "_sched_setaffinity");
if (np != 1) {
cpuset = cpuset_create();
if (cpuset == NULL)
err(EXIT_FAILURE, "cpuset_create");
cpuset_zero(cpuset);
cpuset_set(id, cpuset);
if (_sched_setaffinity(0, 0, cpuset_size(cpuset), cpuset) < 0) {
if (errno == EPERM) {
printf("Cannot bind to target CPU. Output "
"may not accurately describe the target.\n"
"Run as root to allow binding.\n\n");
} else {
err(EXIT_FAILURE, "_sched_setaffinity");
}
}
cpuset_destroy(cpuset);
}
cpuset_destroy(cpuset);
identifycpu(fd, name);
}
identifycpu(fd, name);
}
static u_int