Module Name:    src
Committed By:   riastradh
Date:           Wed Jan 15 13:51:58 UTC 2014

Modified Files:
        src/sys/external/bsd/drm2/include/linux [riastradh-drm2]: idr.h
        src/sys/external/bsd/drm2/linux [riastradh-drm2]: linux_idr.c

Log Message:
Convert linux_idr(9) to use spin locks.

idr_for_each is unlocked; caller must exclude modifications.

Eventually this should be rewritten with pserialize and a fancy
bitmap algorithm, but this *actually* works for now.


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.8 -r1.1.2.9 \
    src/sys/external/bsd/drm2/include/linux/idr.h
cvs rdiff -u -r1.1.2.11 -r1.1.2.12 \
    src/sys/external/bsd/drm2/linux/linux_idr.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/drm2/include/linux/idr.h
diff -u src/sys/external/bsd/drm2/include/linux/idr.h:1.1.2.8 src/sys/external/bsd/drm2/include/linux/idr.h:1.1.2.9
--- src/sys/external/bsd/drm2/include/linux/idr.h:1.1.2.8	Wed Jan 15 13:51:48 2014
+++ src/sys/external/bsd/drm2/include/linux/idr.h	Wed Jan 15 13:51:58 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: idr.h,v 1.1.2.8 2014/01/15 13:51:48 riastradh Exp $	*/
+/*	$NetBSD: idr.h,v 1.1.2.9 2014/01/15 13:51:58 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -39,7 +39,7 @@
 /* XXX Stupid expedient algorithm should be replaced by something better.  */
 
 struct idr {
-	krwlock_t idr_lock;
+	kmutex_t idr_lock;
 	rb_tree_t idr_tree;
 	struct idr_node *idr_temp;
 };

Index: src/sys/external/bsd/drm2/linux/linux_idr.c
diff -u src/sys/external/bsd/drm2/linux/linux_idr.c:1.1.2.11 src/sys/external/bsd/drm2/linux/linux_idr.c:1.1.2.12
--- src/sys/external/bsd/drm2/linux/linux_idr.c:1.1.2.11	Wed Jan 15 13:51:48 2014
+++ src/sys/external/bsd/drm2/linux/linux_idr.c	Wed Jan 15 13:51:58 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_idr.c,v 1.1.2.11 2014/01/15 13:51:48 riastradh Exp $	*/
+/*	$NetBSD: linux_idr.c,v 1.1.2.12 2014/01/15 13:51:58 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_idr.c,v 1.1.2.11 2014/01/15 13:51:48 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_idr.c,v 1.1.2.12 2014/01/15 13:51:58 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -88,7 +88,7 @@ void
 idr_init(struct idr *idr)
 {
 
-	rw_init(&idr->idr_lock);
+	mutex_init(&idr->idr_lock, MUTEX_DEFAULT, IPL_VM);
 	rb_tree_init(&idr->idr_tree, &idr_rb_ops);
 	idr->idr_temp = NULL;
 }
@@ -105,7 +105,7 @@ idr_destroy(struct idr *idr)
 #if 0				/* XXX No rb_tree_destroy?  */
 	rb_tree_destroy(&idr->idr_tree);
 #endif
-	rw_destroy(&idr->idr_lock);
+	mutex_destroy(&idr->idr_lock);
 }
 
 void *
@@ -114,10 +114,10 @@ idr_find(struct idr *idr, int id)
 	const struct idr_node *node;
 	void *data;
 
-	rw_enter(&idr->idr_lock, RW_READER);
+	mutex_spin_enter(&idr->idr_lock);
 	node = rb_tree_find_node(&idr->idr_tree, &id);
 	data = (node == NULL? NULL : node->in_data);
-	rw_exit(&idr->idr_lock);
+	mutex_spin_exit(&idr->idr_lock);
 
 	return data;
 }
@@ -128,7 +128,7 @@ idr_replace(struct idr *idr, void *repla
 	struct idr_node *node;
 	void *result;
 
-	rw_enter(&idr->idr_lock, RW_WRITER);
+	mutex_spin_enter(&idr->idr_lock);
 	node = rb_tree_find_node(&idr->idr_tree, &id);
 	if (node == NULL) {
 		result = ERR_PTR(-ENOENT);
@@ -136,7 +136,7 @@ idr_replace(struct idr *idr, void *repla
 		result = node->in_data;
 		node->in_data = replacement;
 	}
-	rw_exit(&idr->idr_lock);
+	mutex_spin_exit(&idr->idr_lock);
 
 	return result;
 }
@@ -146,11 +146,11 @@ idr_remove(struct idr *idr, int id)
 {
 	struct idr_node *node;
 
-	rw_enter(&idr->idr_lock, RW_WRITER);
+	mutex_spin_enter(&idr->idr_lock);
 	node = rb_tree_find_node(&idr->idr_tree, &id);
 	KASSERT(node != NULL);
 	rb_tree_remove_node(&idr->idr_tree, node);
-	rw_exit(&idr->idr_lock);
+	mutex_spin_exit(&idr->idr_lock);
 	kmem_free(node, sizeof(*node));
 }
 
@@ -159,14 +159,14 @@ idr_remove_all(struct idr *idr)
 {
 	struct idr_node *node;
 
-	rw_enter(&idr->idr_lock, RW_WRITER);
+	mutex_spin_enter(&idr->idr_lock);
 	while ((node = RB_TREE_MIN(&idr->idr_tree)) != NULL) {
 		rb_tree_remove_node(&idr->idr_tree, node);
-		rw_exit(&idr->idr_lock);
+		mutex_spin_exit(&idr->idr_lock);
 		kmem_free(node, sizeof(*node));
-		rw_enter(&idr->idr_lock, RW_WRITER);
+		mutex_spin_enter(&idr->idr_lock);
 	}
-	rw_exit(&idr->idr_lock);
+	mutex_spin_exit(&idr->idr_lock);
 }
 
 int
@@ -174,12 +174,12 @@ idr_pre_get(struct idr *idr, int flags _
 {
 	struct idr_node *temp = kmem_alloc(sizeof(*temp), KM_SLEEP);
 
-	rw_enter(&idr->idr_lock, RW_WRITER);
+	mutex_spin_enter(&idr->idr_lock);
 	if (idr->idr_temp == NULL) {
 		idr->idr_temp = temp;
 		temp = NULL;
 	}
-	rw_exit(&idr->idr_lock);
+	mutex_spin_exit(&idr->idr_lock);
 
 	if (temp != NULL)
 		kmem_free(temp, sizeof(*temp));
@@ -194,7 +194,7 @@ idr_get_new_above(struct idr *idr, void 
 	int want_id = min_id;
 	int error;
 
-	rw_enter(&idr->idr_lock, RW_WRITER);
+	mutex_spin_enter(&idr->idr_lock);
 
 	node = idr->idr_temp;
 	if (node == NULL) {
@@ -222,7 +222,7 @@ idr_get_new_above(struct idr *idr, void 
 	*id = want_id;
 	error = 0;
 
-out:	rw_exit(&idr->idr_lock);
+out:	mutex_spin_exit(&idr->idr_lock);
 	return error;
 }
 
@@ -232,13 +232,13 @@ idr_for_each(struct idr *idr, int (*proc
 	struct idr_node *node;
 	int error = 0;
 
-	rw_enter(&idr->idr_lock, RW_READER);
+	/* XXX Caller must exclude modifications.  */
+	membar_consumer();
 	RB_TREE_FOREACH(node, &idr->idr_tree) {
 		error = (*proc)(node->in_index, node->in_data, arg);
 		if (error)
 			break;
 	}
-	rw_exit(&idr->idr_lock);
 
 	return error;
 }

Reply via email to