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;
}