d80211: ieee80211_hw handlers should be allowed to sleep
Subsystems (2)
PATCH 1/1 d80211: ieee80211_hw handlers should be allowed to sleep
This patch changes the ieee80211_if_sta timer structure into a workqueue. This will allow the config(), reset_tsf() and config_interface() handlers in the ieee80211_hw structure to sleep. This is especially required for USB drivers that have to sleep for all register access.
Signed-off-by Jan Kiszka <[email protected]>
Signed-off-by Ivo van Doorn <[email protected]>
---
Note that this patch is created against the dscape git tree, this patch will likley not apply cleanly against the wireless-dev git tree.
net/d80211/ieee80211.c +4 -4
@@ -2075,15 +2075,15 @@ void ieee80211_if_shutdown(struct net_decase IEEE80211_IF_TYPE_STA :case IEEE80211_IF_TYPE_IBSS : sdata->u.sta.state =IEEE80211_DISABLED ; -del_timer_sync (&sdata->u.sta.timer); +cancel_delayed_work (&sdata->u.sta.work);if (local->scan_work.data == sdata->dev) { local->sta_scanning =0 ;cancel_delayed_work (&local->scan_work); -flush_scheduled_work ();/* see comment in ieee80211_unregister_hw to * understand why this works */ local->scan_work.data =NULL ; } +flush_scheduled_work ();break ; } }
@@ -4603,8 +4603,8 @@ void ieee80211_unregister_hw(struct net_flush_scheduled_work ();/* The scan_work is guaranteed not to be called at this * point. It is not scheduled and not running now. It can be -* scheduled again only by some sta_timer (all of them are -* stopped by now) or under rtnl lock. */ +* scheduled again only by sta_work (stopped by now) or under +* rtnl lock. */ }ieee80211_rx_bss_list_deinit (dev);
net/d80211/ieee80211_i.h +2 -2
@@ -240,7 +240,7 @@ struct ieee80211_if_sta {IEEE80211_ASSOCIATE ,IEEE80211_ASSOCIATED , IEEE80211_IBSS_SEARCH, IEEE80211_IBSS_JOINED } state; -struct timer_list timer; +struct work_struct work;u8 bssid[ETH_ALEN ], prev_bssid[ETH_ALEN ];u8 ssid[IEEE80211_MAX_SSID_LEN ];size_t ssid_len;
@@ -621,7 +621,7 @@ int ieee80211_set_compression(struct iee struct net_device *dev, struct sta_info *sta);int ieee80211_init_client (struct net_device *dev);/* ieee80211_sta.c */ -void ieee80211_sta_timer (unsigned long ptr); +void ieee80211_sta_work (void *ptr);void ieee80211_sta_rx_mgmt (struct net_device *dev,struct sk_buff *skb,struct ieee80211_rx_status *rx_status);int ieee80211_sta_set_ssid (struct net_device *dev,char *ssid,size_t len);
net/d80211/ieee80211_iface.c +1 -3
@@ -194,9 +194,7 @@ void ieee80211_if_set_type(struct net_destruct ieee80211_if_sta *ifsta; ifsta = &sdata->u.sta; -init_timer (&ifsta->timer); - ifsta->timer.data = (unsigned long ) dev; - ifsta->timer.function = ieee80211_sta_timer; +INIT_WORK (&ifsta->work, ieee80211_sta_work, dev); ifsta->capab =WLAN_CAPABILITY_ESS ; ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN |
net/d80211/ieee80211_sta.c +19 -20
@@ -457,7 +457,7 @@ static void ieee80211_authenticate(strucieee80211_send_auth (dev, ifsta,1 ,NULL ,0 ,0 ); -mod_timer (&ifsta->timer, jiffies +IEEE80211_AUTH_TIMEOUT ); +schedule_delayed_work (&ifsta->work,IEEE80211_AUTH_TIMEOUT ); }
@@ -677,7 +677,7 @@ static void ieee80211_associate(struct nieee80211_send_assoc (dev, ifsta); -mod_timer (&ifsta->timer, jiffies +IEEE80211_ASSOC_TIMEOUT ); +schedule_delayed_work (&ifsta->work,IEEE80211_ASSOC_TIMEOUT ); }
@@ -735,11 +735,11 @@ static void ieee80211_associated(structmemset (wrqu.ap_addr.sa_data,0 ,ETH_ALEN ); wrqu.ap_addr.sa_family =ARPHRD_ETHER ;wireless_send_event (dev,SIOCGIWAP , &wrqu,NULL ); -mod_timer (&ifsta->timer, - jiffies +IEEE80211_MONITORING_INTERVAL +30 *HZ ); +schedule_delayed_work (&ifsta->work, +IEEE80211_MONITORING_INTERVAL +30 *HZ ); }else { -mod_timer (&ifsta->timer, - jiffies +IEEE80211_MONITORING_INTERVAL ); +schedule_delayed_work (&ifsta->work, +IEEE80211_MONITORING_INTERVAL ); } }
@@ -1019,8 +1019,8 @@ static void ieee80211_rx_mgmt_deauth(str ifsta->state == IEEE80211_ASSOCIATE || ifsta->state == IEEE80211_ASSOCIATED) { ifsta->state =IEEE80211_AUTHENTICATE ; -mod_timer (&ifsta->timer, - jiffies +IEEE80211_RETRY_AUTH_INTERVAL ); +schedule_delayed_work (&ifsta->work, +IEEE80211_RETRY_AUTH_INTERVAL ); }ieee80211_set_associated (dev, ifsta,0 );
@@ -1062,8 +1062,8 @@ static void ieee80211_rx_mgmt_disassoc(sif (ifsta->state ==IEEE80211_ASSOCIATED ) { ifsta->state =IEEE80211_ASSOCIATE ; -mod_timer (&ifsta->timer, - jiffies +IEEE80211_RETRY_AUTH_INTERVAL ); +schedule_delayed_work (&ifsta->work, +IEEE80211_RETRY_AUTH_INTERVAL ); }ieee80211_set_associated (dev, ifsta,0 );
@@ -1829,7 +1829,7 @@ static void ieee80211_sta_expire(structstatic void ieee80211_sta_merge_ibss (struct net_device *dev,struct ieee80211_if_sta *ifsta) { -mod_timer (&ifsta->timer, jiffies +IEEE80211_IBSS_MERGE_INTERVAL ); +schedule_delayed_work (&ifsta->work,IEEE80211_IBSS_MERGE_INTERVAL );ieee80211_sta_expire (dev);if (ieee80211_sta_active_ibss (dev))
@@ -1841,20 +1841,19 @@ static void ieee80211_sta_merge_ibss(str } -void ieee80211_sta_timer (unsigned long ptr) +void ieee80211_sta_work (void *ptr) { -struct net_device *dev; +struct net_device *dev = ptr;struct ieee80211_sub_if_data *sdata;struct ieee80211_if_sta *ifsta; - dev = (struct net_device *) ptr;if (!netif_running (dev))return ; sdata =IEEE80211_DEV_TO_SUB_IF (dev);if (sdata->type !=IEEE80211_IF_TYPE_STA && sdata->type !=IEEE80211_IF_TYPE_IBSS ) { -printk (KERN_DEBUG "%s: ieee80211_sta_timer: non-STA interface " +printk (KERN_DEBUG "%s: ieee80211_sta_work: non-STA interface " "(type=%d)\n" , dev->name, sdata->type);return ; }
@@ -1879,7 +1878,7 @@ void ieee80211_sta_timer(unsigned long pieee80211_sta_merge_ibss (dev, ifsta);break ;default : -printk (KERN_DEBUG "ieee80211_sta_timer: Unknown state %d\n" , +printk (KERN_DEBUG "ieee80211_sta_work: Unknown state %d\n" , ifsta->state);break ; }
@@ -2107,7 +2106,7 @@ static int ieee80211_sta_join_ibss(struc } ifsta->state =IEEE80211_IBSS_JOINED ; -mod_timer (&ifsta->timer, jiffies +IEEE80211_IBSS_MERGE_INTERVAL ); +schedule_delayed_work (&ifsta->work,IEEE80211_IBSS_MERGE_INTERVAL );ieee80211_rx_bss_put (dev, bss);
@@ -2224,8 +2223,8 @@ #endif /* CONFIG_D80211_IBSS_DEBUG *//* Selected IBSS not found in current scan results - try to scan */ if (ifsta->state ==IEEE80211_IBSS_JOINED && !ieee80211_sta_active_ibss (dev)) { -mod_timer (&ifsta->timer, - jiffies +IEEE80211_IBSS_MERGE_INTERVAL ); +schedule_delayed_work (&ifsta->work, +IEEE80211_IBSS_MERGE_INTERVAL ); }else if (time_after (jiffies, local->last_scan_completed +IEEE80211_SCAN_INTERVAL )) { printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
@@ -2253,7 +2252,7 @@ #endif /* CONFIG_D80211_IBSS_DEBUG */ } ifsta->state =IEEE80211_IBSS_SEARCH ; -mod_timer (&ifsta->timer, jiffies + interval); +schedule_delayed_work (&ifsta->work, interval);return 0 ; }
Quoted 7 lines · Ivo van Doorn
net/d80211/ieee80211.c +0
-1@@ -2075,15 +2075,15 @@ void ieee80211_if_shutdown(struct net_decase IEEE80211_IF_TYPE_STA :case IEEE80211_IF_TYPE_IBSS : sdata->u.sta.state =IEEE80211_DISABLED ; -del_timer_sync (&sdata->u.sta.timer);
net/d80211/ieee80211.c void ieee80211_if_shutdown(struct net_de · line 2086
Quoted 10 lines
net/d80211/ieee80211.c +2
-1+cancel_delayed_work (&sdata->u.sta.work);if (local->scan_work.data == sdata->dev) { local->sta_scanning =0 ;cancel_delayed_work (&local->scan_work); -flush_scheduled_work ();/* see comment in ieee80211_unregister_hw to * understand why this works */ local->scan_work.data =NULL ; } +flush_scheduled_work ();
This is racy. local->scan_work.data can be set to NULL only after flush_scheduled_work().
Other than that, the patch looks good to me.
Thanks,
Jiri
Signature · 2 lines
Jiri Benc SUSE Labs
Quoted 13 lines · Jiri Benc
Quoted 12 lines · Ivo van Doorn
net/d80211/ieee80211.c +1
-2@@ -2075,15 +2075,15 @@ void ieee80211_if_shutdown(struct net_decase IEEE80211_IF_TYPE_STA :case IEEE80211_IF_TYPE_IBSS : sdata->u.sta.state =IEEE80211_DISABLED ; -del_timer_sync (&sdata->u.sta.timer); +cancel_delayed_work (&sdata->u.sta.work);if (local->scan_work.data == sdata->dev) { local->sta_scanning =0 ;cancel_delayed_work (&local->scan_work); -flush_scheduled_work ();
Quoted 8 lines
net/d80211/ieee80211.c void ieee80211_if_shutdown(struct net_de · line 2086
Quoted 5 lines
net/d80211/ieee80211.c +1
-0/* see comment in ieee80211_unregister_hw to * understand why this works */ local->scan_work.data =NULL ; } +flush_scheduled_work ();This is racy.
local->scan_work.datacan be set to NULL only afterflush_scheduled_work().
Would something like the patch below be better?
It keeps the flush_scheduled_work() at the same location, but a second is added in case local->scan_work.data != sdata->dev
Jan, was there any particular reason to move flush_cheduled_work() outside of the if-statement?
Signed-off-by Ivo van Doorn <[email protected]>
---
net/d80211/ieee80211.c +5 -4
@@ -2075,7 +2075,7 @@ void ieee80211_if_shutdown(struct net_decase IEEE80211_IF_TYPE_STA :case IEEE80211_IF_TYPE_IBSS : sdata->u.sta.state =IEEE80211_DISABLED ; -del_timer_sync (&sdata->u.sta.timer); +cancel_delayed_work (&sdata->u.sta.work);if (local->scan_work.data == sdata->dev) { local->sta_scanning =0 ;cancel_delayed_work (&local->scan_work);
@@ -2083,7 +2083,8 @@ void ieee80211_if_shutdown(struct net_de/* see comment in ieee80211_unregister_hw to * understand why this works */ local->scan_work.data =NULL ; - } + }else +flush_scheduled_work ();break ; } }
@@ -4605,8 +4606,8 @@ void ieee80211_unregister_hw(struct net_flush_scheduled_work ();/* The scan_work is guaranteed not to be called at this * point. It is not scheduled and not running now. It can be -* scheduled again only by some sta_timer (all of them are -* stopped by now) or under rtnl lock. */ +* scheduled again only by sta_work (stopped by now) or under +* rtnl lock. */ }ieee80211_rx_bss_list_deinit (dev);
net/d80211/ieee80211_i.h +2 -2
@@ -240,7 +240,7 @@ struct ieee80211_if_sta {IEEE80211_ASSOCIATE ,IEEE80211_ASSOCIATED , IEEE80211_IBSS_SEARCH, IEEE80211_IBSS_JOINED } state; -struct timer_list timer; +struct work_struct work;u8 bssid[ETH_ALEN ], prev_bssid[ETH_ALEN ];u8 ssid[IEEE80211_MAX_SSID_LEN ];size_t ssid_len;
@@ -621,7 +621,7 @@ int ieee80211_set_compression(struct iee struct net_device *dev, struct sta_info *sta);int ieee80211_init_client (struct net_device *dev);/* ieee80211_sta.c */ -void ieee80211_sta_timer (unsigned long ptr); +void ieee80211_sta_work (void *ptr);void ieee80211_sta_rx_mgmt (struct net_device *dev,struct sk_buff *skb,struct ieee80211_rx_status *rx_status);int ieee80211_sta_set_ssid (struct net_device *dev,char *ssid,size_t len);
net/d80211/ieee80211_iface.c +1 -3
@@ -194,9 +194,7 @@ void ieee80211_if_set_type(struct net_destruct ieee80211_if_sta *ifsta; ifsta = &sdata->u.sta; -init_timer (&ifsta->timer); - ifsta->timer.data = (unsigned long ) dev; - ifsta->timer.function = ieee80211_sta_timer; +INIT_WORK (&ifsta->work, ieee80211_sta_work, dev); ifsta->capab =WLAN_CAPABILITY_ESS ; ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN |
net/d80211/ieee80211_sta.c +19 -20
@@ -457,7 +457,7 @@ static void ieee80211_authenticate(strucieee80211_send_auth (dev, ifsta,1 ,NULL ,0 ,0 ); -mod_timer (&ifsta->timer, jiffies +IEEE80211_AUTH_TIMEOUT ); +schedule_delayed_work (&ifsta->work,IEEE80211_AUTH_TIMEOUT ); }
@@ -677,7 +677,7 @@ static void ieee80211_associate(struct nieee80211_send_assoc (dev, ifsta); -mod_timer (&ifsta->timer, jiffies +IEEE80211_ASSOC_TIMEOUT ); +schedule_delayed_work (&ifsta->work,IEEE80211_ASSOC_TIMEOUT ); }
@@ -735,11 +735,11 @@ static void ieee80211_associated(structmemset (wrqu.ap_addr.sa_data,0 ,ETH_ALEN ); wrqu.ap_addr.sa_family =ARPHRD_ETHER ;wireless_send_event (dev,SIOCGIWAP , &wrqu,NULL ); -mod_timer (&ifsta->timer, - jiffies +IEEE80211_MONITORING_INTERVAL +30 *HZ ); +schedule_delayed_work (&ifsta->work, +IEEE80211_MONITORING_INTERVAL +30 *HZ ); }else { -mod_timer (&ifsta->timer, - jiffies +IEEE80211_MONITORING_INTERVAL ); +schedule_delayed_work (&ifsta->work, +IEEE80211_MONITORING_INTERVAL ); } }
@@ -1019,8 +1019,8 @@ static void ieee80211_rx_mgmt_deauth(str ifsta->state == IEEE80211_ASSOCIATE || ifsta->state == IEEE80211_ASSOCIATED) { ifsta->state =IEEE80211_AUTHENTICATE ; -mod_timer (&ifsta->timer, - jiffies +IEEE80211_RETRY_AUTH_INTERVAL ); +schedule_delayed_work (&ifsta->work, +IEEE80211_RETRY_AUTH_INTERVAL ); }ieee80211_set_associated (dev, ifsta,0 );
@@ -1062,8 +1062,8 @@ static void ieee80211_rx_mgmt_disassoc(sif (ifsta->state ==IEEE80211_ASSOCIATED ) { ifsta->state =IEEE80211_ASSOCIATE ; -mod_timer (&ifsta->timer, - jiffies +IEEE80211_RETRY_AUTH_INTERVAL ); +schedule_delayed_work (&ifsta->work, +IEEE80211_RETRY_AUTH_INTERVAL ); }ieee80211_set_associated (dev, ifsta,0 );
@@ -1829,7 +1829,7 @@ static void ieee80211_sta_expire(structstatic void ieee80211_sta_merge_ibss (struct net_device *dev,struct ieee80211_if_sta *ifsta) { -mod_timer (&ifsta->timer, jiffies +IEEE80211_IBSS_MERGE_INTERVAL ); +schedule_delayed_work (&ifsta->work,IEEE80211_IBSS_MERGE_INTERVAL );ieee80211_sta_expire (dev);if (ieee80211_sta_active_ibss (dev))
@@ -1841,20 +1841,19 @@ static void ieee80211_sta_merge_ibss(str } -void ieee80211_sta_timer (unsigned long ptr) +void ieee80211_sta_work (void *ptr) { -struct net_device *dev; +struct net_device *dev = ptr;struct ieee80211_sub_if_data *sdata;struct ieee80211_if_sta *ifsta; - dev = (struct net_device *) ptr;if (!netif_running (dev))return ; sdata =IEEE80211_DEV_TO_SUB_IF (dev);if (sdata->type !=IEEE80211_IF_TYPE_STA && sdata->type !=IEEE80211_IF_TYPE_IBSS ) { -printk (KERN_DEBUG "%s: ieee80211_sta_timer: non-STA interface " +printk (KERN_DEBUG "%s: ieee80211_sta_work: non-STA interface " "(type=%d)\n" , dev->name, sdata->type);return ; }
@@ -1879,7 +1878,7 @@ void ieee80211_sta_timer(unsigned long pieee80211_sta_merge_ibss (dev, ifsta);break ;default : -printk (KERN_DEBUG "ieee80211_sta_timer: Unknown state %d\n" , +printk (KERN_DEBUG "ieee80211_sta_work: Unknown state %d\n" , ifsta->state);break ; }
@@ -2107,7 +2106,7 @@ static int ieee80211_sta_join_ibss(struc } ifsta->state =IEEE80211_IBSS_JOINED ; -mod_timer (&ifsta->timer, jiffies +IEEE80211_IBSS_MERGE_INTERVAL ); +schedule_delayed_work (&ifsta->work,IEEE80211_IBSS_MERGE_INTERVAL );ieee80211_rx_bss_put (dev, bss);
@@ -2224,8 +2223,8 @@ #endif /* CONFIG_D80211_IBSS_DEBUG *//* Selected IBSS not found in current scan results - try to scan */ if (ifsta->state ==IEEE80211_IBSS_JOINED && !ieee80211_sta_active_ibss (dev)) { -mod_timer (&ifsta->timer, - jiffies +IEEE80211_IBSS_MERGE_INTERVAL ); +schedule_delayed_work (&ifsta->work, +IEEE80211_IBSS_MERGE_INTERVAL ); }else if (time_after (jiffies, local->last_scan_completed +IEEE80211_SCAN_INTERVAL )) { printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
@@ -2253,7 +2252,7 @@ #endif /* CONFIG_D80211_IBSS_DEBUG */ } ifsta->state =IEEE80211_IBSS_SEARCH ; -mod_timer (&ifsta->timer, jiffies + interval); +schedule_delayed_work (&ifsta->work, interval);return 0 ; }
Quoted 22 lines · Ivo van Doorn
Quoted 12 lines · Jiri Benc
Quoted 11 lines · Ivo van Doorn
net/d80211/ieee80211.c +1
-1@@ -2075,15 +2075,15 @@ void ieee80211_if_shutdown(struct net_decase IEEE80211_IF_TYPE_STA :case IEEE80211_IF_TYPE_IBSS : sdata->u.sta.state =IEEE80211_DISABLED ; -del_timer_sync (&sdata->u.sta.timer); +cancel_delayed_work (&sdata->u.sta.work);if (local->scan_work.data == sdata->dev) { local->sta_scanning =0 ;cancel_delayed_work (&local->scan_work);Quoted 8 lines
net/d80211/ieee80211.c void ieee80211_if_shutdown(struct net_de
Quoted 6 lines
net/d80211/ieee80211.c +1
-1-flush_scheduled_work ();/* see comment in ieee80211_unregister_hw to * understand why this works */ local->scan_work.data =NULL ; } +flush_scheduled_work ();This is racy.
local->scan_work.datacan be set to NULL only afterflush_scheduled_work().
Quoted 5 lines
Would something like the patch below be better?
It keeps theflush_scheduled_work()at the same location, but a second is added in caselocal->scan_work.data!=sdata->devJan, was there any particular reason to move
flush_cheduled_work()outside of the if-statement?
It is needed unconditionally now, so I moved it out without knowing about this side effect. Your approach looks good to me.
Quoted 207 lines
Signed-off-by Ivo van Doorn <[email protected]>
---
net/d80211/ieee80211.c +5
-4@@ -2075,7 +2075,7 @@ void ieee80211_if_shutdown(struct net_decase IEEE80211_IF_TYPE_STA :case IEEE80211_IF_TYPE_IBSS : sdata->u.sta.state =IEEE80211_DISABLED ; -del_timer_sync (&sdata->u.sta.timer); +cancel_delayed_work (&sdata->u.sta.work);if (local->scan_work.data == sdata->dev) { local->sta_scanning =0 ;cancel_delayed_work (&local->scan_work);@@ -2083,7 +2083,8 @@ void ieee80211_if_shutdown(struct net_de/* see comment in ieee80211_unregister_hw to * understand why this works */ local->scan_work.data =NULL ; - } + }else +flush_scheduled_work ();break ; } }@@ -4605,8 +4606,8 @@ void ieee80211_unregister_hw(struct net_flush_scheduled_work ();/* The scan_work is guaranteed not to be called at this * point. It is not scheduled and not running now. It can be -* scheduled again only by some sta_timer (all of them are -* stopped by now) or under rtnl lock. */ +* scheduled again only by sta_work (stopped by now) or under +* rtnl lock. */ }ieee80211_rx_bss_list_deinit (dev);net/d80211/ieee80211_i.h +2
-2@@ -240,7 +240,7 @@ struct ieee80211_if_sta {IEEE80211_ASSOCIATE ,IEEE80211_ASSOCIATED , IEEE80211_IBSS_SEARCH, IEEE80211_IBSS_JOINED } state; -struct timer_list timer; +struct work_struct work;u8 bssid[ETH_ALEN ], prev_bssid[ETH_ALEN ];u8 ssid[IEEE80211_MAX_SSID_LEN ];size_t ssid_len;@@ -621,7 +621,7 @@ int ieee80211_set_compression(struct iee struct net_device *dev, struct sta_info *sta);int ieee80211_init_client (struct net_device *dev);/* ieee80211_sta.c */ -void ieee80211_sta_timer (unsigned long ptr); +void ieee80211_sta_work (void *ptr);void ieee80211_sta_rx_mgmt (struct net_device *dev,struct sk_buff *skb,struct ieee80211_rx_status *rx_status);int ieee80211_sta_set_ssid (struct net_device *dev,char *ssid,size_t len);net/d80211/ieee80211_iface.c +1
-3@@ -194,9 +194,7 @@ void ieee80211_if_set_type(struct net_destruct ieee80211_if_sta *ifsta; ifsta = &sdata->u.sta; -init_timer (&ifsta->timer); - ifsta->timer.data = (unsigned long ) dev; - ifsta->timer.function = ieee80211_sta_timer; +INIT_WORK (&ifsta->work, ieee80211_sta_work, dev); ifsta->capab =WLAN_CAPABILITY_ESS ; ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN |net/d80211/ieee80211_sta.c +19
-20@@ -457,7 +457,7 @@ static void ieee80211_authenticate(strucieee80211_send_auth (dev, ifsta,1 ,NULL ,0 ,0 ); -mod_timer (&ifsta->timer, jiffies +IEEE80211_AUTH_TIMEOUT ); +schedule_delayed_work (&ifsta->work,IEEE80211_AUTH_TIMEOUT ); }@@ -677,7 +677,7 @@ static void ieee80211_associate(struct nieee80211_send_assoc (dev, ifsta); -mod_timer (&ifsta->timer, jiffies +IEEE80211_ASSOC_TIMEOUT ); +schedule_delayed_work (&ifsta->work,IEEE80211_ASSOC_TIMEOUT ); }@@ -735,11 +735,11 @@ static void ieee80211_associated(structmemset (wrqu.ap_addr.sa_data,0 ,ETH_ALEN ); wrqu.ap_addr.sa_family =ARPHRD_ETHER ;wireless_send_event (dev,SIOCGIWAP , &wrqu,NULL ); -mod_timer (&ifsta->timer, - jiffies +IEEE80211_MONITORING_INTERVAL +30 *HZ ); +schedule_delayed_work (&ifsta->work, +IEEE80211_MONITORING_INTERVAL +30 *HZ ); }else { -mod_timer (&ifsta->timer, - jiffies +IEEE80211_MONITORING_INTERVAL ); +schedule_delayed_work (&ifsta->work, +IEEE80211_MONITORING_INTERVAL ); } }@@ -1019,8 +1019,8 @@ static void ieee80211_rx_mgmt_deauth(str ifsta->state == IEEE80211_ASSOCIATE || ifsta->state == IEEE80211_ASSOCIATED) { ifsta->state =IEEE80211_AUTHENTICATE ; -mod_timer (&ifsta->timer, - jiffies +IEEE80211_RETRY_AUTH_INTERVAL ); +schedule_delayed_work (&ifsta->work, +IEEE80211_RETRY_AUTH_INTERVAL ); }ieee80211_set_associated (dev, ifsta,0 );@@ -1062,8 +1062,8 @@ static void ieee80211_rx_mgmt_disassoc(sif (ifsta->state ==IEEE80211_ASSOCIATED ) { ifsta->state =IEEE80211_ASSOCIATE ; -mod_timer (&ifsta->timer, - jiffies +IEEE80211_RETRY_AUTH_INTERVAL ); +schedule_delayed_work (&ifsta->work, +IEEE80211_RETRY_AUTH_INTERVAL ); }ieee80211_set_associated (dev, ifsta,0 );@@ -1829,7 +1829,7 @@ static void ieee80211_sta_expire(structstatic void ieee80211_sta_merge_ibss (struct net_device *dev,struct ieee80211_if_sta *ifsta) { -mod_timer (&ifsta->timer, jiffies +IEEE80211_IBSS_MERGE_INTERVAL ); +schedule_delayed_work (&ifsta->work,IEEE80211_IBSS_MERGE_INTERVAL );ieee80211_sta_expire (dev);if (ieee80211_sta_active_ibss (dev))@@ -1841,20 +1841,19 @@ static void ieee80211_sta_merge_ibss(str } -void ieee80211_sta_timer (unsigned long ptr) +void ieee80211_sta_work (void *ptr) { -struct net_device *dev; +struct net_device *dev = ptr;struct ieee80211_sub_if_data *sdata;struct ieee80211_if_sta *ifsta; - dev = (struct net_device *) ptr;if (!netif_running (dev))return ; sdata =IEEE80211_DEV_TO_SUB_IF (dev);if (sdata->type !=IEEE80211_IF_TYPE_STA && sdata->type !=IEEE80211_IF_TYPE_IBSS ) { -printk (KERN_DEBUG "%s: ieee80211_sta_timer: non-STA interface " +printk (KERN_DEBUG "%s: ieee80211_sta_work: non-STA interface " "(type=%d)\n" , dev->name, sdata->type);return ; }@@ -1879,7 +1878,7 @@ void ieee80211_sta_timer(unsigned long pieee80211_sta_merge_ibss (dev, ifsta);break ;default : -printk (KERN_DEBUG "ieee80211_sta_timer: Unknown state %d\n" , +printk (KERN_DEBUG "ieee80211_sta_work: Unknown state %d\n" , ifsta->state);break ; }@@ -2107,7 +2106,7 @@ static int ieee80211_sta_join_ibss(struc } ifsta->state =IEEE80211_IBSS_JOINED ; -mod_timer (&ifsta->timer, jiffies +IEEE80211_IBSS_MERGE_INTERVAL ); +schedule_delayed_work (&ifsta->work,IEEE80211_IBSS_MERGE_INTERVAL );ieee80211_rx_bss_put (dev, bss);@@ -2224,8 +2223,8 @@ #endif /* CONFIG_D80211_IBSS_DEBUG *//* Selected IBSS not found in current scan results - try to scan */ if (ifsta->state ==IEEE80211_IBSS_JOINED && !ieee80211_sta_active_ibss (dev)) { -mod_timer (&ifsta->timer, - jiffies +IEEE80211_IBSS_MERGE_INTERVAL ); +schedule_delayed_work (&ifsta->work, +IEEE80211_IBSS_MERGE_INTERVAL ); }else if (time_after (jiffies, local->last_scan_completed +IEEE80211_SCAN_INTERVAL )) { printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "@@ -2253,7 +2252,7 @@ #endif /* CONFIG_D80211_IBSS_DEBUG */ } ifsta->state =IEEE80211_IBSS_SEARCH ; -mod_timer (&ifsta->timer, jiffies + interval); +schedule_delayed_work (&ifsta->work, interval);return 0 ; }
Jiri Benc
AppliedQuoted 3 lines · Ivo van Doorn
Would something like the patch below be better?
It keeps theflush_scheduled_work()at the same location, but a second is added in caselocal->scan_work.data!=sdata->dev
Applied to my tree, thanks for the patch!
Jiri
Signature · 2 lines
Jiri Benc SUSE Labs