libthr: Fix pthread_attr_[g|s]etaffinity_np to match it's manual and the kernel.
Since f35093f8
semantics of a thread affinity functions is changed to be a
compatible with Linux:
In case of getaffinity(), the minimum cpuset_t size that the kernel permits is
the maximum CPU id, present in the system, / NBBY bytes, the maximum size is not
limited.
In case of setaffinity(), the kernel does not limit the size of the user-provided
cpuset_t, internally using only the meaningful part of the set, where the upper
bound is the maximum CPU id, present in the system, no larger than the size of
the kernel cpuset_t.
To match pthread_attr_[g|s]etaffinity_np checks of the user-provided cpusets to
the kernel behavior export the minimum cpuset_t size allowed by running kernel
via new sysctl kern.sched.cpusetsizemin and use it in checks.
Reviewed by:
Differential Revision: https://reviews.freebsd.org/D38112
MFC after: 1 week
This commit is contained in:
parent
02f7670ed2
commit
01f74ccd5a
@ -599,8 +599,10 @@ _get_kern_cpuset_size(void)
|
|||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
len = sizeof(kern_cpuset_size);
|
len = sizeof(kern_cpuset_size);
|
||||||
if (sysctlbyname("kern.sched.cpusetsize", &kern_cpuset_size,
|
if (sysctlbyname("kern.sched.cpusetsizemin", &kern_cpuset_size,
|
||||||
&len, NULL, 0))
|
&len, NULL, 0) != 0 &&
|
||||||
|
sysctlbyname("kern.sched.cpusetsize", &kern_cpuset_size,
|
||||||
|
&len, NULL, 0) != 0)
|
||||||
PANIC("failed to get sysctl kern.sched.cpusetsize");
|
PANIC("failed to get sysctl kern.sched.cpusetsize");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,11 +136,17 @@ static struct domainlist cpuset_domains;
|
|||||||
static struct unrhdr *cpuset_unr;
|
static struct unrhdr *cpuset_unr;
|
||||||
static struct cpuset *cpuset_zero, *cpuset_default, *cpuset_kernel;
|
static struct cpuset *cpuset_zero, *cpuset_default, *cpuset_kernel;
|
||||||
static struct domainset *domainset0, *domainset2;
|
static struct domainset *domainset0, *domainset2;
|
||||||
|
u_int cpusetsizemin = 1;
|
||||||
|
|
||||||
/* Return the size of cpuset_t at the kernel level */
|
/* Return the size of cpuset_t at the kernel level */
|
||||||
SYSCTL_INT(_kern_sched, OID_AUTO, cpusetsize, CTLFLAG_RD | CTLFLAG_CAPRD,
|
SYSCTL_INT(_kern_sched, OID_AUTO, cpusetsize, CTLFLAG_RD | CTLFLAG_CAPRD,
|
||||||
SYSCTL_NULL_INT_PTR, sizeof(cpuset_t), "sizeof(cpuset_t)");
|
SYSCTL_NULL_INT_PTR, sizeof(cpuset_t), "sizeof(cpuset_t)");
|
||||||
|
|
||||||
|
/* Return the minimum size of cpuset_t allowed by the kernel */
|
||||||
|
SYSCTL_UINT(_kern_sched, OID_AUTO, cpusetsizemin,
|
||||||
|
CTLFLAG_RD | CTLFLAG_CAPRD, &cpusetsizemin, 0,
|
||||||
|
"The minimum size of cpuset_t allowed by the kernel");
|
||||||
|
|
||||||
cpuset_t *cpuset_root;
|
cpuset_t *cpuset_root;
|
||||||
cpuset_t cpuset_domain[MAXMEMDOM];
|
cpuset_t cpuset_domain[MAXMEMDOM];
|
||||||
|
|
||||||
|
@ -148,6 +148,8 @@ mp_setmaxid(void *dummy)
|
|||||||
KASSERT(mp_maxid >= mp_ncpus - 1,
|
KASSERT(mp_maxid >= mp_ncpus - 1,
|
||||||
("%s: counters out of sync: max %d, count %d", __func__,
|
("%s: counters out of sync: max %d, count %d", __func__,
|
||||||
mp_maxid, mp_ncpus));
|
mp_maxid, mp_ncpus));
|
||||||
|
|
||||||
|
cpusetsizemin = howmany(mp_maxid + 1, NBBY);
|
||||||
}
|
}
|
||||||
SYSINIT(cpu_mp_setmaxid, SI_SUB_TUNABLES, SI_ORDER_FIRST, mp_setmaxid, NULL);
|
SYSINIT(cpu_mp_setmaxid, SI_SUB_TUNABLES, SI_ORDER_FIRST, mp_setmaxid, NULL);
|
||||||
|
|
||||||
|
@ -120,6 +120,7 @@
|
|||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
|
|
||||||
LIST_HEAD(setlist, cpuset);
|
LIST_HEAD(setlist, cpuset);
|
||||||
|
extern u_int cpusetsizemin;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cpusets encapsulate cpu binding information for one or more threads.
|
* cpusets encapsulate cpu binding information for one or more threads.
|
||||||
|
Loading…
Reference in New Issue
Block a user