1*c8b5c478SDmitry Chagin /*- 2*c8b5c478SDmitry Chagin * Copyright (c) 2022 Dmitry Chagin <dchagin@FreeBSD.org> 3*c8b5c478SDmitry Chagin * 4*c8b5c478SDmitry Chagin * SPDX-License-Identifier: BSD-2-Clause 5*c8b5c478SDmitry Chagin */ 6*c8b5c478SDmitry Chagin #include <sys/cdefs.h> 7*c8b5c478SDmitry Chagin __FBSDID("$FreeBSD$"); 8*c8b5c478SDmitry Chagin 9*c8b5c478SDmitry Chagin #include <sys/types.h> 10*c8b5c478SDmitry Chagin #include <sys/stdint.h> 11*c8b5c478SDmitry Chagin #include <sys/sysctl.h> 12*c8b5c478SDmitry Chagin 13*c8b5c478SDmitry Chagin #include <errno.h> 14*c8b5c478SDmitry Chagin #include <sched.h> 15*c8b5c478SDmitry Chagin 16*c8b5c478SDmitry Chagin #include <atf-c.h> 17*c8b5c478SDmitry Chagin 18*c8b5c478SDmitry Chagin static uint32_t maxcpuid; 19*c8b5c478SDmitry Chagin static uint32_t maxcpus; 20*c8b5c478SDmitry Chagin static uint32_t cpus; 21*c8b5c478SDmitry Chagin 22*c8b5c478SDmitry Chagin static uint32_t 23*c8b5c478SDmitry Chagin support_getcpus(void) 24*c8b5c478SDmitry Chagin { 25*c8b5c478SDmitry Chagin uint32_t val; 26*c8b5c478SDmitry Chagin size_t sz = sizeof(val); 27*c8b5c478SDmitry Chagin 28*c8b5c478SDmitry Chagin ATF_REQUIRE(sysctlbyname("kern.smp.cpus", &val, &sz, NULL, 0) == 0); 29*c8b5c478SDmitry Chagin return (val); 30*c8b5c478SDmitry Chagin } 31*c8b5c478SDmitry Chagin 32*c8b5c478SDmitry Chagin static uint32_t 33*c8b5c478SDmitry Chagin support_getmaxcpus(void) 34*c8b5c478SDmitry Chagin { 35*c8b5c478SDmitry Chagin uint32_t val; 36*c8b5c478SDmitry Chagin size_t sz = sizeof(val); 37*c8b5c478SDmitry Chagin 38*c8b5c478SDmitry Chagin ATF_REQUIRE(sysctlbyname("kern.smp.maxcpus", &val, &sz, NULL, 0) == 0); 39*c8b5c478SDmitry Chagin return (val); 40*c8b5c478SDmitry Chagin } 41*c8b5c478SDmitry Chagin 42*c8b5c478SDmitry Chagin static uint32_t 43*c8b5c478SDmitry Chagin support_getmaxcpuid(void) 44*c8b5c478SDmitry Chagin { 45*c8b5c478SDmitry Chagin cpuset_t *set; 46*c8b5c478SDmitry Chagin int setsize, rv; 47*c8b5c478SDmitry Chagin uint32_t i, id; 48*c8b5c478SDmitry Chagin 49*c8b5c478SDmitry Chagin for (i = 1; i < maxcpus; i++) { 50*c8b5c478SDmitry Chagin setsize = CPU_ALLOC_SIZE(i); 51*c8b5c478SDmitry Chagin set = CPU_ALLOC(i); 52*c8b5c478SDmitry Chagin ATF_REQUIRE(set != NULL); 53*c8b5c478SDmitry Chagin CPU_ZERO_S(i, set); 54*c8b5c478SDmitry Chagin rv = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 55*c8b5c478SDmitry Chagin -1, setsize, set); 56*c8b5c478SDmitry Chagin if (rv == 0) { 57*c8b5c478SDmitry Chagin id = __BIT_FLS(i, set) - 1; 58*c8b5c478SDmitry Chagin CPU_FREE(set); 59*c8b5c478SDmitry Chagin break; 60*c8b5c478SDmitry Chagin } 61*c8b5c478SDmitry Chagin CPU_FREE(set); 62*c8b5c478SDmitry Chagin } 63*c8b5c478SDmitry Chagin ATF_REQUIRE(rv == 0); 64*c8b5c478SDmitry Chagin return (id); 65*c8b5c478SDmitry Chagin } 66*c8b5c478SDmitry Chagin 67*c8b5c478SDmitry Chagin ATF_TC_WITHOUT_HEAD(test_setinvalidcpu); 68*c8b5c478SDmitry Chagin ATF_TC_BODY(test_setinvalidcpu, tc) 69*c8b5c478SDmitry Chagin { 70*c8b5c478SDmitry Chagin size_t cpusetsize; 71*c8b5c478SDmitry Chagin cpuset_t *set; 72*c8b5c478SDmitry Chagin 73*c8b5c478SDmitry Chagin cpusetsize = CPU_ALLOC_SIZE(maxcpuid + 1); 74*c8b5c478SDmitry Chagin set = CPU_ALLOC(maxcpuid + 1); 75*c8b5c478SDmitry Chagin ATF_REQUIRE(set != NULL); 76*c8b5c478SDmitry Chagin CPU_ZERO_S(maxcpuid + 1, set); 77*c8b5c478SDmitry Chagin CPU_SET_S(maxcpuid + 1, maxcpuid + 1, set); 78*c8b5c478SDmitry Chagin CPU_SET_S(maxcpuid - 1, maxcpuid + 1, set); 79*c8b5c478SDmitry Chagin ATF_REQUIRE(sched_setaffinity(0, cpusetsize, set) == 0); 80*c8b5c478SDmitry Chagin CPU_FREE(set); 81*c8b5c478SDmitry Chagin 82*c8b5c478SDmitry Chagin cpusetsize = CPU_ALLOC_SIZE(maxcpus + 1); 83*c8b5c478SDmitry Chagin set = CPU_ALLOC(maxcpus + 1); 84*c8b5c478SDmitry Chagin ATF_REQUIRE(set != NULL); 85*c8b5c478SDmitry Chagin CPU_ZERO_S(maxcpus + 1, set); 86*c8b5c478SDmitry Chagin CPU_SET_S(maxcpuid + 1, maxcpus + 1, set); 87*c8b5c478SDmitry Chagin CPU_SET_S(maxcpuid - 1, maxcpus + 1, set); 88*c8b5c478SDmitry Chagin ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 89*c8b5c478SDmitry Chagin -1, cpusetsize, set) == -1); 90*c8b5c478SDmitry Chagin ATF_REQUIRE_EQ(errno, EINVAL); 91*c8b5c478SDmitry Chagin CPU_FREE(set); 92*c8b5c478SDmitry Chagin } 93*c8b5c478SDmitry Chagin 94*c8b5c478SDmitry Chagin ATF_TC_WITHOUT_HEAD(test_setvalidcpu); 95*c8b5c478SDmitry Chagin ATF_TC_BODY(test_setvalidcpu, tc) 96*c8b5c478SDmitry Chagin { 97*c8b5c478SDmitry Chagin size_t cpusetsize; 98*c8b5c478SDmitry Chagin cpuset_t *set; 99*c8b5c478SDmitry Chagin int cpu; 100*c8b5c478SDmitry Chagin 101*c8b5c478SDmitry Chagin ATF_REQUIRE(maxcpuid < maxcpus); 102*c8b5c478SDmitry Chagin cpu = maxcpuid > 1 ? maxcpuid - 1 : 0; 103*c8b5c478SDmitry Chagin 104*c8b5c478SDmitry Chagin cpusetsize = CPU_ALLOC_SIZE(maxcpus + 1); 105*c8b5c478SDmitry Chagin set = CPU_ALLOC(maxcpus + 1); 106*c8b5c478SDmitry Chagin ATF_REQUIRE(set != NULL); 107*c8b5c478SDmitry Chagin CPU_ZERO_S(maxcpus + 1, set); 108*c8b5c478SDmitry Chagin CPU_SET_S(cpu, maxcpus + 1, set); 109*c8b5c478SDmitry Chagin ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 110*c8b5c478SDmitry Chagin -1, cpusetsize, set) == 0); 111*c8b5c478SDmitry Chagin ATF_REQUIRE_EQ(cpu, sched_getcpu()); 112*c8b5c478SDmitry Chagin CPU_FREE(set); 113*c8b5c478SDmitry Chagin } 114*c8b5c478SDmitry Chagin 115*c8b5c478SDmitry Chagin ATF_TC_WITHOUT_HEAD(test_setzeroset1); 116*c8b5c478SDmitry Chagin ATF_TC_BODY(test_setzeroset1, tc) 117*c8b5c478SDmitry Chagin { 118*c8b5c478SDmitry Chagin size_t cpusetsize; 119*c8b5c478SDmitry Chagin cpuset_t *set; 120*c8b5c478SDmitry Chagin 121*c8b5c478SDmitry Chagin cpusetsize = CPU_ALLOC_SIZE(maxcpuid + 1); 122*c8b5c478SDmitry Chagin set = CPU_ALLOC(maxcpuid + 1); 123*c8b5c478SDmitry Chagin ATF_REQUIRE(set != NULL); 124*c8b5c478SDmitry Chagin CPU_ZERO_S(maxcpuid + 1, set); 125*c8b5c478SDmitry Chagin ATF_REQUIRE(sched_setaffinity(0, cpusetsize, set) == -1); 126*c8b5c478SDmitry Chagin ATF_REQUIRE_EQ(errno, EINVAL); 127*c8b5c478SDmitry Chagin CPU_FREE(set); 128*c8b5c478SDmitry Chagin } 129*c8b5c478SDmitry Chagin 130*c8b5c478SDmitry Chagin ATF_TC_WITHOUT_HEAD(test_setzeroset2); 131*c8b5c478SDmitry Chagin ATF_TC_BODY(test_setzeroset2, tc) 132*c8b5c478SDmitry Chagin { 133*c8b5c478SDmitry Chagin size_t cpusetsize; 134*c8b5c478SDmitry Chagin cpuset_t *set; 135*c8b5c478SDmitry Chagin 136*c8b5c478SDmitry Chagin cpusetsize = CPU_ALLOC_SIZE(maxcpuid + 1); 137*c8b5c478SDmitry Chagin set = CPU_ALLOC(maxcpuid + 1); 138*c8b5c478SDmitry Chagin ATF_REQUIRE(set != NULL); 139*c8b5c478SDmitry Chagin CPU_ZERO_S(maxcpuid + 1, set); 140*c8b5c478SDmitry Chagin ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 141*c8b5c478SDmitry Chagin -1, cpusetsize, set) == -1); 142*c8b5c478SDmitry Chagin ATF_REQUIRE_EQ(errno, EDEADLK); 143*c8b5c478SDmitry Chagin CPU_FREE(set); 144*c8b5c478SDmitry Chagin } 145*c8b5c478SDmitry Chagin 146*c8b5c478SDmitry Chagin ATF_TC_WITHOUT_HEAD(test_setmaxsetsize); 147*c8b5c478SDmitry Chagin ATF_TC_BODY(test_setmaxsetsize, tc) 148*c8b5c478SDmitry Chagin { 149*c8b5c478SDmitry Chagin size_t cpusetsize; 150*c8b5c478SDmitry Chagin cpuset_t *set; 151*c8b5c478SDmitry Chagin 152*c8b5c478SDmitry Chagin cpusetsize = CPU_ALLOC_SIZE(maxcpus * 2); 153*c8b5c478SDmitry Chagin set = CPU_ALLOC(maxcpus * 2); 154*c8b5c478SDmitry Chagin ATF_REQUIRE(set != NULL); 155*c8b5c478SDmitry Chagin CPU_ZERO_S(maxcpus * 2, set); 156*c8b5c478SDmitry Chagin ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 0); 157*c8b5c478SDmitry Chagin CPU_SET_S(0, maxcpus * 2, set); 158*c8b5c478SDmitry Chagin ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 1); 159*c8b5c478SDmitry Chagin ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 160*c8b5c478SDmitry Chagin -1, cpusetsize, set) == 0); 161*c8b5c478SDmitry Chagin 162*c8b5c478SDmitry Chagin CPU_ZERO_S(maxcpus * 2, set); 163*c8b5c478SDmitry Chagin CPU_SET_S(maxcpuid, maxcpus * 2, set); 164*c8b5c478SDmitry Chagin ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 165*c8b5c478SDmitry Chagin -1, cpusetsize, set) == 0); 166*c8b5c478SDmitry Chagin 167*c8b5c478SDmitry Chagin CPU_ZERO_S(maxcpus * 2, set); 168*c8b5c478SDmitry Chagin CPU_SET_S(maxcpuid + 1, maxcpus * 2, set); 169*c8b5c478SDmitry Chagin ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 170*c8b5c478SDmitry Chagin -1, cpusetsize, set) == -1); 171*c8b5c478SDmitry Chagin ATF_REQUIRE_EQ(errno, EINVAL); 172*c8b5c478SDmitry Chagin CPU_FREE(set); 173*c8b5c478SDmitry Chagin } 174*c8b5c478SDmitry Chagin 175*c8b5c478SDmitry Chagin ATF_TC_WITHOUT_HEAD(test_setminsetsize); 176*c8b5c478SDmitry Chagin ATF_TC_BODY(test_setminsetsize, tc) 177*c8b5c478SDmitry Chagin { 178*c8b5c478SDmitry Chagin size_t cpusetsize = 1; 179*c8b5c478SDmitry Chagin int8_t set; 180*c8b5c478SDmitry Chagin 181*c8b5c478SDmitry Chagin if (cpus <= 8) 182*c8b5c478SDmitry Chagin return; 183*c8b5c478SDmitry Chagin 184*c8b5c478SDmitry Chagin set = 1; 185*c8b5c478SDmitry Chagin ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 186*c8b5c478SDmitry Chagin -1, cpusetsize, (const cpuset_t *)&set) == 0); 187*c8b5c478SDmitry Chagin set = 0; 188*c8b5c478SDmitry Chagin ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 189*c8b5c478SDmitry Chagin -1, cpusetsize, (const cpuset_t *)&set) == -1); 190*c8b5c478SDmitry Chagin ATF_REQUIRE_EQ(errno, EDEADLK); 191*c8b5c478SDmitry Chagin } 192*c8b5c478SDmitry Chagin 193*c8b5c478SDmitry Chagin ATF_TC_WITHOUT_HEAD(test_getminsetsize); 194*c8b5c478SDmitry Chagin ATF_TC_BODY(test_getminsetsize, tc) 195*c8b5c478SDmitry Chagin { 196*c8b5c478SDmitry Chagin size_t cpusetsize = 1; 197*c8b5c478SDmitry Chagin int8_t set = 0; 198*c8b5c478SDmitry Chagin 199*c8b5c478SDmitry Chagin if (cpus < 9) 200*c8b5c478SDmitry Chagin return; 201*c8b5c478SDmitry Chagin ATF_REQUIRE(cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 202*c8b5c478SDmitry Chagin -1, cpusetsize, (cpuset_t *)&set) == -1); 203*c8b5c478SDmitry Chagin ATF_REQUIRE_EQ(errno, ERANGE); 204*c8b5c478SDmitry Chagin } 205*c8b5c478SDmitry Chagin 206*c8b5c478SDmitry Chagin ATF_TC_WITHOUT_HEAD(test_getsetsize); 207*c8b5c478SDmitry Chagin ATF_TC_BODY(test_getsetsize, tc) 208*c8b5c478SDmitry Chagin { 209*c8b5c478SDmitry Chagin size_t cpusetsize; 210*c8b5c478SDmitry Chagin cpuset_t *set; 211*c8b5c478SDmitry Chagin 212*c8b5c478SDmitry Chagin cpusetsize = CPU_ALLOC_SIZE(maxcpuid + 1); 213*c8b5c478SDmitry Chagin set = CPU_ALLOC(maxcpuid + 1); 214*c8b5c478SDmitry Chagin ATF_REQUIRE(set != NULL); 215*c8b5c478SDmitry Chagin CPU_ZERO_S(maxcpuid + 1, set); 216*c8b5c478SDmitry Chagin ATF_REQUIRE(cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 217*c8b5c478SDmitry Chagin -1, cpusetsize, set) == 0); 218*c8b5c478SDmitry Chagin CPU_FREE(set); 219*c8b5c478SDmitry Chagin } 220*c8b5c478SDmitry Chagin 221*c8b5c478SDmitry Chagin ATF_TC_WITHOUT_HEAD(test_schedgetsetsize); 222*c8b5c478SDmitry Chagin ATF_TC_BODY(test_schedgetsetsize, tc) 223*c8b5c478SDmitry Chagin { 224*c8b5c478SDmitry Chagin cpuset_t *set; 225*c8b5c478SDmitry Chagin int cpusetsize; 226*c8b5c478SDmitry Chagin 227*c8b5c478SDmitry Chagin cpusetsize = CPU_ALLOC_SIZE(maxcpuid + 1); 228*c8b5c478SDmitry Chagin set = CPU_ALLOC(maxcpuid + 1); 229*c8b5c478SDmitry Chagin ATF_REQUIRE(set != NULL); 230*c8b5c478SDmitry Chagin CPU_ZERO_S(maxcpuid + 1, set); 231*c8b5c478SDmitry Chagin ATF_REQUIRE(sched_getaffinity(0, cpusetsize, set) == cpusetsize); 232*c8b5c478SDmitry Chagin CPU_FREE(set); 233*c8b5c478SDmitry Chagin 234*c8b5c478SDmitry Chagin set = CPU_ALLOC(CPU_SETSIZE); 235*c8b5c478SDmitry Chagin ATF_REQUIRE(set != NULL); 236*c8b5c478SDmitry Chagin cpusetsize = CPU_ALLOC_SIZE(CPU_SETSIZE); 237*c8b5c478SDmitry Chagin CPU_ZERO(set); 238*c8b5c478SDmitry Chagin ATF_REQUIRE(sched_getaffinity(0, cpusetsize, set) == cpusetsize); 239*c8b5c478SDmitry Chagin CPU_FREE(set); 240*c8b5c478SDmitry Chagin } 241*c8b5c478SDmitry Chagin 242*c8b5c478SDmitry Chagin ATF_TC_WITHOUT_HEAD(test_holes); 243*c8b5c478SDmitry Chagin ATF_TC_BODY(test_holes, tc) 244*c8b5c478SDmitry Chagin { 245*c8b5c478SDmitry Chagin cpuset_t *set; 246*c8b5c478SDmitry Chagin int cpusetsize; 247*c8b5c478SDmitry Chagin 248*c8b5c478SDmitry Chagin cpusetsize = CPU_ALLOC_SIZE(maxcpus * 2); 249*c8b5c478SDmitry Chagin set = CPU_ALLOC(maxcpus * 2); 250*c8b5c478SDmitry Chagin ATF_REQUIRE(set != NULL); 251*c8b5c478SDmitry Chagin CPU_ZERO_S(maxcpus * 2, set); 252*c8b5c478SDmitry Chagin ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 0); 253*c8b5c478SDmitry Chagin CPU_SET_S(maxcpuid, maxcpus * 2, set); 254*c8b5c478SDmitry Chagin ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 1); 255*c8b5c478SDmitry Chagin ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 256*c8b5c478SDmitry Chagin -1, cpusetsize, set) == 0); 257*c8b5c478SDmitry Chagin 258*c8b5c478SDmitry Chagin CPU_ZERO_S(maxcpus * 2, set); 259*c8b5c478SDmitry Chagin ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 0); 260*c8b5c478SDmitry Chagin CPU_SET_S(maxcpuid + 1, maxcpus * 2, set); 261*c8b5c478SDmitry Chagin ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 1); 262*c8b5c478SDmitry Chagin ATF_REQUIRE(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 263*c8b5c478SDmitry Chagin -1, cpusetsize, set) == -1); 264*c8b5c478SDmitry Chagin ATF_REQUIRE_EQ(errno, EINVAL); 265*c8b5c478SDmitry Chagin 266*c8b5c478SDmitry Chagin ATF_REQUIRE(CPU_COUNT_S(maxcpus * 2, set) == 1); 267*c8b5c478SDmitry Chagin ATF_REQUIRE(cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, 268*c8b5c478SDmitry Chagin -1, cpusetsize, set) == 0); 269*c8b5c478SDmitry Chagin ATF_REQUIRE(CPU_ISSET_S(maxcpuid + 1, maxcpus * 2, set) == false); 270*c8b5c478SDmitry Chagin ATF_REQUIRE(CPU_ISSET_S(maxcpuid, maxcpus * 2, set) == true); 271*c8b5c478SDmitry Chagin ATF_REQUIRE_EQ(maxcpuid, (uint32_t)sched_getcpu()); 272*c8b5c478SDmitry Chagin } 273*c8b5c478SDmitry Chagin 274*c8b5c478SDmitry Chagin ATF_TP_ADD_TCS(tp) 275*c8b5c478SDmitry Chagin { 276*c8b5c478SDmitry Chagin 277*c8b5c478SDmitry Chagin cpus = support_getcpus(); 278*c8b5c478SDmitry Chagin maxcpus = support_getmaxcpus(); 279*c8b5c478SDmitry Chagin maxcpuid = support_getmaxcpuid(); 280*c8b5c478SDmitry Chagin 281*c8b5c478SDmitry Chagin ATF_TP_ADD_TC(tp, test_setinvalidcpu); 282*c8b5c478SDmitry Chagin ATF_TP_ADD_TC(tp, test_setvalidcpu); 283*c8b5c478SDmitry Chagin ATF_TP_ADD_TC(tp, test_setzeroset1); 284*c8b5c478SDmitry Chagin ATF_TP_ADD_TC(tp, test_setzeroset2); 285*c8b5c478SDmitry Chagin 286*c8b5c478SDmitry Chagin ATF_TP_ADD_TC(tp, test_setminsetsize); 287*c8b5c478SDmitry Chagin ATF_TP_ADD_TC(tp, test_setmaxsetsize); 288*c8b5c478SDmitry Chagin 289*c8b5c478SDmitry Chagin ATF_TP_ADD_TC(tp, test_getminsetsize); 290*c8b5c478SDmitry Chagin ATF_TP_ADD_TC(tp, test_getsetsize); 291*c8b5c478SDmitry Chagin 292*c8b5c478SDmitry Chagin ATF_TP_ADD_TC(tp, test_schedgetsetsize); 293*c8b5c478SDmitry Chagin 294*c8b5c478SDmitry Chagin ATF_TP_ADD_TC(tp, test_holes); 295*c8b5c478SDmitry Chagin 296*c8b5c478SDmitry Chagin return (atf_no_error()); 297*c8b5c478SDmitry Chagin } 298