diff --git a/lib/libc/gen/sched_getaffinity.c b/lib/libc/gen/sched_getaffinity.c --- a/lib/libc/gen/sched_getaffinity.c +++ b/lib/libc/gen/sched_getaffinity.c @@ -35,7 +35,7 @@ { int error; - error = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, + error = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TIDPID, pid == 0 ? -1 : pid, cpusetsz, cpuset); if (error == -1 && errno == ERANGE) errno = EINVAL; diff --git a/lib/libc/gen/sched_setaffinity.c b/lib/libc/gen/sched_setaffinity.c --- a/lib/libc/gen/sched_setaffinity.c +++ b/lib/libc/gen/sched_setaffinity.c @@ -58,7 +58,7 @@ if (cpu > mp_maxid) CPU_CLR(cpu, &c); } - error = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, + error = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TIDPID, pid == 0 ? -1 : pid, sizeof(cpuset_t), &c); if (error == -1 && errno == EDEADLK) errno = EINVAL; diff --git a/lib/libc/sys/cpuset.2 b/lib/libc/sys/cpuset.2 --- a/lib/libc/sys/cpuset.2 +++ b/lib/libc/sys/cpuset.2 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 3, 2017 +.Dd January 28, 2023 .Dt CPUSET 2 .Os .Sh NAME @@ -100,6 +100,7 @@ .Bl -column CPU_WHICH_INTRHANDLER -offset indent .It Dv CPU_WHICH_TID Ta "id is lwpid_t (thread id)" .It Dv CPU_WHICH_PID Ta "id is pid_t (process id)" +.It Dv CPU_WHICH_TIDPID Ta "id is lwpid_t (thread id) or id is pid_t (process id)" .It Dv CPU_WHICH_JAIL Ta "id is jid (jail id)" .It Dv CPU_WHICH_CPUSET Ta "id is a cpusetid_t (cpuset id)" .It Dv CPU_WHICH_IRQ Ta "id is an irq number" @@ -115,6 +116,7 @@ of .Dv CPU_WHICH_TID , .Dv CPU_WHICH_PID , +.Dv CPU_WHICH_TIDPID , or .Dv CPU_WHICH_CPUSET to mean the current thread, process, or current thread's diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c --- a/sys/kern/kern_cpuset.c +++ b/sys/kern/kern_cpuset.c @@ -150,6 +150,8 @@ cpuset_t *cpuset_root; cpuset_t cpuset_domain[MAXMEMDOM]; +static int cpuset_which2(cpuwhich_t *, id_t, struct proc **, struct thread **, + struct cpuset **); static int domainset_valid(const struct domainset *, const struct domainset *); /* @@ -972,6 +974,20 @@ return (0); } +static int +cpuset_which2(cpuwhich_t *which, id_t id, struct proc **pp, struct thread **tdp, + struct cpuset **setp) +{ + + if (*which == CPU_WHICH_TIDPID) { + if (id == -1 || id > PID_MAX) + *which = CPU_WHICH_TID; + else + *which = CPU_WHICH_PID; + } + return (cpuset_which(*which, id, pp, tdp, setp)); +} + static int cpuset_testshadow(struct cpuset *set, const cpuset_t *mask, const struct domainset *domain) @@ -1739,7 +1755,11 @@ if (IN_CAPABILITY_MODE(td)) { if (level != CPU_LEVEL_WHICH) return (ECAPMODE); - if (which != CPU_WHICH_TID && which != CPU_WHICH_PID) + if (which != CPU_WHICH_TID && which != CPU_WHICH_PID && + which != CPU_WHICH_TIDPID) + return (ECAPMODE); + if (id != -1 && which == CPU_WHICH_TIDPID && + id != td->td_tid && id != td->td_proc->p_pid) return (ECAPMODE); if (id != -1 && !(which == CPU_WHICH_TID && id == td->td_tid) && @@ -1876,7 +1896,7 @@ if (level == CPU_LEVEL_WHICH && which != CPU_WHICH_CPUSET) return (EINVAL); - error = cpuset_which(which, id, &p, &ttd, &set); + error = cpuset_which2(&which, id, &p, &ttd, &set); if (error) return (error); switch (which) { @@ -1943,7 +1963,7 @@ error = cpuset_check_capabilities(td, level, which, id); if (error != 0) return (error); - error = cpuset_which(which, id, &p, &ttd, &set); + error = cpuset_which2(&which, id, &p, &ttd, &set); if (error != 0) return (error); switch (level) { @@ -2099,7 +2119,7 @@ switch (level) { case CPU_LEVEL_ROOT: case CPU_LEVEL_CPUSET: - error = cpuset_which(which, id, &p, &ttd, &set); + error = cpuset_which2(&which, id, &p, &ttd, &set); if (error) break; switch (which) { @@ -2135,6 +2155,13 @@ case CPU_WHICH_PID: error = cpuset_setproc(id, NULL, mask, NULL, false); break; + case CPU_WHICH_TIDPID: + if (id > PID_MAX || id == -1) + error = cpuset_setthread(id, mask); + else + error = cpuset_setproc(id, NULL, mask, NULL, + false); + break; case CPU_WHICH_CPUSET: case CPU_WHICH_JAIL: error = cpuset_which(which, id, &p, &ttd, &set); @@ -2243,7 +2270,7 @@ return (error); mask = malloc(domainsetsize, M_TEMP, M_WAITOK | M_ZERO); bzero(&outset, sizeof(outset)); - error = cpuset_which(which, id, &p, &ttd, &set); + error = cpuset_which2(&which, id, &p, &ttd, &set); if (error) goto out; switch (level) { @@ -2425,13 +2452,12 @@ */ if (domainset_empty_vm(&domain)) domainset_copy(domainset2, &domain); - + error = cpuset_which2(&which, id, &p, &ttd, &set); + if (error != 0) + goto out; switch (level) { case CPU_LEVEL_ROOT: case CPU_LEVEL_CPUSET: - error = cpuset_which(which, id, &p, &ttd, &set); - if (error) - break; switch (which) { case CPU_WHICH_TID: case CPU_WHICH_PID: @@ -2468,11 +2494,8 @@ break; case CPU_WHICH_CPUSET: case CPU_WHICH_JAIL: - error = cpuset_which(which, id, &p, &ttd, &set); - if (error == 0) { - error = cpuset_modify_domain(set, &domain); - cpuset_rel(set); - } + error = cpuset_modify_domain(set, &domain); + cpuset_rel(set); break; case CPU_WHICH_IRQ: case CPU_WHICH_INTRHANDLER: diff --git a/sys/sys/cpuset.h b/sys/sys/cpuset.h --- a/sys/sys/cpuset.h +++ b/sys/sys/cpuset.h @@ -109,6 +109,7 @@ #define CPU_WHICH_DOMAIN 6 /* Specifies a NUMA domain id. */ #define CPU_WHICH_INTRHANDLER 7 /* Specifies an irq # (not ithread). */ #define CPU_WHICH_ITHREAD 8 /* Specifies an irq's ithread. */ +#define CPU_WHICH_TIDPID 9 /* Specifies a process or thread id. */ /* * Reserved cpuset identifiers.