Message ID | 20140905214331.GE17986@wotan.suse.de (mailing list archive) |
---|---|
State | Not Applicable, archived |
Headers | show |
Hi, On Fri, Sep 5, 2014 at 11:43 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote: > Yeah this seems to be a corner case of the fact that we deal with > locking for the last request only through RCU and we only annotate > that the request was processed but don't add checks for when its > about to be processed. At least that's what I gather could be > the issue here given that if you see __reg_process_hint_driver() > we already check for two driver hints matching and and just > request the core to copy the existing regulatory domain onto > the new device. > > if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && > !regdom_changes(driver_request->alpha2)) > return REG_REQ_ALREADY_SET; > > return REG_REQ_INTERSECT; > > The intersection would happen otherwise and I think this is caused > by a small race here. Can you try the following: Just retried with your patch applied but I can still get an "98" intersected regdomain :( [ 6.190000] ath: EEPROM regdomain: 0x0 [ 6.190000] ath: EEPROM indicates default country code should be used [ 6.190000] ath: doing EEPROM country->regdmn map search [ 6.190000] ath: country maps to regdmn code: 0x3a [ 6.190000] ath: Country alpha2 being used: US [ 6.190000] ath: Regpair used: 0x3a [ 6.200000] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht' [ 6.210000] ieee80211 phy0: Atheros AR9340 Rev:0 mem=0xb8100000, irq=47 [ 6.210000] PCI: Enabling device 0000:00:00.0 (0000 -> 0002) [ 6.210000] ath: EEPROM regdomain: 0x0 [ 6.210000] ath: EEPROM indicates default country code should be used [ 6.210000] ath: doing EEPROM country->regdmn map search [ 6.210000] ath: country maps to regdmn code: 0x3a [ 6.210000] ath: Country alpha2 being used: US [ 6.210000] ath: Regpair used: 0x3a [ 6.220000] ieee80211 phy1: Selected rate control algorithm 'minstrel_ht' [ 6.240000] cfg80211: Calling CRDA for country: US [ 6.240000] cfg80211: Calling CRDA for country: US [ 6.240000] cfg80211: Current regulatory domain intersected: [ 6.240000] cfg80211: DFS Master region: unset [ 6.240000] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time) [ 6.240000] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A) [ 6.240000] cfg80211: (2457000 KHz - 2472000 KHz @ 15000 KHz), (N/A, 2000 mBm), (N/A) [ 6.240000] cfg80211: (5170000 KHz - 5250000 KHz @ 80000 KHz), (N/A, 1700 mBm), (N/A) [ 6.240000] cfg80211: (5250000 KHz - 5330000 KHz @ 80000 KHz), (N/A, 2000 mBm), (0 s) [ 6.240000] cfg80211: (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A) [ 6.240000] cfg80211: (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm), (N/A) [ 6.240000] cfg80211: Calling CRDA for country: US [ 6.240000] ieee80211 phy1: Atheros AR9300 Rev:3 mem=0xb0000000, irq=40 [ 6.240000] cfg80211: Current regulatory domain intersected: [ 6.240000] cfg80211: DFS Master region: unset [ 6.240000] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time) [ 6.240000] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A) [ 6.240000] cfg80211: (2457000 KHz - 2472000 KHz @ 15000 KHz), (N/A, 2000 mBm), (N/A) [ 6.240000] cfg80211: (5170000 KHz - 5250000 KHz @ 80000 KHz), (N/A, 1700 mBm), (N/A) [ 6.240000] cfg80211: (5250000 KHz - 5330000 KHz @ 80000 KHz), (N/A, 2000 mBm), (0 s) [ 6.240000] cfg80211: (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A) [ 6.240000] cfg80211: (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm), (N/A) I'll try to dive deeper into the regulatory code ... Helmut -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, Sep 08, 2014 at 11:59:39AM +0200, Helmut Schaa wrote: > Hi, > > On Fri, Sep 5, 2014 at 11:43 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote: > > Yeah this seems to be a corner case of the fact that we deal with > > locking for the last request only through RCU and we only annotate > > that the request was processed but don't add checks for when its > > about to be processed. At least that's what I gather could be > > the issue here given that if you see __reg_process_hint_driver() > > we already check for two driver hints matching and and just > > request the core to copy the existing regulatory domain onto > > the new device. > > > > if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && > > !regdom_changes(driver_request->alpha2)) > > return REG_REQ_ALREADY_SET; > > > > return REG_REQ_INTERSECT; > > > > The intersection would happen otherwise and I think this is caused > > by a small race here. Can you try the following: > > Just retried with your patch applied but I can still get an "98" > intersected regdomain :( > > [ 6.190000] ath: EEPROM regdomain: 0x0 > [ 6.190000] ath: EEPROM indicates default country code should be > used > [ 6.190000] ath: doing EEPROM country->regdmn map search > [ 6.190000] ath: country maps to regdmn code: 0x3a > [ 6.190000] ath: Country alpha2 being used: US > [ 6.190000] ath: Regpair used: 0x3a > [ 6.200000] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht' > [ 6.210000] ieee80211 phy0: Atheros AR9340 Rev:0 mem=0xb8100000, irq=47 > [ 6.210000] PCI: Enabling device 0000:00:00.0 (0000 -> 0002) > [ 6.210000] ath: EEPROM regdomain: 0x0 > [ 6.210000] ath: EEPROM indicates default country code should be used > [ 6.210000] ath: doing EEPROM country->regdmn map search > [ 6.210000] ath: country maps to regdmn code: 0x3a > [ 6.210000] ath: Country alpha2 being used: US > [ 6.210000] ath: Regpair used: 0x3a > [ 6.220000] ieee80211 phy1: Selected rate control algorithm 'minstrel_ht' > [ 6.240000] cfg80211: Calling CRDA for country: US > [ 6.240000] cfg80211: Calling CRDA for country: US > [ 6.240000] cfg80211: Current regulatory domain intersected: > [ 6.240000] cfg80211: DFS Master region: unset > [ 6.240000] cfg80211: (start_freq - end_freq @ bandwidth), > (max_antenna_gain, max_eirp), (dfs_cac_time) > [ 6.240000] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), > (N/A, 2000 mBm), (N/A) > [ 6.240000] cfg80211: (2457000 KHz - 2472000 KHz @ 15000 KHz), > (N/A, 2000 mBm), (N/A) > [ 6.240000] cfg80211: (5170000 KHz - 5250000 KHz @ 80000 KHz), > (N/A, 1700 mBm), (N/A) > [ 6.240000] cfg80211: (5250000 KHz - 5330000 KHz @ 80000 KHz), > (N/A, 2000 mBm), (0 s) > [ 6.240000] cfg80211: (5735000 KHz - 5835000 KHz @ 80000 KHz), > (N/A, 2000 mBm), (N/A) > [ 6.240000] cfg80211: (57240000 KHz - 63720000 KHz @ 2160000 > KHz), (N/A, 0 mBm), (N/A) > [ 6.240000] cfg80211: Calling CRDA for country: US > [ 6.240000] ieee80211 phy1: Atheros AR9300 Rev:3 mem=0xb0000000, irq=40 > [ 6.240000] cfg80211: Current regulatory domain intersected: > [ 6.240000] cfg80211: DFS Master region: unset > [ 6.240000] cfg80211: (start_freq - end_freq @ bandwidth), > (max_antenna_gain, max_eirp), (dfs_cac_time) > [ 6.240000] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), > (N/A, 2000 mBm), (N/A) > [ 6.240000] cfg80211: (2457000 KHz - 2472000 KHz @ 15000 KHz), > (N/A, 2000 mBm), (N/A) > [ 6.240000] cfg80211: (5170000 KHz - 5250000 KHz @ 80000 KHz), > (N/A, 1700 mBm), (N/A) > [ 6.240000] cfg80211: (5250000 KHz - 5330000 KHz @ 80000 KHz), > (N/A, 2000 mBm), (0 s) > [ 6.240000] cfg80211: (5735000 KHz - 5835000 KHz @ 80000 KHz), > (N/A, 2000 mBm), (N/A) > [ 6.240000] cfg80211: (57240000 KHz - 63720000 KHz @ 2160000 > KHz), (N/A, 0 mBm), (N/A) > > I'll try to dive deeper into the regulatory code ... OK thanks I appreciate that, it will take me a bit to get back to this as this week and the next few weeks will be really busy and I will be traveling. Luis -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/include/net/regulatory.h b/include/net/regulatory.h index 2599924..f3011d8 100644 --- a/include/net/regulatory.h +++ b/include/net/regulatory.h @@ -67,6 +67,10 @@ enum environment_cap { * CRDA and can be used by other regulatory requests. When a * the last request is not yet processed we must yield until it * is processed before processing any new requests. + * @processing: tells the regulatory core if the request is currently + * being processed. This is used to avoid contention on processing + * a request twice since we treat only the last request atomically + * with RCU. * @country_ie_checksum: checksum of the last processed and accepted * country IE * @country_ie_env: lets us know if the AP is telling us we are outdoor, @@ -82,6 +86,7 @@ struct regulatory_request { enum nl80211_dfs_regions dfs_region; bool intersect; bool processed; + bool processing; enum environment_cap country_ie_env; struct list_head list; }; diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 1afdf45..ae35385 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1912,7 +1912,7 @@ static void reg_process_pending_hints(void) lr = get_last_request(); /* When last_request->processed becomes true this will be rescheduled */ - if (lr && !lr->processed) { + if (lr && !lr->processed && !lr->processing) { reg_process_hint(lr); return; } @@ -2595,6 +2595,7 @@ int set_regdom(const struct ieee80211_regdomain *rd) } lr = get_last_request(); + lr->processing = true; /* Note that this doesn't update the wiphys, this is done below */ switch (lr->initiator) {