Page MenuHomeFreeBSD

D46608.diff
No OneTemporary

D46608.diff

diff --git a/share/man/man9/domainset.9 b/share/man/man9/domainset.9
--- a/share/man/man9/domainset.9
+++ b/share/man/man9/domainset.9
@@ -22,7 +22,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd April 14, 2021
+.Dd September 08, 2024
.Dt DOMAINSET 9
.Os
.Sh NAME
@@ -54,6 +54,8 @@
.Ft struct domainset *
.Fn domainset_create "const struct domainset *key"
.Ft int
+.Fn domainset_populate "struct domainset *domain" "domainset_t *mask" "int policy" "size_t mask_size"
+.Ft int
.Fn sysctl_handle_domainset "SYSCTL_HANDLER_ARGS"
.Sh DESCRIPTION
The
@@ -137,6 +139,7 @@
to avoid blocking indefinitely on a
.Dv M_WAITOK
request.
+.Pp
The
.Fn domainset_create
function takes a partially filled in domainset as a key and returns a
@@ -148,6 +151,16 @@
not be modified after return.
.Pp
The
+.Fn domainset_populate
+function fills a
+.Vt domainset
+struct using a domain mask and policy. It is used for validating and
+translating a domain mask and policy into a
+.Vt domainset
+struct when creating a custom domainset using
+.Vt domainset_create.
+.Pp
+The
.Fn sysctl_handle_domainset
function is provided as a convenience for modifying or viewing domainsets
that are not accessible via
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
@@ -2409,81 +2409,90 @@
}
int
-kern_cpuset_setdomain(struct thread *td, cpulevel_t level, cpuwhich_t which,
- id_t id, size_t domainsetsize, const domainset_t *maskp, int policy,
- const struct cpuset_copy_cb *cb)
+domainset_populate(struct domainset *domain, domainset_t *mask, int policy,
+ size_t mask_size)
{
- struct cpuset *nset;
- struct cpuset *set;
- struct thread *ttd;
- struct proc *p;
- struct domainset domain;
- domainset_t *mask;
- int error;
- if (domainsetsize < sizeof(domainset_t) ||
- domainsetsize > DOMAINSET_MAXSIZE / NBBY)
- return (ERANGE);
if (policy <= DOMAINSET_POLICY_INVALID ||
policy > DOMAINSET_POLICY_MAX)
return (EINVAL);
- error = cpuset_check_capabilities(td, level, which, id);
- if (error != 0)
- return (error);
- memset(&domain, 0, sizeof(domain));
- mask = malloc(domainsetsize, M_TEMP, M_WAITOK | M_ZERO);
- error = cb->cpuset_copyin(maskp, mask, domainsetsize);
- if (error)
- goto out;
+
/*
* Verify that no high bits are set.
*/
- if (domainsetsize > sizeof(domainset_t)) {
+ if (mask_size > sizeof(domainset_t)) {
char *end;
char *cp;
end = cp = (char *)&mask->__bits;
- end += domainsetsize;
+ end += mask_size;
cp += sizeof(domainset_t);
while (cp != end)
if (*cp++ != 0) {
- error = EINVAL;
- goto out;
+ return (EINVAL);
}
}
if (DOMAINSET_EMPTY(mask)) {
- error = EDEADLK;
- goto out;
+ return (EDEADLK);
}
- DOMAINSET_COPY(mask, &domain.ds_mask);
- domain.ds_policy = policy;
+ DOMAINSET_COPY(mask, &domain->ds_mask);
+ domain->ds_policy = policy;
/*
* Sanitize the provided mask.
*/
- if (!DOMAINSET_SUBSET(&all_domains, &domain.ds_mask)) {
- error = EINVAL;
- goto out;
+ if (!DOMAINSET_SUBSET(&all_domains, &domain->ds_mask)) {
+ return (EINVAL);
}
/* Translate preferred policy into a mask and fallback. */
if (policy == DOMAINSET_POLICY_PREFER) {
/* Only support a single preferred domain. */
- if (DOMAINSET_COUNT(&domain.ds_mask) != 1) {
- error = EINVAL;
- goto out;
+ if (DOMAINSET_COUNT(&domain->ds_mask) != 1) {
+ return (EINVAL);
}
- domain.ds_prefer = DOMAINSET_FFS(&domain.ds_mask) - 1;
+ domain->ds_prefer = DOMAINSET_FFS(&domain->ds_mask) - 1;
/* This will be constrained by domainset_shadow(). */
- DOMAINSET_COPY(&all_domains, &domain.ds_mask);
+ DOMAINSET_COPY(&all_domains, &domain->ds_mask);
}
/*
* When given an impossible policy, fall back to interleaving
* across all domains.
*/
- if (domainset_empty_vm(&domain))
- domainset_copy(domainset2, &domain);
+ if (domainset_empty_vm(domain))
+ domainset_copy(domainset2, domain);
+
+ return (0);
+}
+
+int
+kern_cpuset_setdomain(struct thread *td, cpulevel_t level, cpuwhich_t which,
+ id_t id, size_t domainsetsize, const domainset_t *maskp, int policy,
+ const struct cpuset_copy_cb *cb)
+{
+ struct cpuset *nset;
+ struct cpuset *set;
+ struct thread *ttd;
+ struct proc *p;
+ struct domainset domain;
+ domainset_t *mask;
+ int error;
+
+ error = cpuset_check_capabilities(td, level, which, id);
+ if (error != 0)
+ return (error);
+ if (domainsetsize < sizeof(domainset_t) ||
+ domainsetsize > DOMAINSET_MAXSIZE / NBBY)
+ return (ERANGE);
+ memset(&domain, 0, sizeof(domain));
+ mask = malloc(domainsetsize, M_TEMP, M_WAITOK | M_ZERO);
+ error = cb->cpuset_copyin(maskp, mask, domainsetsize);
+ if (error)
+ goto out;
+ error = domainset_populate(&domain, mask, policy, domainsetsize);
+ if (error)
+ goto out;
switch (level) {
case CPU_LEVEL_ROOT:
diff --git a/sys/sys/domainset.h b/sys/sys/domainset.h
--- a/sys/sys/domainset.h
+++ b/sys/sys/domainset.h
@@ -113,6 +113,14 @@
* returned value will not match the key pointer.
*/
struct domainset *domainset_create(const struct domainset *);
+
+/*
+ * Validate and populate a domainset structure according to the specified
+ * policy and mask.
+ */
+int domainset_populate(struct domainset *domain, domainset_t *mask, int policy,
+ size_t mask_size);
+
#ifdef _SYS_SYSCTL_H_
int sysctl_handle_domainset(SYSCTL_HANDLER_ARGS);
#endif

File Metadata

Mime Type
text/plain
Expires
Wed, Feb 5, 9:49 AM (21 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16471976
Default Alt Text
D46608.diff (5 KB)

Event Timeline