Source-Changes-HG archive

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

[src/trunk]: src/sys/net80211 Use atomic_ops(3) to increase/decrease node ref...



details:   https://anonhg.NetBSD.org/src/rev/95526089e2c8
branches:  trunk
changeset: 770192:95526089e2c8
user:      dyoung <dyoung%NetBSD.org@localhost>
date:      Fri Oct 07 16:51:45 2011 +0000

description:
Use atomic_ops(3) to increase/decrease node reference counts, just
like the upstream code did, because the current reference counting is
potentially racy.  This works fine in light testing.

diffstat:

 sys/net80211/ieee80211_netbsd.c |  16 +++------
 sys/net80211/ieee80211_netbsd.h |  23 +-------------
 sys/net80211/ieee80211_node.h   |  68 +++++++++++++++++++++++++++++++---------
 3 files changed, 60 insertions(+), 47 deletions(-)

diffs (171 lines):

diff -r 481f2aa72527 -r 95526089e2c8 sys/net80211/ieee80211_netbsd.c
--- a/sys/net80211/ieee80211_netbsd.c   Fri Oct 07 16:36:23 2011 +0000
+++ b/sys/net80211/ieee80211_netbsd.c   Fri Oct 07 16:51:45 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ieee80211_netbsd.c,v 1.18 2011/07/17 20:54:52 joerg Exp $ */
+/* $NetBSD: ieee80211_netbsd.c,v 1.19 2011/10/07 16:51:45 dyoung Exp $ */
 /*-
  * Copyright (c) 2003-2005 Sam Leffler, Errno Consulting
  * All rights reserved.
@@ -30,7 +30,7 @@
 #ifdef __FreeBSD__
 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_freebsd.c,v 1.8 2005/08/08 18:46:35 sam Exp $");
 #else
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_netbsd.c,v 1.18 2011/07/17 20:54:52 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_netbsd.c,v 1.19 2011/10/07 16:51:45 dyoung Exp $");
 #endif
 
 /*
@@ -488,15 +488,11 @@
 int
 ieee80211_node_dectestref(struct ieee80211_node *ni)
 {
-       int rc, s;
-       s = splnet();
-       if (--ni->ni_refcnt == 0) {
-               rc = 1;
-               ni->ni_refcnt = 1;
+       if (atomic_dec_uint_nv(&ni->ni_refcnt) == 0) {
+               atomic_inc_uint(&ni->ni_refcnt);
+               return 1;
        } else
-               rc = 0;
-       splx(s);
-       return rc;
+               return 0;
 }
 
 void
diff -r 481f2aa72527 -r 95526089e2c8 sys/net80211/ieee80211_netbsd.h
--- a/sys/net80211/ieee80211_netbsd.h   Fri Oct 07 16:36:23 2011 +0000
+++ b/sys/net80211/ieee80211_netbsd.h   Fri Oct 07 16:51:45 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ieee80211_netbsd.h,v 1.15 2008/06/15 16:42:19 christos Exp $ */
+/* $NetBSD: ieee80211_netbsd.h,v 1.16 2011/10/07 16:51:45 dyoung Exp $ */
 /*-
  * Copyright (c) 2003-2005 Sam Leffler, Errno Consulting
  * All rights reserved.
@@ -153,27 +153,6 @@
 #define        ACL_UNLOCK(_as)                 IEEE80211_UNLOCK_IMPL(_as, as_lock)
 #define        ACL_LOCK_ASSERT(_as)            IEEE80211_LOCK_ASSERT_IMPL(_as, as_lock)
 
-/*
- * Node reference counting definitions.
- *
- * ieee80211_node_initref      initialize the reference count to 1
- * ieee80211_node_incref       add a reference
- * ieee80211_node_decref       remove a reference
- * ieee80211_node_dectestref   remove a reference and return 1 if this
- *                             is the last reference, otherwise 0
- * ieee80211_node_refcnt       reference count for printing (only)
- */
-
-#define ieee80211_node_initref(_ni) \
-       do { ((_ni)->ni_refcnt = 1); } while (0)
-#define ieee80211_node_incref(_ni) \
-       do { (_ni)->ni_refcnt++; } while (0)
-#define        ieee80211_node_decref(_ni) \
-       do { (_ni)->ni_refcnt--; } while (0)
-struct ieee80211_node;
-int ieee80211_node_dectestref(struct ieee80211_node *ni);
-#define        ieee80211_node_refcnt(_ni)      (_ni)->ni_refcnt
-
 struct ifqueue;
 void   ieee80211_drain_ifq(struct ifqueue *);
 
diff -r 481f2aa72527 -r 95526089e2c8 sys/net80211/ieee80211_node.h
--- a/sys/net80211/ieee80211_node.h     Fri Oct 07 16:36:23 2011 +0000
+++ b/sys/net80211/ieee80211_node.h     Fri Oct 07 16:51:45 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ieee80211_node.h,v 1.23 2007/12/22 00:51:07 dyoung Exp $       */
+/*     $NetBSD: ieee80211_node.h,v 1.24 2011/10/07 16:51:45 dyoung Exp $       */
 /*-
  * Copyright (c) 2001 Atsushi Onoe
  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@@ -35,6 +35,7 @@
 #ifndef _NET80211_IEEE80211_NODE_H_
 #define _NET80211_IEEE80211_NODE_H_
 
+#include <sys/atomic.h>
 #include <net80211/ieee80211_netbsd.h>
 #include <net80211/ieee80211_ioctl.h>          /* for ieee80211_nodestats */
 
@@ -159,20 +160,6 @@
 #define        IEEE80211_NODE_STAT_ADD(ni,stat,v)      (ni->ni_stats.ns_##stat += v)
 #define        IEEE80211_NODE_STAT_SET(ni,stat,v)      (ni->ni_stats.ns_##stat = v)
 
-static __inline struct ieee80211_node *
-ieee80211_ref_node(struct ieee80211_node *ni)
-{
-       ieee80211_node_incref(ni);
-       return ni;
-}
-
-static __inline void
-ieee80211_unref_node(struct ieee80211_node **ni)
-{
-       ieee80211_node_decref(*ni);
-       *ni = NULL;                     /* guard against use */
-}
-
 struct ieee80211com;
 
 void   ieee80211_node_attach(struct ieee80211com *);
@@ -327,6 +314,57 @@
        u_int8_t        *wme;
 };
 
+/*
+ * Node reference counting definitions.
+ *
+ * ieee80211_node_initref      initialize the reference count to 1
+ * ieee80211_node_incref       add a reference
+ * ieee80211_node_decref       remove a reference
+ * ieee80211_node_dectestref   remove a reference and return 1 if this
+ *                             is the last reference, otherwise 0
+ * ieee80211_node_refcnt       reference count for printing (only)
+ */
+
+static inline void
+ieee80211_node_initref(struct ieee80211_node *ni)
+{
+       ni->ni_refcnt = 1;
+}
+
+static inline void
+ieee80211_node_incref(struct ieee80211_node *ni)
+{
+       atomic_inc_uint(&ni->ni_refcnt);
+}
+
+static inline void
+ieee80211_node_decref(struct ieee80211_node *ni)
+{
+       atomic_dec_uint(&ni->ni_refcnt);
+}
+
+int ieee80211_node_dectestref(struct ieee80211_node *ni);
+
+static inline unsigned int
+ieee80211_node_refcnt(const struct ieee80211_node *ni)
+{
+       return ni->ni_refcnt;
+}
+
+static __inline struct ieee80211_node *
+ieee80211_ref_node(struct ieee80211_node *ni)
+{
+       ieee80211_node_incref(ni);
+       return ni;
+}
+
+static __inline void
+ieee80211_unref_node(struct ieee80211_node **ni)
+{
+       ieee80211_node_decref(*ni);
+       *ni = NULL;                     /* guard against use */
+}
+
 void   ieee80211_add_scan(struct ieee80211com *,
                const struct ieee80211_scanparams *,
                const struct ieee80211_frame *,



Home | Main Index | Thread Index | Old Index