Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/prg-localcount2]: src/sys/kern When we're draining the localcount's refe...
details: https://anonhg.NetBSD.org/src/rev/d25a1e8fb7cb
branches: prg-localcount2
changeset: 823540:d25a1e8fb7cb
user: pgoyette <pgoyette%NetBSD.org@localhost>
date: Fri May 12 22:12:23 2017 +0000
description:
When we're draining the localcount's references, transfer the local
CPU's reference count to the global total, and then zero it. Any
further calls to localcount_release() will adjust only the global
counter.
Avoids a race condition which depends on having localcount_release()
being aware of whether the local CPU's contribution has already been
accounted for. Thanks to Kengo NAKAHARA for bringing up the question,
and to riastradh@ for the solution.
diffstat:
sys/kern/subr_localcount.c | 17 ++++++++++++-----
1 files changed, 12 insertions(+), 5 deletions(-)
diffs (52 lines):
diff -r 7e4e53b99635 -r d25a1e8fb7cb sys/kern/subr_localcount.c
--- a/sys/kern/subr_localcount.c Fri May 12 06:24:53 2017 +0000
+++ b/sys/kern/subr_localcount.c Fri May 12 22:12:23 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_localcount.c,v 1.1.6.4 2017/05/11 21:31:12 pgoyette Exp $ */
+/* $NetBSD: subr_localcount.c,v 1.1.6.5 2017/05/12 22:12:23 pgoyette Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -44,7 +44,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_localcount.c,v 1.1.6.4 2017/05/11 21:31:12 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_localcount.c,v 1.1.6.5 2017/05/12 22:12:23 pgoyette Exp $");
#include <sys/param.h>
#include <sys/localcount.h>
@@ -148,6 +148,14 @@
percpu_free(lc->lc_percpu, sizeof(uint64_t));
}
+/*
+ * localcount_xc(cookie0, cookie1)
+ *
+ * Accumulate and transfer the per-CPU reference counts to a
+ * global total, resetting the per-CPU counter to zero. Once
+ * localcount_drain() has started, we only maintain the total
+ * count in localcount_release().
+ */
static void
localcount_xc(void *cookie0, void *cookie1)
{
@@ -158,6 +166,7 @@
mutex_enter(interlock);
localp = percpu_getref(lc->lc_percpu);
*lc->lc_totalp += *localp;
+ *localp -= *localp; /* ie, *localp = 0; */
percpu_putref(lc->lc_percpu);
mutex_exit(interlock);
}
@@ -235,9 +244,7 @@
* the last reference.
*/
mutex_enter(interlock);
- localcount_adjust(lc, -1);
- *lc->lc_totalp -= 1;
- if (*lc->lc_totalp == 0)
+ if (--*lc->lc_totalp == 0)
cv_broadcast(cv);
mutex_exit(interlock);
goto out;
Home |
Main Index |
Thread Index |
Old Index