Create a cpuset mask for each NUMA domain that is available in the
kernel via the global cpuset_domain[] array. To export these to userland, add a CPU_WHICH_DOMAIN level that can be used to fetch the mask for a specific domain. Add a -d flag to cpuset(1) that can be used to fetch the mask for a given domain. Differential Revision: https://reviews.freebsd.org/D1232 Submitted by: jeff (kernel bits) Reviewed by: adrian, jeff
This commit is contained in:
parent
2303632301
commit
c0ae66888b
@ -56,6 +56,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/interrupt.h>
|
||||
|
||||
#include <vm/uma.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_page.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/vm_phys.h>
|
||||
|
||||
#ifdef DDB
|
||||
#include <ddb/ddb.h>
|
||||
@ -113,6 +117,7 @@ SYSCTL_INT(_kern_sched, OID_AUTO, cpusetsize, CTLFLAG_RD,
|
||||
SYSCTL_NULL_INT_PTR, sizeof(cpuset_t), "sizeof(cpuset_t)");
|
||||
|
||||
cpuset_t *cpuset_root;
|
||||
cpuset_t cpuset_domain[MAXMEMDOM];
|
||||
|
||||
/*
|
||||
* Acquire a reference to a cpuset, all pointers must be tracked with refs.
|
||||
@ -457,6 +462,7 @@ cpuset_which(cpuwhich_t which, id_t id, struct proc **pp, struct thread **tdp,
|
||||
return (0);
|
||||
}
|
||||
case CPU_WHICH_IRQ:
|
||||
case CPU_WHICH_DOMAIN:
|
||||
return (0);
|
||||
default:
|
||||
return (EINVAL);
|
||||
@ -810,7 +816,8 @@ cpuset_setithread(lwpid_t id, int cpu)
|
||||
|
||||
|
||||
/*
|
||||
* Creates the cpuset for thread0. We make two sets:
|
||||
* Creates system-wide cpusets and the cpuset for thread0 including two
|
||||
* sets:
|
||||
*
|
||||
* 0 - The root set which should represent all valid processors in the
|
||||
* system. It is initially created with a mask of all processors
|
||||
@ -856,6 +863,10 @@ cpuset_thread0(void)
|
||||
*/
|
||||
cpuset_unr = new_unrhdr(2, INT_MAX, NULL);
|
||||
|
||||
/* MD Code is responsible for initializing sets if vm_ndomains > 1. */
|
||||
if (vm_ndomains == 1)
|
||||
CPU_COPY(&all_cpus, &cpuset_domain[0]);
|
||||
|
||||
return (set);
|
||||
}
|
||||
|
||||
@ -1010,6 +1021,7 @@ sys_cpuset_getid(struct thread *td, struct cpuset_getid_args *uap)
|
||||
case CPU_WHICH_JAIL:
|
||||
break;
|
||||
case CPU_WHICH_IRQ:
|
||||
case CPU_WHICH_DOMAIN:
|
||||
return (EINVAL);
|
||||
}
|
||||
switch (uap->level) {
|
||||
@ -1073,6 +1085,7 @@ sys_cpuset_getaffinity(struct thread *td, struct cpuset_getaffinity_args *uap)
|
||||
case CPU_WHICH_JAIL:
|
||||
break;
|
||||
case CPU_WHICH_IRQ:
|
||||
case CPU_WHICH_DOMAIN:
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@ -1104,6 +1117,12 @@ sys_cpuset_getaffinity(struct thread *td, struct cpuset_getaffinity_args *uap)
|
||||
case CPU_WHICH_IRQ:
|
||||
error = intr_getaffinity(uap->id, mask);
|
||||
break;
|
||||
case CPU_WHICH_DOMAIN:
|
||||
if (uap->id >= vm_ndomains)
|
||||
error = ESRCH;
|
||||
else
|
||||
CPU_COPY(&cpuset_domain[uap->id], mask);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1182,6 +1201,7 @@ sys_cpuset_setaffinity(struct thread *td, struct cpuset_setaffinity_args *uap)
|
||||
case CPU_WHICH_JAIL:
|
||||
break;
|
||||
case CPU_WHICH_IRQ:
|
||||
case CPU_WHICH_DOMAIN:
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
@ -76,6 +76,7 @@
|
||||
#define CPU_WHICH_CPUSET 3 /* Specifies a set id. */
|
||||
#define CPU_WHICH_IRQ 4 /* Specifies an irq #. */
|
||||
#define CPU_WHICH_JAIL 5 /* Specifies a jail id. */
|
||||
#define CPU_WHICH_DOMAIN 6 /* Specifies a NUMA domain id. */
|
||||
|
||||
/*
|
||||
* Reserved cpuset identifiers.
|
||||
|
@ -85,6 +85,7 @@ extern int mp_ncpus;
|
||||
extern volatile int smp_started;
|
||||
|
||||
extern cpuset_t all_cpus;
|
||||
extern cpuset_t cpuset_domain[MAXMEMDOM]; /* CPUs in each NUMA domain. */
|
||||
|
||||
/*
|
||||
* Macro allowing us to determine whether a CPU is absent at any given
|
||||
|
@ -342,7 +342,7 @@ srat_walk_table(acpi_subtable_handler *handler, void *arg)
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup per-CPU ACPI IDs.
|
||||
* Setup per-CPU domain IDs.
|
||||
*/
|
||||
static void
|
||||
srat_set_cpus(void *dummy)
|
||||
@ -363,6 +363,7 @@ srat_set_cpus(void *dummy)
|
||||
panic("SRAT: CPU with APIC ID %u is not known",
|
||||
pc->pc_apic_id);
|
||||
pc->pc_domain = cpu->domain;
|
||||
CPU_SET(i, &cpuset_domain[cpu->domain]);
|
||||
if (bootverbose)
|
||||
printf("SRAT: CPU %u has memory domain %d\n", i,
|
||||
cpu->domain);
|
||||
|
@ -46,12 +46,13 @@
|
||||
.Fl C
|
||||
.Fl p Ar pid
|
||||
.Nm
|
||||
.Op Fl cr
|
||||
.Op Fl c
|
||||
.Op Fl l Ar cpu-list
|
||||
.Op Fl j Ar jailid | Fl p Ar pid | Fl t Ar tid | Fl s Ar setid | Fl x Ar irq
|
||||
.Nm
|
||||
.Op Fl cgir
|
||||
.Op Fl j Ar jailid | Fl p Ar pid | Fl t Ar tid | Fl s Ar setid | Fl x Ar irq
|
||||
.Fl g
|
||||
.Op Fl cir
|
||||
.Op Fl d Ar domain | j Ar jailid | Fl p Ar pid | Fl t Ar tid | Fl s Ar setid | Fl x Ar irq
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
@ -62,7 +63,7 @@ about processor binding, sets, and available processors in the system.
|
||||
.Nm
|
||||
requires a target to modify or query.
|
||||
The target may be specified as a command, process id, thread id, a
|
||||
cpuset id, an irq or a jail id.
|
||||
cpuset id, an irq, a jail id, or a NUMA domain.
|
||||
Using
|
||||
.Fl g
|
||||
the target's set id or mask may be queried.
|
||||
@ -108,6 +109,8 @@ Create a new cpuset and assign the target process to that set.
|
||||
.It Fl c
|
||||
The requested operation should reference the cpuset available via the
|
||||
target specifier.
|
||||
.It Fl d Ar domain
|
||||
Specifies a NUMA domain id as the target of the operation.
|
||||
.It Fl g
|
||||
Causes
|
||||
.Nm
|
||||
|
@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
static int Cflag;
|
||||
static int cflag;
|
||||
static int dflag;
|
||||
static int gflag;
|
||||
static int iflag;
|
||||
static int jflag;
|
||||
@ -161,7 +162,8 @@ printset(cpuset_t *mask)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static const char *whichnames[] = { NULL, "tid", "pid", "cpuset", "irq", "jail" };
|
||||
static const char *whichnames[] = { NULL, "tid", "pid", "cpuset", "irq", "jail",
|
||||
"domain" };
|
||||
static const char *levelnames[] = { NULL, " root", " cpuset", "" };
|
||||
|
||||
static void
|
||||
@ -206,17 +208,20 @@ main(int argc, char *argv[])
|
||||
level = CPU_LEVEL_WHICH;
|
||||
which = CPU_WHICH_PID;
|
||||
id = pid = tid = setid = -1;
|
||||
while ((ch = getopt(argc, argv, "Ccgij:l:p:rs:t:x:")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "Ccd:gij:l:p:rs:t:x:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'C':
|
||||
Cflag = 1;
|
||||
break;
|
||||
case 'c':
|
||||
if (rflag)
|
||||
usage();
|
||||
cflag = 1;
|
||||
level = CPU_LEVEL_CPUSET;
|
||||
break;
|
||||
case 'd':
|
||||
dflag = 1;
|
||||
which = CPU_WHICH_DOMAIN;
|
||||
id = atoi(optarg);
|
||||
break;
|
||||
case 'g':
|
||||
gflag = 1;
|
||||
break;
|
||||
@ -238,8 +243,6 @@ main(int argc, char *argv[])
|
||||
id = pid = atoi(optarg);
|
||||
break;
|
||||
case 'r':
|
||||
if (cflag)
|
||||
usage();
|
||||
level = CPU_LEVEL_ROOT;
|
||||
rflag = 1;
|
||||
break;
|
||||
@ -268,7 +271,7 @@ main(int argc, char *argv[])
|
||||
if (argc || Cflag || lflag)
|
||||
usage();
|
||||
/* Only one identity specifier. */
|
||||
if (jflag + xflag + sflag + pflag + tflag > 1)
|
||||
if (dflag + jflag + xflag + sflag + pflag + tflag > 1)
|
||||
usage();
|
||||
if (iflag)
|
||||
printsetid();
|
||||
@ -276,13 +279,13 @@ main(int argc, char *argv[])
|
||||
printaffinity();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
if (iflag)
|
||||
if (dflag || iflag || rflag)
|
||||
usage();
|
||||
/*
|
||||
* The user wants to run a command with a set and possibly cpumask.
|
||||
*/
|
||||
if (argc) {
|
||||
if (Cflag | pflag | rflag | tflag | xflag | jflag)
|
||||
if (Cflag || pflag || tflag || xflag || jflag)
|
||||
usage();
|
||||
if (sflag) {
|
||||
if (cpuset_setid(CPU_WHICH_PID, -1, setid))
|
||||
@ -303,9 +306,9 @@ main(int argc, char *argv[])
|
||||
/*
|
||||
* We're modifying something that presently exists.
|
||||
*/
|
||||
if (Cflag && (sflag || rflag || !pflag || tflag || xflag || jflag))
|
||||
if (Cflag && (jflag || !pflag || sflag || tflag || xflag))
|
||||
usage();
|
||||
if (!lflag && (cflag || rflag))
|
||||
if (!lflag && cflag)
|
||||
usage();
|
||||
if (!lflag && !(Cflag || sflag))
|
||||
usage();
|
||||
@ -354,8 +357,9 @@ usage(void)
|
||||
fprintf(stderr,
|
||||
" cpuset [-c] [-l cpu-list] -C -p pid\n");
|
||||
fprintf(stderr,
|
||||
" cpuset [-cr] [-l cpu-list] [-j jailid | -p pid | -t tid | -s setid | -x irq]\n");
|
||||
" cpuset [-c] [-l cpu-list] [-j jailid | -p pid | -t tid | -s setid | -x irq]\n");
|
||||
fprintf(stderr,
|
||||
" cpuset [-cgir] [-j jailid | -p pid | -t tid | -s setid | -x irq]\n");
|
||||
" cpuset -g [-cir] [-d domain | -j jailid | -p pid | -t tid | -s setid |\n"
|
||||
" -x irq]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user