|
| 1 | +From: Sven Eckelmann < [email protected]> |
| 2 | +Date: Wed, 22 Jan 2025 21:51:20 +0100 |
| 3 | +Subject: batman-adv: Ignore neighbor throughput metrics in error case |
| 4 | + |
| 5 | +If a temporary error happened in the evaluation of the neighbor throughput |
| 6 | +information, then the invalid throughput result should not be stored in the |
| 7 | +throughtput EWMA. |
| 8 | + |
| 9 | +Signed-off-by: Sven Eckelmann < [email protected]> |
| 10 | +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/ce8b40b7bdcc7f011191acda4c2d3067566eef54 |
| 11 | + |
| 12 | +--- a/net/batman-adv/bat_v_elp.c |
| 13 | ++++ b/net/batman-adv/bat_v_elp.c |
| 14 | +@@ -59,11 +59,13 @@ static void batadv_v_elp_start_timer(str |
| 15 | + /** |
| 16 | + * batadv_v_elp_get_throughput() - get the throughput towards a neighbour |
| 17 | + * @neigh: the neighbour for which the throughput has to be obtained |
| 18 | ++ * @pthroughput: calculated throughput towards the given neighbour in multiples |
| 19 | ++ * of 100kpbs (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc). |
| 20 | + * |
| 21 | +- * Return: The throughput towards the given neighbour in multiples of 100kpbs |
| 22 | +- * (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc). |
| 23 | ++ * Return: true when value behind @pthroughput was set |
| 24 | + */ |
| 25 | +-static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) |
| 26 | ++static bool batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh, |
| 27 | ++ u32 *pthroughput) |
| 28 | + { |
| 29 | + struct batadv_hard_iface *hard_iface = neigh->if_incoming; |
| 30 | + struct net_device *soft_iface = hard_iface->soft_iface; |
| 31 | +@@ -77,14 +79,16 @@ static u32 batadv_v_elp_get_throughput(s |
| 32 | + * batman-adv interface |
| 33 | + */ |
| 34 | + if (!soft_iface) |
| 35 | +- return BATADV_THROUGHPUT_DEFAULT_VALUE; |
| 36 | ++ return false; |
| 37 | + |
| 38 | + /* if the user specified a customised value for this interface, then |
| 39 | + * return it directly |
| 40 | + */ |
| 41 | + throughput = atomic_read(&hard_iface->bat_v.throughput_override); |
| 42 | +- if (throughput != 0) |
| 43 | +- return throughput; |
| 44 | ++ if (throughput != 0) { |
| 45 | ++ *pthroughput = throughput; |
| 46 | ++ return true; |
| 47 | ++ } |
| 48 | + |
| 49 | + /* if this is a wireless device, then ask its throughput through |
| 50 | + * cfg80211 API |
| 51 | +@@ -111,19 +115,24 @@ static u32 batadv_v_elp_get_throughput(s |
| 52 | + * possible to delete this neighbor. For now set |
| 53 | + * the throughput metric to 0. |
| 54 | + */ |
| 55 | +- return 0; |
| 56 | ++ *pthroughput = 0; |
| 57 | ++ return true; |
| 58 | + } |
| 59 | + if (ret) |
| 60 | + goto default_throughput; |
| 61 | + |
| 62 | +- if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)) |
| 63 | +- return sinfo.expected_throughput / 100; |
| 64 | ++ if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)) { |
| 65 | ++ *pthroughput = sinfo.expected_throughput / 100; |
| 66 | ++ return true; |
| 67 | ++ } |
| 68 | + |
| 69 | + /* try to estimate the expected throughput based on reported tx |
| 70 | + * rates |
| 71 | + */ |
| 72 | +- if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)) |
| 73 | +- return cfg80211_calculate_bitrate(&sinfo.txrate) / 3; |
| 74 | ++ if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)) { |
| 75 | ++ *pthroughput = cfg80211_calculate_bitrate(&sinfo.txrate) / 3; |
| 76 | ++ return true; |
| 77 | ++ } |
| 78 | + |
| 79 | + goto default_throughput; |
| 80 | + } |
| 81 | +@@ -142,8 +151,10 @@ static u32 batadv_v_elp_get_throughput(s |
| 82 | + hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX; |
| 83 | + |
| 84 | + throughput = link_settings.base.speed; |
| 85 | +- if (throughput && throughput != SPEED_UNKNOWN) |
| 86 | +- return throughput * 10; |
| 87 | ++ if (throughput && throughput != SPEED_UNKNOWN) { |
| 88 | ++ *pthroughput = throughput * 10; |
| 89 | ++ return true; |
| 90 | ++ } |
| 91 | + } |
| 92 | + |
| 93 | + default_throughput: |
| 94 | +@@ -157,7 +168,8 @@ default_throughput: |
| 95 | + } |
| 96 | + |
| 97 | + /* if none of the above cases apply, return the base_throughput */ |
| 98 | +- return BATADV_THROUGHPUT_DEFAULT_VALUE; |
| 99 | ++ *pthroughput = BATADV_THROUGHPUT_DEFAULT_VALUE; |
| 100 | ++ return true; |
| 101 | + } |
| 102 | + |
| 103 | + /** |
| 104 | +@@ -169,15 +181,21 @@ void batadv_v_elp_throughput_metric_upda |
| 105 | + { |
| 106 | + struct batadv_hardif_neigh_node_bat_v *neigh_bat_v; |
| 107 | + struct batadv_hardif_neigh_node *neigh; |
| 108 | ++ u32 throughput; |
| 109 | ++ bool valid; |
| 110 | + |
| 111 | + neigh_bat_v = container_of(work, struct batadv_hardif_neigh_node_bat_v, |
| 112 | + metric_work); |
| 113 | + neigh = container_of(neigh_bat_v, struct batadv_hardif_neigh_node, |
| 114 | + bat_v); |
| 115 | + |
| 116 | +- ewma_throughput_add(&neigh->bat_v.throughput, |
| 117 | +- batadv_v_elp_get_throughput(neigh)); |
| 118 | ++ valid = batadv_v_elp_get_throughput(neigh, &throughput); |
| 119 | ++ if (!valid) |
| 120 | ++ goto put_neigh; |
| 121 | ++ |
| 122 | ++ ewma_throughput_add(&neigh->bat_v.throughput, throughput); |
| 123 | + |
| 124 | ++put_neigh: |
| 125 | + /* decrement refcounter to balance increment performed before scheduling |
| 126 | + * this task |
| 127 | + */ |
0 commit comments