Search Linux Wireless

[PATCH] fix softmac lockdep reports

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

 



It seems I was actually able to hit this deadlock, on my quad G5 softmac
locks up more often than not. This fixes it by using an own workqueue
that can safely be flushed under RTNL.

Not sure if the patch is correct with the workqueue naming. And don't
think with the patch it doesn't continually lock up. It still does, just
doesn't invoke lockdep warnings all the time.

Signed-off-by: Johannes Berg <johannes@xxxxxxxxxxxxxxxx>

---
 include/net/ieee80211softmac.h                  |    2 ++
 net/ieee80211/softmac/ieee80211softmac_assoc.c  |    8 ++++----
 net/ieee80211/softmac/ieee80211softmac_auth.c   |    8 ++++----
 net/ieee80211/softmac/ieee80211softmac_event.c  |    2 +-
 net/ieee80211/softmac/ieee80211softmac_module.c |   10 ++++++++--
 net/ieee80211/softmac/ieee80211softmac_scan.c   |    4 ++--
 net/ieee80211/softmac/ieee80211softmac_wx.c     |    8 ++++----
 7 files changed, 25 insertions(+), 17 deletions(-)

--- wireless-dev.orig/include/net/ieee80211softmac.h	2007-08-29 21:08:28.892054940 +0200
+++ wireless-dev/include/net/ieee80211softmac.h	2007-09-20 14:14:48.041572701 +0200
@@ -229,6 +229,8 @@ struct ieee80211softmac_device {
 	/* this lock protects this structure */
 	spinlock_t lock;
 
+	struct workqueue_struct *wq;
+
 	u8 running; /* SoftMAC started? */
 	u8 scanning;
 
--- wireless-dev.orig/net/ieee80211/softmac/ieee80211softmac_module.c	2007-08-29 21:08:46.832054940 +0200
+++ wireless-dev/net/ieee80211/softmac/ieee80211softmac_module.c	2007-09-20 14:15:48.911562664 +0200
@@ -36,8 +36,13 @@ struct net_device *alloc_ieee80211softma
 	dev = alloc_ieee80211(sizeof(*softmac) + sizeof_priv);
 	if (!dev)
 		return NULL;
-
 	softmac = ieee80211_priv(dev);
+	softmac->wq = create_freezeable_workqueue("softmac");
+	if (!softmac->wq) {
+		free_ieee80211(dev);
+		return NULL;
+	}
+
 	softmac->dev = dev;
 	softmac->ieee = netdev_priv(dev);
 	spin_lock_init(&softmac->lock);
@@ -105,7 +110,7 @@ ieee80211softmac_clear_pending_work(stru
 		cancel_delayed_work(&eventptr->work);
 
 	spin_unlock_irqrestore(&sm->lock, flags);
-	flush_scheduled_work();
+	flush_workqueue(sm->wq);
 
 	/* now we should be save and no longer need locking... */
 	spin_lock_irqsave(&sm->lock, flags);
@@ -139,6 +144,7 @@ void free_ieee80211softmac(struct net_de
 	ieee80211softmac_clear_pending_work(sm);
 	kfree(sm->scaninfo);
 	kfree(sm->wpa.IE);
+	destroy_workqueue(sm->wq);
 	free_ieee80211(dev);
 }
 EXPORT_SYMBOL_GPL(free_ieee80211softmac);
--- wireless-dev.orig/net/ieee80211/softmac/ieee80211softmac_wx.c	2007-08-29 21:08:46.862054940 +0200
+++ wireless-dev/net/ieee80211/softmac/ieee80211softmac_wx.c	2007-09-20 14:14:48.041572701 +0200
@@ -103,7 +103,7 @@ check_assoc_again:
 			/* We must unlock to avoid deadlocks with the assoc workqueue
 			 * on the associnfo.mutex */
 			mutex_unlock(&sm->associnfo.mutex);
-			flush_scheduled_work();
+			flush_workqueue(sm->wq);
 			/* Avoid race! Check assoc status again. Maybe someone started an
 			 * association while we flushed. */
 			goto check_assoc_again;
@@ -127,7 +127,7 @@ check_assoc_again:
 
 	sm->associnfo.associating = 1;
 	/* queue lower level code to do work (if necessary) */
-	schedule_delayed_work(&sm->associnfo.work, 0);
+	queue_delayed_work(sm->wq, &sm->associnfo.work, 0);
 out:
 	mutex_unlock(&sm->associnfo.mutex);
 
@@ -362,7 +362,7 @@ ieee80211softmac_wx_set_wap(struct net_d
 		/* force reassociation */
 		mac->associnfo.bssvalid = 0;
 		if (mac->associnfo.associated)
-			schedule_delayed_work(&mac->associnfo.work, 0);
+			queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
 	} else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
 		/* the bssid we have is no longer fixed */
 		mac->associnfo.bssfixed = 0;
@@ -379,7 +379,7 @@ ieee80211softmac_wx_set_wap(struct net_d
 		/* tell the other code that this bssid should be used no matter what */
 		mac->associnfo.bssfixed = 1;
 		/* queue associate if new bssid or (old one again and not associated) */
-		schedule_delayed_work(&mac->associnfo.work, 0);
+		queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
 	}
 
  out:
--- wireless-dev.orig/net/ieee80211/softmac/ieee80211softmac_assoc.c	2007-08-29 21:08:46.802054940 +0200
+++ wireless-dev/net/ieee80211/softmac/ieee80211softmac_assoc.c	2007-09-20 14:14:48.051571725 +0200
@@ -53,7 +53,7 @@ ieee80211softmac_assoc(struct ieee80211s
 	/* Set a timer for timeout */
 	/* FIXME: make timeout configurable */
 	if (likely(mac->running))
-		schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ);
+		queue_delayed_work(mac->wq, &mac->associnfo.timeout, 5 * HZ);
 	spin_unlock_irqrestore(&mac->lock, flags);
 }
 
@@ -419,7 +419,7 @@ ieee80211softmac_handle_assoc_response(s
 				network->authenticated = 0;
 				/* we don't want to do this more than once ... */
 				network->auth_desynced_once = 1;
-				schedule_delayed_work(&mac->associnfo.work, 0);
+				queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
 				break;
 			}
 		default:
@@ -441,7 +441,7 @@ ieee80211softmac_try_reassoc(struct ieee
 
 	spin_lock_irqsave(&mac->lock, flags);
 	mac->associnfo.associating = 1;
-	schedule_delayed_work(&mac->associnfo.work, 0);
+	queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
 	spin_unlock_irqrestore(&mac->lock, flags);
 }
 
@@ -483,7 +483,7 @@ ieee80211softmac_handle_reassoc_req(stru
 		dprintkl(KERN_INFO PFX "reassoc request from unknown network\n");
 		return 0;
 	}
-	schedule_delayed_work(&mac->associnfo.work, 0);
+	queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
 
 	return 0;
 }
--- wireless-dev.orig/net/ieee80211/softmac/ieee80211softmac_auth.c	2007-08-29 21:08:46.812054940 +0200
+++ wireless-dev/net/ieee80211/softmac/ieee80211softmac_auth.c	2007-09-20 14:14:48.051571725 +0200
@@ -61,7 +61,7 @@ ieee80211softmac_auth_req(struct ieee802
 
 	/* add to list */
 	list_add_tail(&auth->list, &mac->auth_queue);
-	schedule_delayed_work(&auth->work, 0);
+	queue_delayed_work(mac->wq, &auth->work, 0);
 	spin_unlock_irqrestore(&mac->lock, flags);
 
 	return 0;
@@ -95,7 +95,7 @@ ieee80211softmac_auth_queue(struct work_
 		}
 		net->authenticated = 0;
 		/* add a timeout call so we eventually give up waiting for an auth reply */
-		schedule_delayed_work(&auth->work, IEEE80211SOFTMAC_AUTH_TIMEOUT);
+		queue_delayed_work(mac->wq, &auth->work, IEEE80211SOFTMAC_AUTH_TIMEOUT);
 		auth->retry--;
 		spin_unlock_irqrestore(&mac->lock, flags);
 		if (ieee80211softmac_send_mgt_frame(mac, auth->net, IEEE80211_STYPE_AUTH, auth->state))
@@ -238,7 +238,7 @@ ieee80211softmac_auth_resp(struct net_de
 			 * request. */
 			cancel_delayed_work(&aq->work);
 			INIT_DELAYED_WORK(&aq->work, &ieee80211softmac_auth_challenge_response);
-			schedule_delayed_work(&aq->work, 0);
+			queue_delayed_work(mac->wq, &aq->work, 0);
 			spin_unlock_irqrestore(&mac->lock, flags);
 			return 0;
 		case IEEE80211SOFTMAC_AUTH_SHARED_PASS:
@@ -403,6 +403,6 @@ ieee80211softmac_deauth_resp(struct net_
 	ieee80211softmac_deauth_from_net(mac, net);
 
 	/* let's try to re-associate */
-	schedule_delayed_work(&mac->associnfo.work, 0);
+	queue_delayed_work(mac->wq, &mac->associnfo.work, 0);
 	return 0;
 }
--- wireless-dev.orig/net/ieee80211/softmac/ieee80211softmac_event.c	2007-08-29 21:08:46.812054940 +0200
+++ wireless-dev/net/ieee80211/softmac/ieee80211softmac_event.c	2007-09-20 14:14:48.081563858 +0200
@@ -172,7 +172,7 @@ ieee80211softmac_call_events_locked(stru
 				/* User may have subscribed to ANY event, so
 				 * we tell them which event triggered it. */
 				eventptr->event_type = event;
-				schedule_delayed_work(&eventptr->work, 0);
+				queue_delayed_work(mac->wq, &eventptr->work, 0);
 			}
 		}
 }
--- wireless-dev.orig/net/ieee80211/softmac/ieee80211softmac_scan.c	2007-08-29 21:08:46.842054940 +0200
+++ wireless-dev/net/ieee80211/softmac/ieee80211softmac_scan.c	2007-09-20 14:14:48.081563858 +0200
@@ -123,7 +123,7 @@ void ieee80211softmac_scan(struct work_s
 				spin_unlock_irqrestore(&sm->lock, flags);
 				break;
 			}
-			schedule_delayed_work(&si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY);
+			queue_delayed_work(sm->wq, &si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY);
 			spin_unlock_irqrestore(&sm->lock, flags);
 			return;
 		} else {
@@ -190,7 +190,7 @@ int ieee80211softmac_start_scan_implemen
 	sm->scaninfo->started = 1;
 	sm->scaninfo->stop = 0;
 	INIT_COMPLETION(sm->scaninfo->finished);
-	schedule_delayed_work(&sm->scaninfo->softmac_scan, 0);
+	queue_delayed_work(sm->wq, &sm->scaninfo->softmac_scan, 0);
 	spin_unlock_irqrestore(&sm->lock, flags);
 	return 0;
 }


-
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux