Index: sys/kern/kern_cpuset.c =================================================================== --- sys/kern/kern_cpuset.c +++ sys/kern/kern_cpuset.c @@ -56,6 +56,10 @@ #include #include +#include +#include +#include +#include #ifdef DDB #include @@ -113,6 +117,7 @@ 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 @@ return (0); } case CPU_WHICH_IRQ: + case CPU_WHICH_DOMAIN: return (0); default: return (EINVAL); @@ -810,7 +816,8 @@ /* - * 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_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 @@ case CPU_WHICH_JAIL: break; case CPU_WHICH_IRQ: + case CPU_WHICH_DOMAIN: return (EINVAL); } switch (uap->level) { @@ -1073,6 +1085,7 @@ case CPU_WHICH_JAIL: break; case CPU_WHICH_IRQ: + case CPU_WHICH_DOMAIN: error = EINVAL; goto out; } @@ -1104,6 +1117,12 @@ 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 @@ case CPU_WHICH_JAIL: break; case CPU_WHICH_IRQ: + case CPU_WHICH_DOMAIN: error = EINVAL; goto out; } Index: sys/sys/cpuset.h =================================================================== --- sys/sys/cpuset.h +++ sys/sys/cpuset.h @@ -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. Index: sys/sys/smp.h =================================================================== --- sys/sys/smp.h +++ sys/sys/smp.h @@ -85,6 +85,7 @@ 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 Index: sys/x86/acpica/srat.c =================================================================== --- sys/x86/acpica/srat.c +++ sys/x86/acpica/srat.c @@ -342,7 +342,7 @@ } /* - * Setup per-CPU ACPI IDs. + * Setup per-CPU domain IDs. */ static void srat_set_cpus(void *dummy) @@ -363,6 +363,7 @@ 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); Index: usr.bin/cpuset/cpuset.1 =================================================================== --- usr.bin/cpuset/cpuset.1 +++ usr.bin/cpuset/cpuset.1 @@ -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 @@ .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 @@ .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 Index: usr.bin/cpuset/cpuset.c =================================================================== --- usr.bin/cpuset/cpuset.c +++ usr.bin/cpuset/cpuset.c @@ -48,6 +48,7 @@ static int Cflag; static int cflag; +static int dflag; static int gflag; static int iflag; static int jflag; @@ -161,7 +162,8 @@ 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 @@ 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 @@ id = pid = atoi(optarg); break; case 'r': - if (cflag) - usage(); level = CPU_LEVEL_ROOT; rflag = 1; break; @@ -268,7 +271,7 @@ 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 @@ 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 @@ /* * 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 @@ 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); }