Source-Changes-HG archive

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

[src/riastradh-drm2]: src/sys/external/bsd/drm2/linux In linux_idr, move idr_...



details:   https://anonhg.NetBSD.org/src/rev/a11579c4fb53
branches:  riastradh-drm2
changeset: 788036:a11579c4fb53
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Wed Jul 24 01:56:48 2013 +0000

description:
In linux_idr, move idr_temp access under the write lock.

The atomic swaps were missing memory barriers, but using the rwlock
is easier to understand for now.  This should probably use passive
serialization eventually anyway.

diffstat:

 sys/external/bsd/drm2/linux/linux_idr.c |  21 ++++++++++++++-------
 1 files changed, 14 insertions(+), 7 deletions(-)

diffs (51 lines):

diff -r 6cabdfd84a41 -r a11579c4fb53 sys/external/bsd/drm2/linux/linux_idr.c
--- a/sys/external/bsd/drm2/linux/linux_idr.c   Wed Jul 24 01:56:33 2013 +0000
+++ b/sys/external/bsd/drm2/linux/linux_idr.c   Wed Jul 24 01:56:48 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_idr.c,v 1.1.2.1 2013/07/24 00:50:36 riastradh Exp $      */
+/*     $NetBSD: linux_idr.c,v 1.1.2.2 2013/07/24 01:56:48 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.1 2013/07/24 00:50:36 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_idr.c,v 1.1.2.2 2013/07/24 01:56:48 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -142,8 +142,12 @@
        if (temp == NULL)
                return 0;
 
-       if (atomic_cas_ptr(&idr->idr_temp, NULL, temp) != NULL)
+       rw_enter(&idr->idr_lock, RW_WRITER);
+       if (idr->idr_temp == NULL)
+               idr->idr_temp = temp;
+       else
                kmem_free(temp, sizeof(*temp));
+       rw_exit(&idr->idr_lock);
 
        return 1;
 }
@@ -154,11 +158,14 @@
        struct idr_node *node, *search, *collision __unused;
        int want_id = min_id;
 
-       node = atomic_swap_ptr(&idr->idr_temp, NULL);
-       if (node == NULL)
+       rw_enter(&idr->idr_lock, RW_WRITER);
+
+       node = idr->idr_temp;
+       if (node == NULL) {
+               rw_exit(&idr->idr_lock);
                return -EAGAIN;
-
-       rw_enter(&idr->idr_lock, RW_WRITER);
+       }
+       idr->idr_temp = NULL;
 
        search = rb_tree_find_node_geq(&idr->idr_tree, &min_id);
        while ((search != NULL) && (search->in_index == want_id)) {



Home | Main Index | Thread Index | Old Index