From 7e3717b2f6bd7b0028bd236e2e1bf7f20faeb125 Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Wed, 21 Sep 2005 11:54:15 -0500 Subject: [PATCH] --- yaml --- r: 10241 b: refs/heads/master c: 0ad0c3c64484b1458b51167bd3e614d8d9d070f8 h: refs/heads/master i: 10239: 12a740396ea23014a3b112b41ad11c8d6dfb2655 v: v3 --- [refs] | 2 +- trunk/include/net/ieee80211.h | 1 + trunk/include/net/ieee80211_crypt.h | 1 + trunk/net/ieee80211/ieee80211_crypt.c | 33 +++++++++++++++++++++----- trunk/net/ieee80211/ieee80211_module.c | 2 ++ 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index 331354fdf2c3..7057d10c2edc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 42e349fd10d471d9ae6955a7f12523291c0193e6 +refs/heads/master: 0ad0c3c64484b1458b51167bd3e614d8d9d070f8 diff --git a/trunk/include/net/ieee80211.h b/trunk/include/net/ieee80211.h index fa14360dbc9d..6cc0674e5606 100644 --- a/trunk/include/net/ieee80211.h +++ b/trunk/include/net/ieee80211.h @@ -684,6 +684,7 @@ struct ieee80211_device { struct ieee80211_crypt_data *crypt[WEP_KEYS]; int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ struct timer_list crypt_deinit_timer; + int crypt_quiesced; int bcrx_sta_key; /* use individual keys to override default keys even * with RX of broad/multicast frames */ diff --git a/trunk/include/net/ieee80211_crypt.h b/trunk/include/net/ieee80211_crypt.h index e2064edb957d..536e9a9e6718 100644 --- a/trunk/include/net/ieee80211_crypt.h +++ b/trunk/include/net/ieee80211_crypt.h @@ -82,5 +82,6 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int); void ieee80211_crypt_deinit_handler(unsigned long); void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, struct ieee80211_crypt_data **crypt); +void ieee80211_crypt_quiescing(struct ieee80211_device *ieee); #endif diff --git a/trunk/net/ieee80211/ieee80211_crypt.c b/trunk/net/ieee80211/ieee80211_crypt.c index 0c366299db0f..60d3166facce 100644 --- a/trunk/net/ieee80211/ieee80211_crypt.c +++ b/trunk/net/ieee80211/ieee80211_crypt.c @@ -44,6 +44,10 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force) unsigned long flags; spin_lock_irqsave(&ieee->lock, flags); + + if (list_empty(&ieee->crypt_deinit_list)) + goto unlock; + for (ptr = ieee->crypt_deinit_list.next, n = ptr->next; ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) { entry = list_entry(ptr, struct ieee80211_crypt_data, list); @@ -59,21 +63,35 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force) } kfree(entry); } + unlock: + spin_unlock_irqrestore(&ieee->lock, flags); +} + +/* After this, crypt_deinit_list won't accept new members */ +void ieee80211_crypt_quiescing(struct ieee80211_device *ieee) +{ + unsigned long flags; + + spin_lock_irqsave(&ieee->lock, flags); + ieee->crypt_quiesced = 1; spin_unlock_irqrestore(&ieee->lock, flags); } void ieee80211_crypt_deinit_handler(unsigned long data) { struct ieee80211_device *ieee = (struct ieee80211_device *)data; + unsigned long flags; ieee80211_crypt_deinit_entries(ieee, 0); - if (!list_empty(&ieee->crypt_deinit_list)) { + + spin_lock_irqsave(&ieee->lock, flags); + if (!list_empty(&ieee->crypt_deinit_list) && !ieee->crypt_quiesced) { printk(KERN_DEBUG "%s: entries remaining in delayed crypt " "deletion list\n", ieee->dev->name); ieee->crypt_deinit_timer.expires = jiffies + HZ; add_timer(&ieee->crypt_deinit_timer); } - + spin_unlock_irqrestore(&ieee->lock, flags); } void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, @@ -93,10 +111,12 @@ void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, * locking. */ spin_lock_irqsave(&ieee->lock, flags); - list_add(&tmp->list, &ieee->crypt_deinit_list); - if (!timer_pending(&ieee->crypt_deinit_timer)) { - ieee->crypt_deinit_timer.expires = jiffies + HZ; - add_timer(&ieee->crypt_deinit_timer); + if (!ieee->crypt_quiesced) { + list_add(&tmp->list, &ieee->crypt_deinit_list); + if (!timer_pending(&ieee->crypt_deinit_timer)) { + ieee->crypt_deinit_timer.expires = jiffies + HZ; + add_timer(&ieee->crypt_deinit_timer); + } } spin_unlock_irqrestore(&ieee->lock, flags); } @@ -250,6 +270,7 @@ static void __exit ieee80211_crypto_deinit(void) EXPORT_SYMBOL(ieee80211_crypt_deinit_entries); EXPORT_SYMBOL(ieee80211_crypt_deinit_handler); EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit); +EXPORT_SYMBOL(ieee80211_crypt_quiescing); EXPORT_SYMBOL(ieee80211_register_crypto_ops); EXPORT_SYMBOL(ieee80211_unregister_crypto_ops); diff --git a/trunk/net/ieee80211/ieee80211_module.c b/trunk/net/ieee80211/ieee80211_module.c index 4b43ae1235f9..82a4fd713b28 100644 --- a/trunk/net/ieee80211/ieee80211_module.c +++ b/trunk/net/ieee80211/ieee80211_module.c @@ -138,6 +138,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv) init_timer(&ieee->crypt_deinit_timer); ieee->crypt_deinit_timer.data = (unsigned long)ieee; ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler; + ieee->crypt_quiesced = 0; spin_lock_init(&ieee->lock); @@ -161,6 +162,7 @@ void free_ieee80211(struct net_device *dev) int i; + ieee80211_crypt_quiescing(ieee); del_timer_sync(&ieee->crypt_deinit_timer); ieee80211_crypt_deinit_entries(ieee, 1);