From bfa593e478b5ec92be87f5c45fb7747e8431e7ae Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 30 Jan 2013 10:58:01 +0100 Subject: [PATCH] 3.7-stable patches added patches: ath9k_htc-fix-memory-leak.patch dm-raid-fix-raid10-s-check-for-sufficient-redundancy.patch mac80211-fix-ft-roaming.patch mac80211-synchronize-scan-off-on-channel-and-ps-states.patch --- queue-3.7/ath9k_htc-fix-memory-leak.patch | 34 +++ ...10-s-check-for-sufficient-redundancy.patch | 240 ++++++++++++++++++ queue-3.7/mac80211-fix-ft-roaming.patch | 55 ++++ ...ze-scan-off-on-channel-and-ps-states.patch | 156 ++++++++++++ queue-3.7/series | 4 + 5 files changed, 489 insertions(+) create mode 100644 queue-3.7/ath9k_htc-fix-memory-leak.patch create mode 100644 queue-3.7/dm-raid-fix-raid10-s-check-for-sufficient-redundancy.patch create mode 100644 queue-3.7/mac80211-fix-ft-roaming.patch create mode 100644 queue-3.7/mac80211-synchronize-scan-off-on-channel-and-ps-states.patch diff --git a/queue-3.7/ath9k_htc-fix-memory-leak.patch b/queue-3.7/ath9k_htc-fix-memory-leak.patch new file mode 100644 index 00000000000..5d601b4573f --- /dev/null +++ b/queue-3.7/ath9k_htc-fix-memory-leak.patch @@ -0,0 +1,34 @@ +From 0981c3b24ef664f5611008a6e6d0622fac6d892b Mon Sep 17 00:00:00 2001 +From: Sujith Manoharan +Date: Wed, 9 Jan 2013 16:07:48 +0530 +Subject: ath9k_htc: Fix memory leak + +From: Sujith Manoharan + +commit 0981c3b24ef664f5611008a6e6d0622fac6d892b upstream. + +SKBs that are allocated in the HTC layer do not have callbacks +registered and hence ended up not being freed, Fix this by freeing +them properly in the TX completion routine. + +Reported-by: Larry Finger +Signed-off-by: Sujith Manoharan +Tested-by: Larry Finger +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/ath/ath9k/htc_hst.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/wireless/ath/ath9k/htc_hst.c ++++ b/drivers/net/wireless/ath/ath9k/htc_hst.c +@@ -344,6 +344,8 @@ void ath9k_htc_txcompletion_cb(struct ht + endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv, + skb, htc_hdr->endpoint_id, + txok); ++ } else { ++ kfree_skb(skb); + } + } + diff --git a/queue-3.7/dm-raid-fix-raid10-s-check-for-sufficient-redundancy.patch b/queue-3.7/dm-raid-fix-raid10-s-check-for-sufficient-redundancy.patch new file mode 100644 index 00000000000..9cec262b946 --- /dev/null +++ b/queue-3.7/dm-raid-fix-raid10-s-check-for-sufficient-redundancy.patch @@ -0,0 +1,240 @@ +From 55ebbb59c1c6eb1b040f62b8c4ae0b724de6e55a Mon Sep 17 00:00:00 2001 +From: Jonathan Brassow +Date: Tue, 22 Jan 2013 21:42:18 -0600 +Subject: DM-RAID: Fix RAID10's check for sufficient redundancy + +From: Jonathan Brassow + +commit 55ebbb59c1c6eb1b040f62b8c4ae0b724de6e55a upstream. + +Before attempting to activate a RAID array, it is checked for sufficient +redundancy. That is, we make sure that there are not too many failed +devices - or devices specified for rebuild - to undermine our ability to +activate the array. The current code performs this check twice - once to +ensure there were not too many devices specified for rebuild by the user +('validate_rebuild_devices') and again after possibly experiencing a failure +to read the superblock ('analyse_superblocks'). Neither of these checks are +sufficient. The first check is done properly but with insufficient +information about the possible failure state of the devices to make a good +determination if the array can be activated. The second check is simply +done wrong in the case of RAID10 because it doesn't account for the +independence of the stripes (i.e. mirror sets). The solution is to use the +properly written check ('validate_rebuild_devices'), but perform the check +after the superblocks have been read and we know which devices have failed. +This gives us one check instead of two and performs it in a location where +it can be done right. + +Only RAID10 was affected and it was affected in the following ways: +- the code did not properly catch the condition where a user specified + a device for rebuild that already had a failed device in the same mirror + set. (This condition would, however, be caught at a deeper level in MD.) +- the code triggers a false positive and denies activation when devices in + independent mirror sets have failed - counting the failures as though they + were all in the same set. + +The most likely place this error was introduced (or this patch should have +been included) is in commit 4ec1e369 - first introduced in v3.7-rc1. +Consequently this fix should also go in v3.7.y, however there is a +small conflict on the .version in raid_target, so I'll submit a +separate patch to -stable. + +Signed-off-by: Jonathan Brassow +Signed-off-by: NeilBrown +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/device-mapper/dm-raid.txt | 1 + drivers/md/dm-raid.c | 101 +++++++++++--------------------- + 2 files changed, 38 insertions(+), 64 deletions(-) + +--- a/Documentation/device-mapper/dm-raid.txt ++++ b/Documentation/device-mapper/dm-raid.txt +@@ -141,3 +141,4 @@ Version History + 1.2.0 Handle creation of arrays that contain failed devices. + 1.3.0 Added support for RAID 10 + 1.3.1 Allow device replacement/rebuild for RAID 10 ++1.3.2 Fix/improve redundancy checking for RAID10 +--- a/drivers/md/dm-raid.c ++++ b/drivers/md/dm-raid.c +@@ -338,24 +338,22 @@ static int validate_region_size(struct r + } + + /* +- * validate_rebuild_devices ++ * validate_raid_redundancy + * @rs + * +- * Determine if the devices specified for rebuild can result in a valid +- * usable array that is capable of rebuilding the given devices. ++ * Determine if there are enough devices in the array that haven't ++ * failed (or are being rebuilt) to form a usable array. + * + * Returns: 0 on success, -EINVAL on failure. + */ +-static int validate_rebuild_devices(struct raid_set *rs) ++static int validate_raid_redundancy(struct raid_set *rs) + { + unsigned i, rebuild_cnt = 0; + unsigned rebuilds_per_group, copies, d; + +- if (!(rs->print_flags & DMPF_REBUILD)) +- return 0; +- + for (i = 0; i < rs->md.raid_disks; i++) +- if (!test_bit(In_sync, &rs->dev[i].rdev.flags)) ++ if (!test_bit(In_sync, &rs->dev[i].rdev.flags) || ++ !rs->dev[i].rdev.sb_page) + rebuild_cnt++; + + switch (rs->raid_type->level) { +@@ -391,27 +389,24 @@ static int validate_rebuild_devices(stru + * A A B B C + * C D D E E + */ +- rebuilds_per_group = 0; + for (i = 0; i < rs->md.raid_disks * copies; i++) { ++ if (!(i % copies)) ++ rebuilds_per_group = 0; + d = i % rs->md.raid_disks; +- if (!test_bit(In_sync, &rs->dev[d].rdev.flags) && ++ if ((!rs->dev[d].rdev.sb_page || ++ !test_bit(In_sync, &rs->dev[d].rdev.flags)) && + (++rebuilds_per_group >= copies)) + goto too_many; +- if (!((i + 1) % copies)) +- rebuilds_per_group = 0; + } + break; + default: +- DMERR("The rebuild parameter is not supported for %s", +- rs->raid_type->name); +- rs->ti->error = "Rebuild not supported for this RAID type"; +- return -EINVAL; ++ if (rebuild_cnt) ++ return -EINVAL; + } + + return 0; + + too_many: +- rs->ti->error = "Too many rebuild devices specified"; + return -EINVAL; + } + +@@ -662,9 +657,6 @@ static int parse_raid_params(struct raid + } + rs->md.dev_sectors = sectors_per_dev; + +- if (validate_rebuild_devices(rs)) +- return -EINVAL; +- + /* Assume there are no metadata devices until the drives are parsed */ + rs->md.persistent = 0; + rs->md.external = 1; +@@ -993,28 +985,10 @@ static int super_validate(struct mddev * + static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) + { + int ret; +- unsigned redundancy = 0; + struct raid_dev *dev; + struct md_rdev *rdev, *tmp, *freshest; + struct mddev *mddev = &rs->md; + +- switch (rs->raid_type->level) { +- case 1: +- redundancy = rs->md.raid_disks - 1; +- break; +- case 4: +- case 5: +- case 6: +- redundancy = rs->raid_type->parity_devs; +- break; +- case 10: +- redundancy = raid10_md_layout_to_copies(mddev->layout) - 1; +- break; +- default: +- ti->error = "Unknown RAID type"; +- return -EINVAL; +- } +- + freshest = NULL; + rdev_for_each_safe(rdev, tmp, mddev) { + /* +@@ -1043,44 +1017,43 @@ static int analyse_superblocks(struct dm + break; + default: + dev = container_of(rdev, struct raid_dev, rdev); +- if (redundancy--) { +- if (dev->meta_dev) +- dm_put_device(ti, dev->meta_dev); ++ if (dev->meta_dev) ++ dm_put_device(ti, dev->meta_dev); + +- dev->meta_dev = NULL; +- rdev->meta_bdev = NULL; ++ dev->meta_dev = NULL; ++ rdev->meta_bdev = NULL; + +- if (rdev->sb_page) +- put_page(rdev->sb_page); ++ if (rdev->sb_page) ++ put_page(rdev->sb_page); + +- rdev->sb_page = NULL; ++ rdev->sb_page = NULL; + +- rdev->sb_loaded = 0; ++ rdev->sb_loaded = 0; + +- /* +- * We might be able to salvage the data device +- * even though the meta device has failed. For +- * now, we behave as though '- -' had been +- * set for this device in the table. +- */ +- if (dev->data_dev) +- dm_put_device(ti, dev->data_dev); +- +- dev->data_dev = NULL; +- rdev->bdev = NULL; ++ /* ++ * We might be able to salvage the data device ++ * even though the meta device has failed. For ++ * now, we behave as though '- -' had been ++ * set for this device in the table. ++ */ ++ if (dev->data_dev) ++ dm_put_device(ti, dev->data_dev); + +- list_del(&rdev->same_set); ++ dev->data_dev = NULL; ++ rdev->bdev = NULL; + +- continue; +- } +- ti->error = "Failed to load superblock"; +- return ret; ++ list_del(&rdev->same_set); + } + } + + if (!freshest) + return 0; + ++ if (validate_raid_redundancy(rs)) { ++ rs->ti->error = "Insufficient redundancy to activate array"; ++ return -EINVAL; ++ } ++ + /* + * Validation of the freshest device provides the source of + * validation for the remaining devices. +@@ -1430,7 +1403,7 @@ static void raid_resume(struct dm_target + + static struct target_type raid_target = { + .name = "raid", +- .version = {1, 3, 1}, ++ .version = {1, 3, 2}, + .module = THIS_MODULE, + .ctr = raid_ctr, + .dtr = raid_dtr, diff --git a/queue-3.7/mac80211-fix-ft-roaming.patch b/queue-3.7/mac80211-fix-ft-roaming.patch new file mode 100644 index 00000000000..23f11d36306 --- /dev/null +++ b/queue-3.7/mac80211-fix-ft-roaming.patch @@ -0,0 +1,55 @@ +From 1626e0fa740dec8665a973cf2349405cdfeb46dc Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Fri, 11 Jan 2013 14:34:25 +0100 +Subject: mac80211: fix FT roaming + +From: Johannes Berg + +commit 1626e0fa740dec8665a973cf2349405cdfeb46dc upstream. + +During FT roaming, wpa_supplicant attempts to set the +key before association. This used to be rejected, but +as a side effect of my commit 66e67e418908442389d3a9e +("mac80211: redesign auth/assoc") the key was accepted +causing hardware crypto to not be used for it as the +station isn't added to the driver yet. + +It would be possible to accept the key and then add it +to the driver when the station has been added. However, +this may run into issues with drivers using the state- +based station adding if they accept the key only after +association like it used to be. + +For now, revert to the behaviour from before the auth +and assoc change. + +Reported-by: Cédric Debarge +Tested-by: Cédric Debarge +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/cfg.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -164,7 +164,17 @@ static int ieee80211_add_key(struct wiph + sta = sta_info_get(sdata, mac_addr); + else + sta = sta_info_get_bss(sdata, mac_addr); +- if (!sta) { ++ /* ++ * The ASSOC test makes sure the driver is ready to ++ * receive the key. When wpa_supplicant has roamed ++ * using FT, it attempts to set the key before ++ * association has completed, this rejects that attempt ++ * so it will set the key again after assocation. ++ * ++ * TODO: accept the key if we have a station entry and ++ * add it to the device after the station. ++ */ ++ if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) { + ieee80211_key_free(sdata->local, key); + err = -ENOENT; + goto out_unlock; diff --git a/queue-3.7/mac80211-synchronize-scan-off-on-channel-and-ps-states.patch b/queue-3.7/mac80211-synchronize-scan-off-on-channel-and-ps-states.patch new file mode 100644 index 00000000000..bceb66bf1e7 --- /dev/null +++ b/queue-3.7/mac80211-synchronize-scan-off-on-channel-and-ps-states.patch @@ -0,0 +1,156 @@ +From aacde9ee45225f7e0b90960f479aef83c66bfdc0 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Thu, 20 Dec 2012 14:41:18 +0100 +Subject: mac80211: synchronize scan off/on-channel and PS states + +From: Stanislaw Gruszka + +commit aacde9ee45225f7e0b90960f479aef83c66bfdc0 upstream. + +Since: + +commit b23b025fe246f3acc2988eb6d400df34c27cb8ae +Author: Ben Greear +Date: Fri Feb 4 11:54:17 2011 -0800 + + mac80211: Optimize scans on current operating channel. + +we do not disable PS while going back to operational channel (on +ieee80211_scan_state_suspend) and deffer that until scan finish. +But since we are allowed to send frames, we can send a frame to AP +without PM bit set, so disable PS on AP side. Then when we switch +to off-channel (in ieee80211_scan_state_resume) we do not enable PS. +Hence we are off-channel with PS disabled, frames are not buffered +by AP. + +To fix remove offchannel_ps_disable argument and always enable PS when +going off-channel and disable it when going on-channel, like it was +before. + +Signed-off-by: Stanislaw Gruszka +Tested-by: Seth Forshee +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/ieee80211_i.h | 6 ++---- + net/mac80211/offchannel.c | 19 +++++++------------ + net/mac80211/scan.c | 15 +++++---------- + 3 files changed, 14 insertions(+), 26 deletions(-) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1279,10 +1279,8 @@ int ieee80211_request_sched_scan_stop(st + void ieee80211_sched_scan_stopped_work(struct work_struct *work); + + /* off-channel helpers */ +-void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, +- bool offchannel_ps_enable); +-void ieee80211_offchannel_return(struct ieee80211_local *local, +- bool offchannel_ps_disable); ++void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local); ++void ieee80211_offchannel_return(struct ieee80211_local *local); + void ieee80211_roc_setup(struct ieee80211_local *local); + void ieee80211_start_next_roc(struct ieee80211_local *local); + void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); +--- a/net/mac80211/offchannel.c ++++ b/net/mac80211/offchannel.c +@@ -102,8 +102,7 @@ static void ieee80211_offchannel_ps_disa + ieee80211_sta_reset_conn_monitor(sdata); + } + +-void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, +- bool offchannel_ps_enable) ++void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local) + { + struct ieee80211_sub_if_data *sdata; + +@@ -131,8 +130,7 @@ void ieee80211_offchannel_stop_vifs(stru + + if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { + netif_tx_stop_all_queues(sdata->dev); +- if (offchannel_ps_enable && +- (sdata->vif.type == NL80211_IFTYPE_STATION) && ++ if (sdata->vif.type == NL80211_IFTYPE_STATION && + sdata->u.mgd.associated) + ieee80211_offchannel_ps_enable(sdata); + } +@@ -140,8 +138,7 @@ void ieee80211_offchannel_stop_vifs(stru + mutex_unlock(&local->iflist_mtx); + } + +-void ieee80211_offchannel_return(struct ieee80211_local *local, +- bool offchannel_ps_disable) ++void ieee80211_offchannel_return(struct ieee80211_local *local) + { + struct ieee80211_sub_if_data *sdata; + +@@ -157,11 +154,9 @@ void ieee80211_offchannel_return(struct + continue; + + /* Tell AP we're back */ +- if (offchannel_ps_disable && +- sdata->vif.type == NL80211_IFTYPE_STATION) { +- if (sdata->u.mgd.associated) +- ieee80211_offchannel_ps_disable(sdata); +- } ++ if (sdata->vif.type == NL80211_IFTYPE_STATION && ++ sdata->u.mgd.associated) ++ ieee80211_offchannel_ps_disable(sdata); + + if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { + /* +@@ -381,7 +376,7 @@ void ieee80211_sw_roc_work(struct work_s + local->tmp_channel = NULL; + ieee80211_hw_config(local, 0); + +- ieee80211_offchannel_return(local, true); ++ ieee80211_offchannel_return(local); + } + + ieee80211_recalc_idle(local); +--- a/net/mac80211/scan.c ++++ b/net/mac80211/scan.c +@@ -310,7 +310,7 @@ static void __ieee80211_scan_completed(s + if (!was_hw_scan) { + ieee80211_configure_filter(local); + drv_sw_scan_complete(local); +- ieee80211_offchannel_return(local, true); ++ ieee80211_offchannel_return(local); + } + + ieee80211_recalc_idle(local); +@@ -355,7 +355,7 @@ static int ieee80211_start_sw_scan(struc + local->next_scan_state = SCAN_DECISION; + local->scan_channel_idx = 0; + +- ieee80211_offchannel_stop_vifs(local, true); ++ ieee80211_offchannel_stop_vifs(local); + + ieee80211_configure_filter(local); + +@@ -680,12 +680,8 @@ static void ieee80211_scan_state_suspend + local->scan_channel = NULL; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); + +- /* +- * Re-enable vifs and beaconing. Leave PS +- * in off-channel state..will put that back +- * on-channel at the end of scanning. +- */ +- ieee80211_offchannel_return(local, false); ++ /* disable PS */ ++ ieee80211_offchannel_return(local); + + *next_delay = HZ / 5; + /* afterwards, resume scan & go to next channel */ +@@ -695,8 +691,7 @@ static void ieee80211_scan_state_suspend + static void ieee80211_scan_state_resume(struct ieee80211_local *local, + unsigned long *next_delay) + { +- /* PS already is in off-channel mode */ +- ieee80211_offchannel_stop_vifs(local, false); ++ ieee80211_offchannel_stop_vifs(local); + + if (local->ops->flush) { + drv_flush(local, false); diff --git a/queue-3.7/series b/queue-3.7/series index 1eebfd9fc3e..2339f6046bf 100644 --- a/queue-3.7/series +++ b/queue-3.7/series @@ -28,3 +28,7 @@ mwifiex-fix-typo-in-pcie-adapter-null-check.patch iwlegacy-fix-ibss-cleanup.patch brcmsmac-increase-timer-reference-count-for-new-timers-only.patch brcmsmac-handle-packet-drop-during-transmit-correctly.patch +dm-raid-fix-raid10-s-check-for-sufficient-redundancy.patch +mac80211-synchronize-scan-off-on-channel-and-ps-states.patch +mac80211-fix-ft-roaming.patch +ath9k_htc-fix-memory-leak.patch -- 2.47.3