Date: Sat, 13 Sep 2014 13:46:17 +0000 (UTC) From: "Alexander V. Chernikov" <melifaro@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r271509 - head/sys/kern Message-ID: <201409131346.s8DDkHn5028043@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: melifaro Date: Sat Sep 13 13:46:16 2014 New Revision: 271509 URL: http://svnweb.freebsd.org/changeset/base/271509 Log: Fix error handling in cpuset_setithread() introduced in r267716. Noted by: kib MFC after: 1 week Modified: head/sys/kern/kern_cpuset.c Modified: head/sys/kern/kern_cpuset.c ============================================================================== --- head/sys/kern/kern_cpuset.c Sat Sep 13 13:36:17 2014 (r271508) +++ head/sys/kern/kern_cpuset.c Sat Sep 13 13:46:16 2014 (r271509) @@ -731,6 +731,7 @@ cpuset_setithread(lwpid_t id, u_char cpu nset = uma_zalloc(cpuset_zone, M_WAITOK); rset = uma_zalloc(cpuset_zone, M_WAITOK); + cs_id = CPUSET_INVALID; CPU_ZERO(&mask); if (cpu == NOCPU) @@ -739,13 +740,14 @@ cpuset_setithread(lwpid_t id, u_char cpu CPU_SET(cpu, &mask); error = cpuset_which(CPU_WHICH_TID, id, &p, &td, &old_set); - if (((cs_id = alloc_unr(cpuset_unr)) == CPUSET_INVALID) || error != 0) + if (error != 0 || ((cs_id = alloc_unr(cpuset_unr)) == CPUSET_INVALID)) goto out; - thread_lock(td); + /* cpuset_which() returns with PROC_LOCK held. */ old_set = td->td_cpuset; if (cpu == NOCPU) { + /* * roll back to default set. We're not using cpuset_shadow() * here because we can fail CPU_SUBSET() check. This can happen @@ -759,7 +761,14 @@ cpuset_setithread(lwpid_t id, u_char cpu if (old_set->cs_id == 1 || (old_set->cs_id == CPUSET_INVALID && old_set->cs_parent->cs_id == 1)) { - /* Default mask, we need to use new root set */ + + /* + * 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, cs_id); if (error != 0) { @@ -772,18 +781,20 @@ cpuset_setithread(lwpid_t id, u_char cpu cs_id = CPUSET_INVALID; } else { /* Assume existing set was already allocated by previous call */ - parent = td->td_cpuset; + parent = old_set; old_set = NULL; } error = cpuset_shadow(parent, nset, &mask); applyset: if (error == 0) { + thread_lock(td); td->td_cpuset = nset; sched_affinity(td); + thread_unlock(td); nset = NULL; - } - thread_unlock(td); + } else + old_set = NULL; PROC_UNLOCK(p); if (old_set != NULL) cpuset_rel(old_set);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409131346.s8DDkHn5028043>