Source-Changes-HG archive

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

[src/trunk]: src/sys/net80211 Don't hold 2 locks at the same time, causes loc...



details:   https://anonhg.NetBSD.org/src/rev/6a42672c4e75
branches:  trunk
changeset: 785755:6a42672c4e75
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Mar 29 02:26:45 2013 +0000

description:
Don't hold 2 locks at the same time, causes lockdebug panic. Triggered by
running usb wifi interfaces as access points. What we do instead is check
the generation number upon restart, and if it changed we give up.

diffstat:

 sys/net80211/ieee80211_node.c |  26 ++++++++++++++++++++------
 1 files changed, 20 insertions(+), 6 deletions(-)

diffs (72 lines):

diff -r 75cd7e87fb1b -r 6a42672c4e75 sys/net80211/ieee80211_node.c
--- a/sys/net80211/ieee80211_node.c     Fri Mar 29 02:20:17 2013 +0000
+++ b/sys/net80211/ieee80211_node.c     Fri Mar 29 02:26:45 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ieee80211_node.c,v 1.65 2013/03/29 02:20:17 christos Exp $     */
+/*     $NetBSD: ieee80211_node.c,v 1.66 2013/03/29 02:26:45 christos Exp $     */
 /*-
  * Copyright (c) 2001 Atsushi Onoe
  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@@ -36,7 +36,7 @@
 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_node.c,v 1.65 2005/08/13 17:50:21 sam Exp $");
 #endif
 #ifdef __NetBSD__
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_node.c,v 1.65 2013/03/29 02:20:17 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_node.c,v 1.66 2013/03/29 02:26:45 christos Exp $");
 #endif
 
 #include "opt_inet.h"
@@ -1908,9 +1908,18 @@
                   ic->ic_opmode == IEEE80211_M_AHDEMO);
        IEEE80211_SCAN_LOCK(nt);
        gen = ++nt->nt_scangen;
+       IEEE80211_SCAN_UNLOCK(nt);
        IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE,
                "%s: %s scangen %u\n", __func__, nt->nt_name, gen);
 restart:
+       IEEE80211_SCAN_LOCK(nt);
+       if (gen != nt->nt_scangen) {
+               printf("%s: scan aborted %u\n", __func__, gen);
+               IEEE80211_SCAN_UNLOCK(nt);
+               return;
+       }
+       IEEE80211_SCAN_UNLOCK(nt);
+
        IEEE80211_NODE_LOCK(nt);
        TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
                if (ni->ni_scangen == gen)      /* previously handled */
@@ -2039,8 +2048,6 @@
        }
        IEEE80211_NODE_UNLOCK(nt);
 
-       IEEE80211_SCAN_UNLOCK(nt);
-
        nt->nt_inact_timer = IEEE80211_INACT_WAIT;
 }
 
@@ -2052,7 +2059,16 @@
 
        IEEE80211_SCAN_LOCK(nt);
        gen = ++nt->nt_scangen;
+       IEEE80211_SCAN_UNLOCK(nt);
 restart:
+       IEEE80211_SCAN_LOCK(nt);
+       if (gen != nt->nt_scangen) {
+               printf("%s: scan aborted %u\n", __func__, gen);
+               IEEE80211_SCAN_UNLOCK(nt);
+               return;
+       }
+       IEEE80211_SCAN_UNLOCK(nt);
+
        IEEE80211_NODE_LOCK(nt);
        TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
                if (ni->ni_scangen != gen) {
@@ -2065,8 +2081,6 @@
                }
        }
        IEEE80211_NODE_UNLOCK(nt);
-
-       IEEE80211_SCAN_UNLOCK(nt);
 }
 
 void



Home | Main Index | Thread Index | Old Index