svn commit: r329842 - in user/jeff/numa/sys: kern sys

Jeff Roberson jeff at FreeBSD.org
Thu Feb 22 23:06:41 UTC 2018


Author: jeff
Date: Thu Feb 22 23:06:39 2018
New Revision: 329842
URL: https://svnweb.freebsd.org/changeset/base/329842

Log:
  Make a dedicated set for the kernel and all kernel threads so we can apply
  policy independently.

Modified:
  user/jeff/numa/sys/kern/kern_cpuset.c
  user/jeff/numa/sys/kern/kern_kthread.c
  user/jeff/numa/sys/sys/cpuset.h

Modified: user/jeff/numa/sys/kern/kern_cpuset.c
==============================================================================
--- user/jeff/numa/sys/kern/kern_cpuset.c	Thu Feb 22 22:25:26 2018	(r329841)
+++ user/jeff/numa/sys/kern/kern_cpuset.c	Thu Feb 22 23:06:39 2018	(r329842)
@@ -118,7 +118,7 @@ static struct mtx cpuset_lock;
 static struct setlist cpuset_ids;
 static struct domainlist cpuset_domains;
 static struct unrhdr *cpuset_unr;
-static struct cpuset *cpuset_zero, *cpuset_default;
+static struct cpuset *cpuset_zero, *cpuset_default, *cpuset_kernel;
 
 /* Return the size of cpuset_t at the kernel level */
 SYSCTL_INT(_kern_sched, OID_AUTO, cpusetsize, CTLFLAG_RD | CTLFLAG_CAPRD,
@@ -507,7 +507,7 @@ domainset_notify(void)
 		PROC_UNLOCK(p);
 	}
 	sx_sunlock(&allproc_lock);
-	kernel_object->domain.dr_policy = cpuset_default->cs_domain;
+	kernel_object->domain.dr_policy = cpuset_kernel->cs_domain;
 }
 
 /*
@@ -1239,94 +1239,20 @@ cpuset_setthread(lwpid_t id, cpuset_t *mask)
 int
 cpuset_setithread(lwpid_t id, int cpu)
 {
-	struct setlist cpusets;
-	struct cpuset *nset, *rset;
-	struct cpuset *parent, *old_set;
-	struct thread *td;
-	struct proc *p;
-	cpusetid_t cs_id;
 	cpuset_t mask;
-	int error;
 
-	cpuset_freelist_init(&cpusets, 1);
-	rset = uma_zalloc(cpuset_zone, M_WAITOK | M_ZERO);
-	cs_id = CPUSET_INVALID;
-
 	CPU_ZERO(&mask);
 	if (cpu == NOCPU)
 		CPU_COPY(cpuset_root, &mask);
 	else
 		CPU_SET(cpu, &mask);
-
-	error = cpuset_which(CPU_WHICH_TID, id, &p, &td, &old_set);
-	if (error != 0 || ((cs_id = alloc_unr(cpuset_unr)) == CPUSET_INVALID))
-		goto out;
-
-	/* cpuset_which() returns with PROC_LOCK held. */
-	old_set = td->td_cpuset;
-
-	if (cpu == NOCPU) {
-		nset = LIST_FIRST(&cpusets);
-		LIST_REMOVE(nset, cs_link);
-
-		/*
-		 * roll back to default set. We're not using cpuset_shadow()
-		 * here because we can fail CPU_SUBSET() check. This can happen
-		 * if default set does not contain all CPUs.
-		 */
-		error = _cpuset_create(nset, cpuset_default, &mask, NULL,
-		    CPUSET_INVALID);
-
-		goto applyset;
-	}
-
-	if (old_set->cs_id == 1 || (old_set->cs_id == CPUSET_INVALID &&
-	    old_set->cs_parent->cs_id == 1)) {
-
-		/*
-		 * Current set is either default (1) or
-		 * shadowed version of default set.
-		 *
-		 * Allocate new root set to be able to shadow it
-		 * with any mask.
-		 */
-		error = _cpuset_create(rset, cpuset_zero,
-		    &cpuset_zero->cs_mask, NULL, cs_id);
-		if (error != 0) {
-			PROC_UNLOCK(p);
-			goto out;
-		}
-		rset->cs_flags |= CPU_SET_ROOT;
-		parent = rset;
-		rset = NULL;
-		cs_id = CPUSET_INVALID;
-	} else {
-		/* Assume existing set was already allocated by previous call */
-		parent = old_set;
-		old_set = NULL;
-	}
-
-	error = cpuset_shadow(parent, &nset, &mask, NULL, &cpusets, NULL);
-applyset:
-	if (error == 0) {
-		thread_lock(td);
-		old_set = cpuset_update_thread(td, nset);
-		thread_unlock(td);
-	} else
-		old_set = NULL;
-	PROC_UNLOCK(p);
-	if (old_set != NULL)
-		cpuset_rel(old_set);
-out:
-	cpuset_freelist_free(&cpusets);
-	if (rset != NULL)
-		uma_zfree(cpuset_zone, rset);
-	if (cs_id != CPUSET_INVALID)
-		free_unr(cpuset_unr, cs_id);
-	return (error);
+	return _cpuset_setthread(id, &mask, NULL);
 }
 
-static struct domainset domainset0;
+/*
+ * Create the domainset for cpuset 0, 1 and cpuset 2.
+ */
+static struct domainset domainset0, domainset2;
 
 void
 domainset_zero(void)
@@ -1344,10 +1270,14 @@ domainset_zero(void)
 	dset->ds_prefer = -1;
 	curthread->td_domain.dr_policy = _domainset_create(dset, NULL);
 	kernel_object->domain.dr_policy = curthread->td_domain.dr_policy;
+
+	domainset_copy(dset, &domainset2);
+	domainset2.ds_policy = DOMAINSET_POLICY_ROUNDROBIN;
+	kernel_object->domain.dr_policy = _domainset_create(&domainset2, NULL);
 }
 
 /*
- * Creates system-wide cpusets and the cpuset for thread0 including two
+ * Creates system-wide cpusets and the cpuset for thread0 including three
  * sets:
  * 
  * 0 - The root set which should represent all valid processors in the
@@ -1357,6 +1287,8 @@ domainset_zero(void)
  * 1 - The default set which all processes are a member of until changed.
  *     This allows an administrator to move all threads off of given cpus to
  *     dedicate them to high priority tasks or save power etc.
+ * 2 - The kernel set which allows restriction and policy to be applied only
+ *     to kernel threads and the kernel_object.
  */
 struct cpuset *
 cpuset_thread0(void)
@@ -1370,7 +1302,7 @@ cpuset_thread0(void)
 	    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
 
 	/*
-	 * Create the root system set for the whole machine.  Doesn't use
+	 * Create the root system set (0) for the whole machine.  Doesn't use
 	 * cpuset_create() due to NULL parent.
 	 */
 	set = uma_zalloc(cpuset_zone, M_WAITOK | M_ZERO);
@@ -1384,12 +1316,20 @@ cpuset_thread0(void)
 	cpuset_root = &set->cs_mask;
 
 	/*
-	 * Now derive a default, modifiable set from that to give out.
+	 * Now derive a default (1), modifiable set from that to give out.
 	 */
 	set = uma_zalloc(cpuset_zone, M_WAITOK | M_ZERO);
 	error = _cpuset_create(set, cpuset_zero, NULL, NULL, 1);
 	KASSERT(error == 0, ("Error creating default set: %d\n", error));
 	cpuset_default = set;
+	/*
+	 * Create the kernel set (2).
+	 */
+	set = uma_zalloc(cpuset_zone, M_WAITOK | M_ZERO);
+	error = _cpuset_create(set, cpuset_zero, NULL, NULL, 2);
+	KASSERT(error == 0, ("Error creating kernel set: %d\n", error));
+	set->cs_domain = &domainset2;
+	cpuset_kernel = set;
 
 	/*
 	 * Initialize the unit allocator. 0 and 1 are allocated above.
@@ -1397,6 +1337,18 @@ cpuset_thread0(void)
 	cpuset_unr = new_unrhdr(2, INT_MAX, NULL);
 
 	return (set);
+}
+
+void
+cpuset_kernthread(struct thread *td)
+{
+	struct cpuset *set;
+
+	thread_lock(td);
+	set = td->td_cpuset;
+	td->td_cpuset = cpuset_ref(cpuset_kernel);
+	thread_unlock(td);
+	cpuset_rel(set);
 }
 
 /*

Modified: user/jeff/numa/sys/kern/kern_kthread.c
==============================================================================
--- user/jeff/numa/sys/kern/kern_kthread.c	Thu Feb 22 22:25:26 2018	(r329841)
+++ user/jeff/numa/sys/kern/kern_kthread.c	Thu Feb 22 23:06:39 2018	(r329842)
@@ -131,7 +131,7 @@ kproc_create(void (*func)(void *), void *arg,
 	cpu_fork_kthread_handler(td, func, arg);
 
 	/* Avoid inheriting affinity from a random parent. */
-	cpuset_setthread(td->td_tid, cpuset_root);
+	cpuset_kernthread(td);
 	thread_lock(td);
 	TD_SET_CAN_RUN(td);
 	sched_prio(td, PVM);
@@ -309,7 +309,7 @@ kthread_add(void (*func)(void *), void *arg, struct pr
 	tidhash_add(newtd);
 
 	/* Avoid inheriting affinity from a random parent. */
-	cpuset_setthread(newtd->td_tid, cpuset_root);
+	cpuset_kernthread(newtd);
 
 	/* Delay putting it on the run queue until now. */
 	if (!(flags & RFSTOPPED)) {

Modified: user/jeff/numa/sys/sys/cpuset.h
==============================================================================
--- user/jeff/numa/sys/sys/cpuset.h	Thu Feb 22 22:25:26 2018	(r329841)
+++ user/jeff/numa/sys/sys/cpuset.h	Thu Feb 22 23:06:39 2018	(r329842)
@@ -139,6 +139,7 @@ int	cpuset_create_root(struct prison *, struct cpuset 
 int	cpuset_setproc_update_set(struct proc *, struct cpuset *);
 int	cpuset_which(cpuwhich_t, id_t, struct proc **,
 	    struct thread **, struct cpuset **);
+void	cpuset_kernthread(struct thread *);
 
 char	*cpusetobj_strprint(char *, const cpuset_t *);
 int	cpusetobj_strscan(cpuset_t *, const char *);


More information about the svn-src-user mailing list