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 ozaki-r@n.o, reviewed by riastradh@n.o, 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;