iwlwifi: use consistent table for tx data collect

When collecting tx data for non-aggregation packets in rate scaling, if
the tx data matches "other table", it still uses current table to update
the stats and calculate average throughput in function rs_collect_tx_data().
This can mess up the rate scaling data structure and cause a kernel panic
in a BUG_ON statement in rs_rate_scale_perform().

To fix this bug, we pass table pointer instead of window pointer (pointed
to by table pointer) to function rs_collect_tx_data() so that the table
being used is consistent.

Signed-off-by: Shanyu Zhao <shanyu.zhao@intel.com>
Signed-off-by: Henry Zhang <hongx.c.zhang@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>

authored by Shanyu Zhao and committed by Reinette Chatre 04f2dec1 dd487449

+24 -31
+24 -31
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
··· 345 345 !!(rate_n_flags & RATE_MCS_ANT_C_MSK); 346 346 } 347 347 348 + /* 349 + * Static function to get the expected throughput from an iwl_scale_tbl_info 350 + * that wraps a NULL pointer check 351 + */ 352 + static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) 353 + { 354 + if (tbl->expected_tpt) 355 + return tbl->expected_tpt[rs_index]; 356 + return 0; 357 + } 358 + 348 359 /** 349 360 * rs_collect_tx_data - Update the success/failure sliding window 350 361 * ··· 363 352 * at this rate. window->data contains the bitmask of successful 364 353 * packets. 365 354 */ 366 - static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, 367 - int scale_index, s32 tpt, int attempts, 368 - int successes) 355 + static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl, 356 + int scale_index, int attempts, int successes) 369 357 { 370 358 struct iwl_rate_scale_data *window = NULL; 371 359 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1)); 372 - s32 fail_count; 360 + s32 fail_count, tpt; 373 361 374 362 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) 375 363 return -EINVAL; 376 364 377 365 /* Select window for current tx bit rate */ 378 - window = &(windows[scale_index]); 366 + window = &(tbl->win[scale_index]); 367 + 368 + /* Get expected throughput */ 369 + tpt = get_expected_tpt(tbl, scale_index); 379 370 380 371 /* 381 372 * Keep track of only the latest 62 tx frame attempts in this rate's ··· 751 738 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && 752 739 (a->is_SGI == b->is_SGI); 753 740 } 754 - /* 755 - * Static function to get the expected throughput from an iwl_scale_tbl_info 756 - * that wraps a NULL pointer check 757 - */ 758 - static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) 759 - { 760 - if (tbl->expected_tpt) 761 - return tbl->expected_tpt[rs_index]; 762 - return 0; 763 - } 764 741 765 742 /* 766 743 * mac80211 sends us Tx status ··· 767 764 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 768 765 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 769 766 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 770 - struct iwl_rate_scale_data *window = NULL; 771 767 enum mac80211_rate_control_flags mac_flags; 772 768 u32 tx_rate; 773 769 struct iwl_scale_tbl_info tbl_type; 774 - struct iwl_scale_tbl_info *curr_tbl, *other_tbl; 775 - s32 tpt = 0; 770 + struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; 776 771 777 772 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); 778 773 ··· 853 852 IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n"); 854 853 return; 855 854 } 856 - window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]); 857 855 858 856 /* 859 857 * Updating the frame history depends on whether packets were ··· 865 865 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); 866 866 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, 867 867 &rs_index); 868 - tpt = get_expected_tpt(curr_tbl, rs_index); 869 - rs_collect_tx_data(window, rs_index, tpt, 868 + rs_collect_tx_data(curr_tbl, rs_index, 870 869 info->status.ampdu_ack_len, 871 870 info->status.ampdu_ack_map); 872 871 ··· 895 896 * table as active/search. 896 897 */ 897 898 if (table_type_matches(&tbl_type, curr_tbl)) 898 - tpt = get_expected_tpt(curr_tbl, rs_index); 899 + tmp_tbl = curr_tbl; 899 900 else if (table_type_matches(&tbl_type, other_tbl)) 900 - tpt = get_expected_tpt(other_tbl, rs_index); 901 + tmp_tbl = other_tbl; 901 902 else 902 903 continue; 903 - 904 - /* Constants mean 1 transmission, 0 successes */ 905 - if (i < retries) 906 - rs_collect_tx_data(window, rs_index, tpt, 1, 907 - 0); 908 - else 909 - rs_collect_tx_data(window, rs_index, tpt, 1, 910 - legacy_success); 904 + rs_collect_tx_data(tmp_tbl, rs_index, 1, 905 + i < retries ? 0 : legacy_success); 911 906 } 912 907 913 908 /* Update success/fail counts if not searching for new mode */