diff options
authorKyle Evans <kevans@FreeBSD.org>2020-12-15 21:51:45 +0000
committerKyle Evans <kevans@FreeBSD.org>2020-12-15 21:51:45 +0000
commit64b4d0ba0b4e35589a88c6035d6675ce1770c01d (patch)
parente4e8ecaf63ba6f2767680a7b4666461243d88749 (diff)
MFC r368460: kern: cpuset: plug a unr leak
cpuset_rel_defer() is supposed to be functionally equivalent to cpuset_rel() but with anything that might sleep deferred until cpuset_rel_complete -- this setup is used specifically for cpuset_setproc. Add in the missing unr free to match cpuset_rel. This fixes a leak that was observed when I wrote a small userland application to try and debug another issue, which effectively did: cpuset(&newid); cpuset(&scratch); newid gets leaked when scratch is created; it's off the list, so there's no mechanism for anything else to relinquish it. A more realistic reproducer would likely be a process that inherits some cpuset that it's the only ref for, but it creates a new one to modify. Alternatively, administratively reassigning a process' cpuset that it's the last ref for will have the same effect.
Notes: svn path=/stable/12/; revision=368679
1 files changed, 5 insertions, 0 deletions
diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c
index c82f776c37f1..7e1e3c4da2d4 100644
--- a/sys/kern/kern_cpuset.c
+++ b/sys/kern/kern_cpuset.c
@@ -246,9 +246,14 @@ cpuset_rel_defer(struct setlist *head, struct cpuset *set)
static void
cpuset_rel_complete(struct cpuset *set)
+ cpusetid_t id;
+ id = set->cs_id;
LIST_REMOVE(set, cs_link);
uma_zfree(cpuset_zone, set);
+ if (id != CPUSET_INVALID)
+ free_unr(cpuset_unr, id);