Skip to content

Commit 3eb0928

Browse files
Manoharan, Rajkumarjmberg-intel
authored andcommitted
mac80211: use DECLARE_EWMA for mesh_fail_avg
As moving average is not considering fractional part, it will get stuck at the same level after certain state. For example, with current values, it can get stuck at 96. Fortunately the current threshold 95%, but if it were increased to 96 or more mesh paths would never be deactivated. Fix failure average movement by using EWMA helpers, which does take into account fractional parts. Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com> [johannes: pick a larger EWMA factor for more precision with the limited range that we will feed into it, adjust to new API] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
1 parent 8d70eeb commit 3eb0928

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

net/mac80211/mesh_hwmp.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -307,10 +307,11 @@ void ieee80211s_update_metric(struct ieee80211_local *local,
307307

308308
failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK);
309309

310-
/* moving average, scaled to 100 */
311-
sta->mesh->fail_avg =
312-
((80 * sta->mesh->fail_avg + 5) / 100 + 20 * failed);
313-
if (sta->mesh->fail_avg > 95)
310+
/* moving average, scaled to 100.
311+
* feed failure as 100 and success as 0
312+
*/
313+
ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, failed * 100);
314+
if (ewma_mesh_fail_avg_read(&sta->mesh->fail_avg) > 95)
314315
mesh_plink_broken(sta);
315316
}
316317

@@ -325,6 +326,8 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
325326
int rate, err;
326327
u32 tx_time, estimated_retx;
327328
u64 result;
329+
unsigned long fail_avg =
330+
ewma_mesh_fail_avg_read(&sta->mesh->fail_avg);
328331

329332
/* Try to get rate based on HW/SW RC algorithm.
330333
* Rate is returned in units of Kbps, correct this
@@ -336,15 +339,15 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
336339
if (rate) {
337340
err = 0;
338341
} else {
339-
if (sta->mesh->fail_avg >= 100)
342+
if (fail_avg >= 100)
340343
return MAX_METRIC;
341344

342345
sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &rinfo);
343346
rate = cfg80211_calculate_bitrate(&rinfo);
344347
if (WARN_ON(!rate))
345348
return MAX_METRIC;
346349

347-
err = (sta->mesh->fail_avg << ARITH_SHIFT) / 100;
350+
err = (fail_avg << ARITH_SHIFT) / 100;
348351
}
349352

350353
/* bitrate is in units of 100 Kbps, while we need rate in units of
@@ -484,6 +487,9 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
484487
? mpath->exp_time : exp_time;
485488
mesh_path_activate(mpath);
486489
spin_unlock_bh(&mpath->state_lock);
490+
ewma_mesh_fail_avg_init(&sta->mesh->fail_avg);
491+
/* init it at a low value - 0 start is tricky */
492+
ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1);
487493
mesh_path_tx_pending(mpath);
488494
/* draft says preq_id should be saved to, but there does
489495
* not seem to be any use for it, skipping by now
@@ -522,6 +528,9 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
522528
? mpath->exp_time : exp_time;
523529
mesh_path_activate(mpath);
524530
spin_unlock_bh(&mpath->state_lock);
531+
ewma_mesh_fail_avg_init(&sta->mesh->fail_avg);
532+
/* init it at a low value - 0 start is tricky */
533+
ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1);
525534
mesh_path_tx_pending(mpath);
526535
} else
527536
spin_unlock_bh(&mpath->state_lock);

net/mac80211/mesh_pathtbl.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,9 @@ void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop)
829829
mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID;
830830
mesh_path_activate(mpath);
831831
spin_unlock_bh(&mpath->state_lock);
832+
ewma_mesh_fail_avg_init(&next_hop->mesh->fail_avg);
833+
/* init it at a low value - 0 start is tricky */
834+
ewma_mesh_fail_avg_add(&next_hop->mesh->fail_avg, 1);
832835
mesh_path_tx_pending(mpath);
833836
}
834837

net/mac80211/sta_info.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,9 @@ struct ieee80211_fast_rx {
324324
struct rcu_head rcu_head;
325325
};
326326

327+
/* we use only values in the range 0-100, so pick a large precision */
328+
DECLARE_EWMA(mesh_fail_avg, 20, 8)
329+
327330
/**
328331
* struct mesh_sta - mesh STA information
329332
* @plink_lock: serialize access to plink fields
@@ -369,7 +372,7 @@ struct mesh_sta {
369372
enum nl80211_mesh_power_mode nonpeer_pm;
370373

371374
/* moving percentage of failed MSDUs */
372-
unsigned int fail_avg;
375+
struct ewma_mesh_fail_avg fail_avg;
373376
};
374377

375378
DECLARE_EWMA(signal, 10, 8)

0 commit comments

Comments
 (0)