Module Name: src
Committed By: snj
Date: Tue Jan 2 10:36:13 UTC 2018
Modified Files:
src/sys/kern [netbsd-8]: subr_psref.c
src/sys/sys [netbsd-8]: psref.h
Log Message:
Pull up following revision(s) (requested by ozaki-r in ticket #458):
sys/sys/psref.h: 1.3
sys/kern/subr_psref.c: 1.8-1.9
Fix psref(9) part of PR kern/52515. It is complete to fix the PR now.
implementated by [email protected], reviewed by [email protected], thanks.
--
Improve debugging functions
- Make psref_check_duplication check just if a given psref is on the list
- It checked both psref and target
- Suggested by riastradh@ some time ago
- Add psref_check_existence that checks a releasing psref is surely on the list
To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.7.2.1 src/sys/kern/subr_psref.c
cvs rdiff -u -r1.2 -r1.2.8.1 src/sys/sys/psref.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/subr_psref.c
diff -u src/sys/kern/subr_psref.c:1.7 src/sys/kern/subr_psref.c:1.7.2.1
--- src/sys/kern/subr_psref.c:1.7 Thu Jun 1 02:45:13 2017
+++ src/sys/kern/subr_psref.c Tue Jan 2 10:36:12 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_psref.c,v 1.7 2017/06/01 02:45:13 chs Exp $ */
+/* $NetBSD: subr_psref.c,v 1.7.2.1 2018/01/02 10:36:12 snj Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_psref.c,v 1.7 2017/06/01 02:45:13 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_psref.c,v 1.7.2.1 2018/01/02 10:36:12 snj Exp $");
#include <sys/types.h>
#include <sys/condvar.h>
@@ -78,7 +78,7 @@ __KERNEL_RCSID(0, "$NetBSD: subr_psref.c
#include <sys/queue.h>
#include <sys/xcall.h>
-LIST_HEAD(psref_head, psref);
+SLIST_HEAD(psref_head, psref);
static bool _psref_held(const struct psref_target *, struct psref_class *,
bool);
@@ -135,7 +135,7 @@ psref_cpu_drained_p(void *p, void *cooki
const struct psref_cpu *pcpu = p;
bool *retp = cookie;
- if (!LIST_EMPTY(&pcpu->pcpu_head))
+ if (!SLIST_EMPTY(&pcpu->pcpu_head))
*retp = false;
}
@@ -187,22 +187,40 @@ psref_target_init(struct psref_target *t
}
#ifdef DEBUG
+static bool
+psref_exist(struct psref_cpu *pcpu, struct psref *psref)
+{
+ struct psref *_psref;
+
+ SLIST_FOREACH(_psref, &pcpu->pcpu_head, psref_entry) {
+ if (_psref == psref)
+ return true;
+ }
+ return false;
+}
+
static void
psref_check_duplication(struct psref_cpu *pcpu, struct psref *psref,
const struct psref_target *target)
{
bool found = false;
- struct psref *_psref;
- LIST_FOREACH(_psref, &pcpu->pcpu_head, psref_entry) {
- if (_psref == psref &&
- _psref->psref_target == target) {
- found = true;
- break;
- }
- }
+ found = psref_exist(pcpu, psref);
if (found) {
- panic("trying to acquire a target twice with the same psref: "
+ panic("The psref is already in the list (acquiring twice?): "
+ "psref=%p target=%p", psref, target);
+ }
+}
+
+static void
+psref_check_existence(struct psref_cpu *pcpu, struct psref *psref,
+ const struct psref_target *target)
+{
+ bool found = false;
+
+ found = psref_exist(pcpu, psref);
+ if (!found) {
+ panic("The psref isn't in the list (releasing unused psref?): "
"psref=%p target=%p", psref, target);
}
}
@@ -250,7 +268,7 @@ psref_acquire(struct psref *psref, const
#endif
/* Record our reference. */
- LIST_INSERT_HEAD(&pcpu->pcpu_head, psref, psref_entry);
+ SLIST_INSERT_HEAD(&pcpu->pcpu_head, psref, psref_entry);
psref->psref_target = target;
psref->psref_lwp = curlwp;
psref->psref_cpu = curcpu();
@@ -273,6 +291,7 @@ void
psref_release(struct psref *psref, const struct psref_target *target,
struct psref_class *class)
{
+ struct psref_cpu *pcpu;
int s;
KASSERTMSG((kpreempt_disabled() || cpu_softintr_p() ||
@@ -302,7 +321,13 @@ psref_release(struct psref *psref, const
* (as does blocking interrupts).
*/
s = splraiseipl(class->prc_iplcookie);
- LIST_REMOVE(psref, psref_entry);
+ pcpu = percpu_getref(class->prc_percpu);
+#ifdef DEBUG
+ /* Sanity-check if the target is surely acquired before. */
+ psref_check_existence(pcpu, psref, target);
+#endif
+ SLIST_REMOVE(&pcpu->pcpu_head, psref, psref, psref_entry);
+ percpu_putref(class->prc_percpu);
splx(s);
/* If someone is waiting for users to drain, notify 'em. */
@@ -353,7 +378,7 @@ psref_copy(struct psref *pto, const stru
pcpu = percpu_getref(class->prc_percpu);
/* Record the new reference. */
- LIST_INSERT_HEAD(&pcpu->pcpu_head, pto, psref_entry);
+ SLIST_INSERT_HEAD(&pcpu->pcpu_head, pto, psref_entry);
pto->psref_target = pfrom->psref_target;
pto->psref_lwp = curlwp;
pto->psref_cpu = curcpu();
@@ -474,7 +499,7 @@ _psref_held(const struct psref_target *t
pcpu = percpu_getref(class->prc_percpu);
/* Search through all the references on this CPU. */
- LIST_FOREACH(psref, &pcpu->pcpu_head, psref_entry) {
+ SLIST_FOREACH(psref, &pcpu->pcpu_head, psref_entry) {
/* Sanity-check the reference's CPU. */
KASSERTMSG((psref->psref_cpu == curcpu()),
"passive reference transferred from CPU %u to CPU %u",
Index: src/sys/sys/psref.h
diff -u src/sys/sys/psref.h:1.2 src/sys/sys/psref.h:1.2.8.1
--- src/sys/sys/psref.h:1.2 Fri Dec 16 20:12:11 2016
+++ src/sys/sys/psref.h Tue Jan 2 10:36:12 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: psref.h,v 1.2 2016/12/16 20:12:11 christos Exp $ */
+/* $NetBSD: psref.h,v 1.2.8.1 2018/01/02 10:36:12 snj Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -69,7 +69,9 @@ struct psref_target {
* written only on the local CPU.
*/
struct psref {
- LIST_ENTRY(psref) psref_entry;
+ SLIST_ENTRY(psref) psref_entry;
+ /* To keep ABI with LIST_ENTRY(psref) version. */
+ void *psref_unused0;
const struct psref_target *psref_target;
struct lwp *psref_lwp;
struct cpu_info *psref_cpu;