Source-Changes-HG archive

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

[src/trunk]: src/sys/sys Cause readers to fail noisily after PSLIST_ENTRY_DES...



details:   https://anonhg.NetBSD.org/src/rev/b18a039b5eb1
branches:  trunk
changeset: 814818:b18a039b5eb1
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Mon Apr 11 03:46:37 2016 +0000

description:
Cause readers to fail noisily after PSLIST_ENTRY_DESTROY.

Using NULL only causes readers to stop iteration, because it looks
like the end of the list; using a bogus non-null pointer causes them
to crash.

diffstat:

 sys/sys/pslist.h |  21 ++++++++++++++++++---
 1 files changed, 18 insertions(+), 3 deletions(-)

diffs (97 lines):

diff -r 6c5e9d6c096a -r b18a039b5eb1 sys/sys/pslist.h
--- a/sys/sys/pslist.h  Mon Apr 11 03:27:14 2016 +0000
+++ b/sys/sys/pslist.h  Mon Apr 11 03:46:37 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pslist.h,v 1.1 2016/04/09 04:39:46 riastradh Exp $     */
+/*     $NetBSD: pslist.h,v 1.2 2016/04/11 03:46:37 riastradh Exp $     */
 
 /*-
  * Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -54,6 +54,8 @@
 #define        _PSLIST_ASSERT  assert
 #endif
 
+#define        _PSLIST_POISON  ((void *)1ul)
+
 /*
  * Initialization.  Allowed only when the caller has exclusive access,
  * excluding writers and readers.
@@ -86,7 +88,13 @@
 {
 
        _PSLIST_ASSERT(entry->ple_prevp == NULL);
-       entry->ple_next = NULL;
+
+       /*
+        * Poison the next entry.  If we used NULL here, then readers
+        * would think they were simply at the end of the list.
+        * Instead, cause readers to crash.
+        */
+       entry->ple_next = _PSLIST_POISON;
 }
 
 /*
@@ -123,6 +131,7 @@
     struct pslist_entry *new)
 {
 
+       _PSLIST_ASSERT(entry->ple_next != _PSLIST_POISON);
        _PSLIST_ASSERT(entry->ple_prevp != NULL);
        _PSLIST_ASSERT(*entry->ple_prevp == entry);
        _PSLIST_ASSERT(new->ple_next == NULL);
@@ -140,6 +149,7 @@
     struct pslist_entry *new)
 {
 
+       _PSLIST_ASSERT(entry->ple_next != _PSLIST_POISON);
        _PSLIST_ASSERT(entry->ple_prevp != NULL);
        _PSLIST_ASSERT(*entry->ple_prevp == entry);
        _PSLIST_ASSERT(new->ple_next == NULL);
@@ -157,13 +167,14 @@
 pslist_writer_remove(struct pslist_entry *entry)
 {
 
+       _PSLIST_ASSERT(entry->ple_next != _PSLIST_POISON);
        _PSLIST_ASSERT(entry->ple_prevp != NULL);
        _PSLIST_ASSERT(*entry->ple_prevp == entry);
 
        if (entry->ple_next != NULL)
                entry->ple_next->ple_prevp = entry->ple_prevp;
        *entry->ple_prevp = entry->ple_next;
-       entry->ple_prevp = NULL; /* poison */
+       entry->ple_prevp = NULL;
 }
 
 static inline struct pslist_entry *
@@ -177,6 +188,7 @@
 pslist_writer_next(struct pslist_entry *entry)
 {
 
+       _PSLIST_ASSERT(entry->ple_next != _PSLIST_POISON);
        return entry->ple_next;
 }
 
@@ -193,6 +205,7 @@
 {
        struct pslist_entry *next = entry->ple_next;
 
+       _PSLIST_ASSERT(next != _PSLIST_POISON);
        return (next == NULL ? NULL : (char *)next - offset);
 }
 
@@ -219,6 +232,7 @@
 {
        struct pslist_entry *next = entry->ple_next;
 
+       _PSLIST_ASSERT(next != _PSLIST_POISON);
        if (next != NULL)
                membar_datadep_consumer();
 
@@ -242,6 +256,7 @@
 {
        struct pslist_entry *next = entry->ple_next;
 
+       _PSLIST_ASSERT(next != _PSLIST_POISON);
        if (next == NULL)
                return NULL;
        membar_datadep_consumer();



Home | Main Index | Thread Index | Old Index