Page MenuHomeFreeBSD

D34849.id105675.diff
No OneTemporary

D34849.id105675.diff

Index: lib/libc/gen/sched_getaffinity.c
===================================================================
--- lib/libc/gen/sched_getaffinity.c
+++ lib/libc/gen/sched_getaffinity.c
@@ -33,24 +33,15 @@
int
sched_getaffinity(pid_t pid, size_t cpusetsz, cpuset_t *cpuset)
{
- /*
- * Be more Linux-compatible:
- * - return EINVAL in passed size is less than size of cpuset_t
- * in advance, instead of ERANGE from the syscall
- * - if passed size is larger than the size of cpuset_t, be
- * permissive by claming it back to sizeof(cpuset_t) and
- * zeroing the rest.
- */
- if (cpusetsz < sizeof(cpuset_t)) {
+ int error;
+
+ error = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ pid == 0 ? -1 : pid, cpusetsz, cpuset);
+ if (error == -1 && errno == ERANGE)
errno = EINVAL;
- return (-1);
- }
- if (cpusetsz > sizeof(cpuset_t)) {
- memset((char *)cpuset + sizeof(cpuset_t), 0,
- cpusetsz - sizeof(cpuset_t));
- cpusetsz = sizeof(cpuset_t);
- }
+ if (error == 0)
+ return (cpusetsz < sizeof(cpuset_t) ? cpusetsz :
+ sizeof(cpuset_t));
- return (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
- pid == 0 ? -1 : pid, cpusetsz, cpuset));
+ return (error);
}
Index: lib/libc/gen/sched_setaffinity.c
===================================================================
--- lib/libc/gen/sched_setaffinity.c
+++ lib/libc/gen/sched_setaffinity.c
@@ -26,22 +26,38 @@
* SUCH DAMAGE.
*/
+#include <sys/param.h>
+#include <sys/sysctl.h>
#include <errno.h>
#include <sched.h>
#include <string.h>
+#include <unistd.h>
int
sched_setaffinity(pid_t pid, size_t cpusetsz, const cpuset_t *cpuset)
{
+ static int mp_maxid;
cpuset_t c;
- int error;
+ int error, sz, lbs, cpu;
+ size_t len;
- if (cpusetsz > sizeof(cpuset_t)) {
- errno = EINVAL;
- return (-1);
- } else {
- memset(&c, 0, sizeof(c));
- memcpy(&c, cpuset, cpusetsz);
+ sz = cpusetsz > sizeof(cpuset_t) ? sizeof(cpuset_t) : cpusetsz;
+ memset(&c, 0, sizeof(c));
+ memcpy(&c, cpuset, sz);
+
+ /* Linux ignores high bits */
+ if (mp_maxid == 0) {
+ len = sizeof(mp_maxid);
+ error = sysctlbyname("kern.smp.maxid", &mp_maxid, &len,
+ NULL, 0);
+ if (error == -1)
+ return (error);
+ }
+ lbs = CPU_FLS(&c) - 1;
+ if (lbs > mp_maxid) {
+ CPU_FOREACH_ISSET(cpu, &c)
+ if (cpu > mp_maxid)
+ CPU_CLR(cpu, &c);
}
error = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
pid == 0 ? -1 : pid, sizeof(cpuset_t), &c);
Index: lib/libc/sys/cpuset_getaffinity.2
===================================================================
--- lib/libc/sys/cpuset_getaffinity.2
+++ lib/libc/sys/cpuset_getaffinity.2
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 23, 2017
+.Dd April 27, 2022
.Dt CPUSET_GETAFFINITY 2
.Os
.Sh NAME
@@ -71,14 +71,19 @@
are composed using the
.Dv CPU_SET
macros.
-The kernel tolerates large sets as long as all CPUs specified
-in the set exist.
-Sets smaller than the kernel uses generate an error on calls to
+If the user-supplied mask is not large enough to fit all of the matching CPUs,
.Fn cpuset_getaffinity
-even if the result set would fit within the user supplied set.
+fails with
+.Er ERANGE .
Calls to
.Fn cpuset_setaffinity
-tolerate small sets with no restrictions.
+tolerate masks of any size with no restrictions.
+The kernel uses the meaningful part of the mask, where the upper bound is
+the maximum CPU id present in the system.
+If bits for non-existing CPUs are set, calls to
+.Fn cpuset_setaffinity
+fails with
+.Er EINVAL .
.Pp
The supplied mask should have a size of
.Fa setsize
@@ -144,7 +149,7 @@
.It Bq Er ERANGE
The
.Fa cpusetsize
-was either preposterously large or smaller than the kernel set size.
+was smaller than needed to fit all of the matching CPUs.
.It Bq Er EPERM
The calling process did not have the credentials required to complete the
operation.
Index: share/man/man3/pthread_attr_affinity_np.3
===================================================================
--- share/man/man3/pthread_attr_affinity_np.3
+++ share/man/man3/pthread_attr_affinity_np.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 12, 2021
+.Dd April 27, 2022
.Dt PTHREAD_ATTR_AFFINITY_NP 3
.Os
.Sh NAME
@@ -51,14 +51,19 @@
are composed using the
.Dv CPU_SET
macros.
-The kernel tolerates large sets as long as all CPUs specified
-in the set exist.
-Sets smaller than the kernel uses generate an error on calls to
-.Fn pthread_attr_getaffinity_np
-even if the result set would fit within the user supplied set.
+If the user-supplied mask is not large enough to fit all of the matching CPUs,
+.Fn cpuset_getaffinity
+fails with
+.Er ERANGE .
Calls to
-.Fn pthread_attr_setaffinity_np
-tolerate small sets with no restrictions.
+.Fn cpuset_setaffinity
+tolerate masks of any size with no restrictions.
+The kernel uses the meaningful part of the mask, where the upper bound is
+the maximum CPU id present in the system.
+If bits for non-existing CPUs are set, calls to
+.Fn cpuset_setaffinity
+fails with
+.Er EINVAL .
.Pp
The supplied mask should have a size of
.Fa cpusetsize
@@ -119,10 +124,6 @@
The
.Fa cpusetp
specified a CPU that was outside the set supported by the kernel.
-.It Bq Er ERANGE
-The
-.Fa cpusetsize
-is too small.
.It Bq Er ENOMEM
Insufficient memory exists to store the cpuset mask.
.El
Index: sys/compat/freebsd32/freebsd32_misc.c
===================================================================
--- sys/compat/freebsd32/freebsd32_misc.c
+++ sys/compat/freebsd32/freebsd32_misc.c
@@ -3324,7 +3324,7 @@
struct freebsd32_cpuset_setaffinity_args *uap)
{
- return (kern_cpuset_setaffinity(td, uap->level, uap->which,
+ return (user_cpuset_setaffinity(td, uap->level, uap->which,
PAIR32TO64(id_t,uap->id), uap->cpusetsize, uap->mask));
}
Index: sys/compat/linux/linux_misc.c
===================================================================
--- sys/compat/linux/linux_misc.c
+++ sys/compat/linux/linux_misc.c
@@ -61,6 +61,7 @@
#include <sys/sched.h>
#include <sys/sdt.h>
#include <sys/signalvar.h>
+#include <sys/smp.h>
#include <sys/stat.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
@@ -2256,22 +2257,22 @@
linux_sched_getaffinity(struct thread *td,
struct linux_sched_getaffinity_args *args)
{
- int error;
struct thread *tdt;
-
- if (args->len < sizeof(cpuset_t))
- return (EINVAL);
+ int error;
+ id_t tid;
tdt = linux_tdfind(td, args->pid, -1);
if (tdt == NULL)
return (ESRCH);
-
+ tid = tdt->td_tid;
PROC_UNLOCK(tdt->td_proc);
error = kern_cpuset_getaffinity(td, CPU_LEVEL_WHICH, CPU_WHICH_TID,
- tdt->td_tid, sizeof(cpuset_t), (cpuset_t *)args->user_mask_ptr);
+ tid, args->len, (cpuset_t *)args->user_mask_ptr);
+ if (error == ERANGE)
+ error = EINVAL;
if (error == 0)
- td->td_retval[0] = sizeof(cpuset_t);
+ td->td_retval[0] = min(args->len, sizeof(cpuset_t));
return (error);
}
@@ -2284,18 +2285,34 @@
struct linux_sched_setaffinity_args *args)
{
struct thread *tdt;
-
- if (args->len < sizeof(cpuset_t))
- return (EINVAL);
+ cpuset_t *mask;
+ int cpu, error;
+ size_t len;
+ id_t tid;
tdt = linux_tdfind(td, args->pid, -1);
if (tdt == NULL)
return (ESRCH);
-
+ tid = tdt->td_tid;
PROC_UNLOCK(tdt->td_proc);
- return (kern_cpuset_setaffinity(td, CPU_LEVEL_WHICH, CPU_WHICH_TID,
- tdt->td_tid, sizeof(cpuset_t), (cpuset_t *) args->user_mask_ptr));
+ len = min(args->len, sizeof(cpuset_t));
+ mask = malloc(sizeof(cpuset_t), M_TEMP, M_WAITOK | M_ZERO);;
+ error = copyin(args->user_mask_ptr, mask, len);
+ if (error != 0)
+ goto out;
+ /* Linux ignore high bits */
+ CPU_FOREACH_ISSET(cpu, mask)
+ if (cpu > mp_maxid)
+ CPU_CLR(cpu, mask);
+
+ error = kern_cpuset_setaffinity(td, CPU_LEVEL_WHICH, CPU_WHICH_TID,
+ tid, mask);
+ if (error == EDEADLK)
+ error = EINVAL;
+out:
+ free(mask, M_TEMP);
+ return (error);
}
struct linux_rlimit64 {
Index: sys/kern/kern_cpuset.c
===================================================================
--- sys/kern/kern_cpuset.c
+++ sys/kern/kern_cpuset.c
@@ -1896,13 +1896,10 @@
int error;
size_t size;
- if (cpusetsize < sizeof(cpuset_t) || cpusetsize > CPU_MAXSIZE / NBBY)
- return (ERANGE);
error = cpuset_check_capabilities(td, level, which, id);
if (error != 0)
return (error);
- size = cpusetsize;
- mask = malloc(size, M_TEMP, M_WAITOK | M_ZERO);
+ mask = malloc(sizeof(cpuset_t), M_TEMP, M_WAITOK | M_ZERO);
error = cpuset_which(which, id, &p, &ttd, &set);
if (error)
goto out;
@@ -1972,8 +1969,33 @@
cpuset_rel(set);
if (p)
PROC_UNLOCK(p);
- if (error == 0)
+ if (error == 0) {
+ if (cpusetsize < howmany(CPU_FLS(mask), NBBY)) {
+ error = ERANGE;
+ goto out;
+ }
+ size = min(cpusetsize, sizeof(cpuset_t));
error = copyout(mask, maskp, size);
+ if (error != 0)
+ goto out;
+ if (cpusetsize > size) {
+ char *end;
+ char *cp;
+ int rv;
+
+ end = cp = (char *)&maskp->__bits;
+ end += cpusetsize;
+ cp += size;
+ while (cp != end) {
+ rv = subyte(cp, 0);
+ if (rv == -1) {
+ error = EFAULT;
+ goto out;
+ }
+ cp++;
+ }
+ }
+ }
out:
free(mask, M_TEMP);
return (error);
@@ -1992,50 +2014,25 @@
sys_cpuset_setaffinity(struct thread *td, struct cpuset_setaffinity_args *uap)
{
- return (kern_cpuset_setaffinity(td, uap->level, uap->which,
+ return (user_cpuset_setaffinity(td, uap->level, uap->which,
uap->id, uap->cpusetsize, uap->mask));
}
int
kern_cpuset_setaffinity(struct thread *td, cpulevel_t level, cpuwhich_t which,
- id_t id, size_t cpusetsize, const cpuset_t *maskp)
+ id_t id, cpuset_t *mask)
{
struct cpuset *nset;
struct cpuset *set;
struct thread *ttd;
struct proc *p;
- cpuset_t *mask;
int error;
- if (cpusetsize < sizeof(cpuset_t) || cpusetsize > CPU_MAXSIZE / NBBY)
- return (ERANGE);
error = cpuset_check_capabilities(td, level, which, id);
if (error != 0)
return (error);
- mask = malloc(cpusetsize, M_TEMP, M_WAITOK | M_ZERO);
- error = copyin(maskp, mask, cpusetsize);
- if (error)
- goto out;
- /*
- * Verify that no high bits are set.
- */
- if (cpusetsize > sizeof(cpuset_t)) {
- char *end;
- char *cp;
-
- end = cp = (char *)&mask->__bits;
- end += cpusetsize;
- cp += sizeof(cpuset_t);
- while (cp != end)
- if (*cp++ != 0) {
- error = EINVAL;
- goto out;
- }
- }
- if (CPU_EMPTY(mask)) {
- error = EDEADLK;
- goto out;
- }
+ if (CPU_EMPTY(mask))
+ return (EDEADLK);
switch (level) {
case CPU_LEVEL_ROOT:
case CPU_LEVEL_CPUSET:
@@ -2057,8 +2054,7 @@
case CPU_WHICH_INTRHANDLER:
case CPU_WHICH_ITHREAD:
case CPU_WHICH_DOMAIN:
- error = EINVAL;
- goto out;
+ return (EINVAL);
}
if (level == CPU_LEVEL_ROOT)
nset = cpuset_refroot(set);
@@ -2098,6 +2094,47 @@
error = EINVAL;
break;
}
+ return (error);
+}
+
+int
+user_cpuset_setaffinity(struct thread *td, cpulevel_t level, cpuwhich_t which,
+ id_t id, size_t cpusetsize, const cpuset_t *maskp)
+{
+ cpuset_t *mask;
+ int error;
+ size_t size;
+
+ size = min(cpusetsize, sizeof(cpuset_t));
+ mask = malloc(sizeof(cpuset_t), M_TEMP, M_WAITOK | M_ZERO);
+ error = copyin(maskp, mask, size);
+ if (error)
+ goto out;
+ /*
+ * Verify that no high bits are set.
+ */
+ if (cpusetsize > sizeof(cpuset_t)) {
+ const char *end, *cp;
+ int val;
+ end = cp = (const char *)&maskp->__bits;
+ end += cpusetsize;
+ cp += sizeof(cpuset_t);
+
+ while (cp != end) {
+ val = fubyte(cp);
+ if (val == -1) {
+ error = EFAULT;
+ goto out;
+ }
+ if (val != 0) {
+ error = EINVAL;
+ goto out;
+ }
+ cp++;
+ }
+ }
+ error = kern_cpuset_setaffinity(td, level, which, id, mask);
+
out:
free(mask, M_TEMP);
return (error);
Index: sys/sys/syscallsubr.h
===================================================================
--- sys/sys/syscallsubr.h
+++ sys/sys/syscallsubr.h
@@ -121,6 +121,8 @@
int kern_cpuset_getaffinity(struct thread *td, cpulevel_t level,
cpuwhich_t which, id_t id, size_t cpusetsize, cpuset_t *maskp);
int kern_cpuset_setaffinity(struct thread *td, cpulevel_t level,
+ cpuwhich_t which, id_t id, cpuset_t *maskp);
+int user_cpuset_setaffinity(struct thread *td, cpulevel_t level,
cpuwhich_t which, id_t id, size_t cpusetsize,
const cpuset_t *maskp);
int kern_cpuset_getdomain(struct thread *td, cpulevel_t level,
Index: tests/sys/kern/Makefile
===================================================================
--- tests/sys/kern/Makefile
+++ tests/sys/kern/Makefile
@@ -26,6 +26,7 @@
ATF_TESTS_C+= ptrace_test
TEST_METADATA.ptrace_test+= timeout="15"
ATF_TESTS_C+= reaper
+ATF_TESTS_C+= sched_affinity
ATF_TESTS_C+= sigaltstack
ATF_TESTS_C+= sigwait
.if ${MACHINE_ARCH} != "i386" && ${MACHINE_ARCH:Mpowerpc*} == ""
Index: tests/sys/kern/sched_affinity.c
===================================================================
--- /dev/null
+++ tests/sys/kern/sched_affinity.c
@@ -0,0 +1,297 @@
+/*-
+ * Copyright (c) 2022 Dmitry Chagin <dchagin@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/stdint.h>
+#include <sys/sysctl.h>
+
+#include <errno.h>
+#include <sched.h>
+
+#include <atf-c.h>
+
+static uint32_t maxcpuid;
+static uint32_t maxcpus;
+static uint32_t cpus;
+
+static uint32_t
+support_getcpus(void)
+{
+ uint32_t val;
+ size_t sz = sizeof(val);
+
+ ATF_REQUIRE(sysctlbyname("kern.smp.cpus", &val, &sz, NULL, 0) == 0);
+ return (val);
+}
+
+static uint32_t
+support_getmaxcpus(void)
+{
+ uint32_t val;
+ size_t sz = sizeof(val);
+
+ ATF_REQUIRE(sysctlbyname("kern.smp.maxcpus", &val, &sz, NULL, 0) == 0);
+ return (val);
+}
+
+static uint32_t
+support_getmaxcpuid(void)
+{
+ cpuset_t *set;
+ int setsize, rv;
+ uint32_t i, id;
+
+ for (i = 1; i < maxcpus; i++) {
+ setsize = CPU_ALLOC_SIZE(i);
+ set = CPU_ALLOC(i);
+ ATF_REQUIRE(set != NULL);
+ CPU_ZERO_S(i, set);
+ rv = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, setsize, set);
+ if (rv == 0) {
+ id = __BIT_FLS(i, set) - 1;
+ CPU_FREE(set);
+ break;
+ }
+ CPU_FREE(set);
+ }
+ ATF_REQUIRE(rv == 0);
+ return (id);
+}
+
+ATF_TC_WITHOUT_HEAD(test_setinvalidcpu);
+ATF_TC_BODY(test_setinvalidcpu, tc)
+{
+ size_t cpusetsize;
+ cpuset_t *set;
+
+ cpusetsize = CPU_ALLOC_SIZE(maxcpuid + 1);
+ set = CPU_ALLOC(maxcpuid + 1);
+ ATF_REQUIRE(set != NULL);
+ CPU_ZERO_S(maxcpuid + 1, set);
+ CPU_SET_S(maxcpuid + 1, maxcpuid + 1, set);
+ CPU_SET_S(maxcpuid - 1, maxcpuid + 1, set);
+ ATF_REQUIRE(sched_setaffinity(0, cpusetsize, set) == 0);
+ CPU_FREE(set);
+
+ cpusetsize = CPU_ALLOC_SIZE(maxcpus + 1);
+ set = CPU_ALLOC(maxcpus + 1);
+ ATF_REQUIRE(set != NULL);
+ CPU_ZERO_S(maxcpus + 1, set);
+ CPU_SET_S(maxcpuid + 1, maxcpus + 1, set);
+ CPU_SET_S(maxcpuid - 1, maxcpus + 1, set);
+ ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, cpusetsize, set) == -1);
+ ATF_REQUIRE_EQ(errno, EINVAL);
+ CPU_FREE(set);
+}
+
+ATF_TC_WITHOUT_HEAD(test_setvalidcpu);
+ATF_TC_BODY(test_setvalidcpu, tc)
+{
+ size_t cpusetsize;
+ cpuset_t *set;
+ int cpu;
+
+ ATF_REQUIRE(maxcpuid < maxcpus);
+ cpu = maxcpuid > 1 ? maxcpuid - 1 : 0;
+
+ cpusetsize = CPU_ALLOC_SIZE(maxcpus + 1);
+ set = CPU_ALLOC(maxcpus + 1);
+ ATF_REQUIRE(set != NULL);
+ CPU_ZERO_S(maxcpus + 1, set);
+ CPU_SET_S(cpu, maxcpus + 1, set);
+ ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, cpusetsize, set) == 0);
+ ATF_REQUIRE_EQ(cpu, sched_getcpu());
+ CPU_FREE(set);
+}
+
+ATF_TC_WITHOUT_HEAD(test_setzeroset1);
+ATF_TC_BODY(test_setzeroset1, tc)
+{
+ size_t cpusetsize;
+ cpuset_t *set;
+
+ cpusetsize = CPU_ALLOC_SIZE(maxcpuid + 1);
+ set = CPU_ALLOC(maxcpuid + 1);
+ ATF_REQUIRE(set != NULL);
+ CPU_ZERO_S(maxcpuid + 1, set);
+ ATF_REQUIRE(sched_setaffinity(0, cpusetsize, set) == -1);
+ ATF_REQUIRE_EQ(errno, EINVAL);
+ CPU_FREE(set);
+}
+
+ATF_TC_WITHOUT_HEAD(test_setzeroset2);
+ATF_TC_BODY(test_setzeroset2, tc)
+{
+ size_t cpusetsize;
+ cpuset_t *set;
+
+ cpusetsize = CPU_ALLOC_SIZE(maxcpuid + 1);
+ set = CPU_ALLOC(maxcpuid + 1);
+ ATF_REQUIRE(set != NULL);
+ CPU_ZERO_S(maxcpuid + 1, set);
+ ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, cpusetsize, set) == -1);
+ ATF_REQUIRE_EQ(errno, EDEADLK);
+ CPU_FREE(set);
+}
+
+ATF_TC_WITHOUT_HEAD(test_setmaxsetsize);
+ATF_TC_BODY(test_setmaxsetsize, tc)
+{
+ size_t cpusetsize;
+ cpuset_t *set;
+
+ cpusetsize = CPU_ALLOC_SIZE(maxcpus * 2);
+ set = CPU_ALLOC(maxcpus * 2);
+ ATF_REQUIRE(set != NULL);
+ CPU_ZERO_S(maxcpus * 2, set);
+ ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 0);
+ CPU_SET_S(0, maxcpus * 2, set);
+ ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 1);
+ ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, cpusetsize, set) == 0);
+
+ CPU_ZERO_S(maxcpus * 2, set);
+ CPU_SET_S(maxcpuid, maxcpus * 2, set);
+ ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, cpusetsize, set) == 0);
+
+ CPU_ZERO_S(maxcpus * 2, set);
+ CPU_SET_S(maxcpuid + 1, maxcpus * 2, set);
+ ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, cpusetsize, set) == -1);
+ ATF_REQUIRE_EQ(errno, EINVAL);
+ CPU_FREE(set);
+}
+
+ATF_TC_WITHOUT_HEAD(test_setminsetsize);
+ATF_TC_BODY(test_setminsetsize, tc)
+{
+ size_t cpusetsize = 1;
+ int8_t set;
+
+ if (cpus <= 8)
+ return;
+
+ set = 1;
+ ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, cpusetsize, (const cpuset_t *)&set) == 0);
+ set = 0;
+ ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, cpusetsize, (const cpuset_t *)&set) == -1);
+ ATF_REQUIRE_EQ(errno, EDEADLK);
+}
+
+ATF_TC_WITHOUT_HEAD(test_getminsetsize);
+ATF_TC_BODY(test_getminsetsize, tc)
+{
+ size_t cpusetsize = 1;
+ int8_t set = 0;
+
+ if (cpus < 9)
+ return;
+ ATF_REQUIRE(cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, cpusetsize, (cpuset_t *)&set) == -1);
+ ATF_REQUIRE_EQ(errno, ERANGE);
+}
+
+ATF_TC_WITHOUT_HEAD(test_getsetsize);
+ATF_TC_BODY(test_getsetsize, tc)
+{
+ size_t cpusetsize;
+ cpuset_t *set;
+
+ cpusetsize = CPU_ALLOC_SIZE(maxcpuid + 1);
+ set = CPU_ALLOC(maxcpuid + 1);
+ ATF_REQUIRE(set != NULL);
+ CPU_ZERO_S(maxcpuid + 1, set);
+ ATF_REQUIRE(cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, cpusetsize, set) == 0);
+ CPU_FREE(set);
+}
+
+ATF_TC_WITHOUT_HEAD(test_schedgetsetsize);
+ATF_TC_BODY(test_schedgetsetsize, tc)
+{
+ cpuset_t *set;
+ int cpusetsize;
+
+ cpusetsize = CPU_ALLOC_SIZE(maxcpuid + 1);
+ set = CPU_ALLOC(maxcpuid + 1);
+ ATF_REQUIRE(set != NULL);
+ CPU_ZERO_S(maxcpuid + 1, set);
+ ATF_REQUIRE(sched_getaffinity(0, cpusetsize, set) == cpusetsize);
+ CPU_FREE(set);
+
+ set = CPU_ALLOC(CPU_SETSIZE);
+ ATF_REQUIRE(set != NULL);
+ cpusetsize = CPU_ALLOC_SIZE(CPU_SETSIZE);
+ CPU_ZERO(set);
+ ATF_REQUIRE(sched_getaffinity(0, cpusetsize, set) == cpusetsize);
+ CPU_FREE(set);
+}
+
+ATF_TC_WITHOUT_HEAD(test_holes);
+ATF_TC_BODY(test_holes, tc)
+{
+ cpuset_t *set;
+ int cpusetsize;
+
+ cpusetsize = CPU_ALLOC_SIZE(maxcpus * 2);
+ set = CPU_ALLOC(maxcpus * 2);
+ ATF_REQUIRE(set != NULL);
+ CPU_ZERO_S(maxcpus * 2, set);
+ ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 0);
+ CPU_SET_S(maxcpuid, maxcpus * 2, set);
+ ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 1);
+ ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, cpusetsize, set) == 0);
+
+ CPU_ZERO_S(maxcpus * 2, set);
+ ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 0);
+ CPU_SET_S(maxcpuid + 1, maxcpus * 2, set);
+ ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 1);
+ ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, cpusetsize, set) == -1);
+ ATF_REQUIRE_EQ(errno, EINVAL);
+
+ ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 1);
+ ATF_REQUIRE(cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
+ -1, cpusetsize, set) == 0);
+ ATF_REQUIRE(CPU_ISSET_S(maxcpuid + 1, maxcpus * 2, set) == false);
+ ATF_REQUIRE(CPU_ISSET_S(maxcpuid, maxcpus * 2, set) == true);
+ ATF_REQUIRE_EQ(maxcpuid, (uint32_t)sched_getcpu());
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ cpus = support_getcpus();
+ maxcpus = support_getmaxcpus();
+ maxcpuid = support_getmaxcpuid();
+
+ ATF_TP_ADD_TC(tp, test_setinvalidcpu);
+ ATF_TP_ADD_TC(tp, test_setvalidcpu);
+ ATF_TP_ADD_TC(tp, test_setzeroset1);
+ ATF_TP_ADD_TC(tp, test_setzeroset2);
+
+ ATF_TP_ADD_TC(tp, test_setminsetsize);
+ ATF_TP_ADD_TC(tp, test_setmaxsetsize);
+
+ ATF_TP_ADD_TC(tp, test_getminsetsize);
+ ATF_TP_ADD_TC(tp, test_getsetsize);
+
+ ATF_TP_ADD_TC(tp, test_schedgetsetsize);
+
+ ATF_TP_ADD_TC(tp, test_holes);
+
+ return (atf_no_error());
+}

File Metadata

Mime Type
text/plain
Expires
Thu, Oct 9, 1:46 PM (21 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23497936
Default Alt Text
D34849.id105675.diff (20 KB)

Event Timeline