Ivo van Doorn wrote:
> On Wednesday 18 October 2006 15:06, Jiri Benc wrote:
>> On Sat, 7 Oct 2006 11:23:15 +0200, Ivo van Doorn wrote:
>>> --- a/net/d80211/ieee80211.c
>>> +++ b/net/d80211/ieee80211.c
>>> @@ -2075,15 +2075,15 @@ void ieee80211_if_shutdown(struct net_de
>>>     case 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();
>> This is racy. local->scan_work.data can be set to NULL only after
>> flush_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?

It is needed unconditionally now, so I moved it out without knowing
about this side effect. Your approach looks good to me.

> 
> Signed-off-by Ivo van Doorn <[EMAIL PROTECTED]>
> 
> ---
> 
> diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
> index 32a1ba7..cb1180c 100644
> --- a/net/d80211/ieee80211.c
> +++ b/net/d80211/ieee80211.c
> @@ -2075,7 +2075,7 @@ void ieee80211_if_shutdown(struct net_de
>       case 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);
> diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
> index 89666ec..5b48ce2 100644
> --- a/net/d80211/ieee80211_i.h
> +++ b/net/d80211/ieee80211_i.h
> @@ -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);
> diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
> index 9a187af..4dd480f 100644
> --- a/net/d80211/ieee80211_iface.c
> +++ b/net/d80211/ieee80211_iface.c
> @@ -194,9 +194,7 @@ void ieee80211_if_set_type(struct net_de
>               struct 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 |
> diff --git a/net/d80211/ieee80211_sta.c b/net/d80211/ieee80211_sta.c
> index cc336bd..bf74b6b 100644
> --- a/net/d80211/ieee80211_sta.c
> +++ b/net/d80211/ieee80211_sta.c
> @@ -457,7 +457,7 @@ static void ieee80211_authenticate(struc
>  
>       ieee80211_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 n
>  
>       ieee80211_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(struct 
>               memset(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(s
>  
>       if (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(struct 
>  static 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 p
>               ieee80211_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;
>       }
>  


Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to