Date: Thu, 22 Feb 2018 23:06:40 +0000 (UTC) From: Jeff Roberson <jeff@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r329842 - in user/jeff/numa/sys: kern sys Message-ID: <201802222306.w1MN6enZ002243@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 *);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802222306.w1MN6enZ002243>