Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-8]: src/sys Pull up following revision(s) (requested by ozaki-r i...



details:   https://anonhg.NetBSD.org/src/rev/dbfa859ea4c6
branches:  netbsd-8
changeset: 851257:dbfa859ea4c6
user:      snj <snj%NetBSD.org@localhost>
date:      Tue Jan 02 10:36:12 2018 +0000

description:
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

diffstat:

 sys/kern/subr_psref.c |  61 +++++++++++++++++++++++++++++++++++---------------
 sys/sys/psref.h       |   6 +++-
 2 files changed, 47 insertions(+), 20 deletions(-)

diffs (157 lines):

diff -r 25b8e54d5258 -r dbfa859ea4c6 sys/kern/subr_psref.c
--- a/sys/kern/subr_psref.c     Tue Jan 02 10:30:10 2018 +0000
+++ b/sys/kern/subr_psref.c     Tue Jan 02 10:36:12 2018 +0000
@@ -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 @@
 #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 @@
        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 @@
 }
 
 #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;
+
+       found = psref_exist(pcpu, psref);
+       if (found) {
+               panic("The psref is already in the list (acquiring twice?): "
+                   "psref=%p target=%p", psref, target);
+       }
+}
 
-       LIST_FOREACH(_psref, &pcpu->pcpu_head, psref_entry) {
-               if (_psref == psref &&
-                   _psref->psref_target == target) {
-                       found = true;
-                       break;
-               }
-       }
-       if (found) {
-               panic("trying to acquire a target twice with the same psref: "
+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 @@
 #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 @@
 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 @@
         * (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 @@
        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 @@
        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",
diff -r 25b8e54d5258 -r dbfa859ea4c6 sys/sys/psref.h
--- a/sys/sys/psref.h   Tue Jan 02 10:30:10 2018 +0000
+++ b/sys/sys/psref.h   Tue Jan 02 10:36:12 2018 +0000
@@ -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 @@
  *     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;



Home | Main Index | Thread Index | Old Index