Skip site navigation (1)Skip section navigation (2)
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>