Module Name:    src
Committed By:   riastradh
Date:           Mon Apr 11 03:46:37 UTC 2016

Modified Files:
        src/sys/sys: pslist.h

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/sys/pslist.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/sys/pslist.h
diff -u src/sys/sys/pslist.h:1.1 src/sys/sys/pslist.h:1.2
--- src/sys/sys/pslist.h:1.1	Sat Apr  9 04:39:46 2016
+++ src/sys/sys/pslist.h	Mon Apr 11 03:46:37 2016
@@ -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 @@ struct pslist_entry {
 #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_entry_destroy(struct pslist_entry
 {
 
 	_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 @@ pslist_writer_insert_before(struct pslis
     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 @@ pslist_writer_insert_after(struct pslist
     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 @@ static inline void
 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 @@ static inline struct pslist_entry *
 pslist_writer_next(struct pslist_entry *entry)
 {
 
+	_PSLIST_ASSERT(entry->ple_next != _PSLIST_POISON);
 	return entry->ple_next;
 }
 
@@ -193,6 +205,7 @@ _pslist_writer_next_container(struct psl
 {
 	struct pslist_entry *next = entry->ple_next;
 
+	_PSLIST_ASSERT(next != _PSLIST_POISON);
 	return (next == NULL ? NULL : (char *)next - offset);
 }
 
@@ -219,6 +232,7 @@ pslist_reader_next(struct pslist_entry *
 {
 	struct pslist_entry *next = entry->ple_next;
 
+	_PSLIST_ASSERT(next != _PSLIST_POISON);
 	if (next != NULL)
 		membar_datadep_consumer();
 
@@ -242,6 +256,7 @@ _pslist_reader_next_container(struct psl
 {
 	struct pslist_entry *next = entry->ple_next;
 
+	_PSLIST_ASSERT(next != _PSLIST_POISON);
 	if (next == NULL)
 		return NULL;
 	membar_datadep_consumer();

Reply via email to