Skip to content

Commit e7e34ff

Browse files
ecsvsimonwunderlich
authored andcommitted
batman-adv: Ignore neighbor throughput metrics in error case
If a temporary error happened in the evaluation of the neighbor throughput information, then the invalid throughput result should not be stored in the throughtput EWMA. Cc: stable@vger.kernel.org Signed-off-by: Sven Eckelmann <sven@narfation.org> Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
1 parent ccb7276 commit e7e34ff

File tree

1 file changed

+34
-16
lines changed

1 file changed

+34
-16
lines changed

net/batman-adv/bat_v_elp.c

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface)
5959
/**
6060
* batadv_v_elp_get_throughput() - get the throughput towards a neighbour
6161
* @neigh: the neighbour for which the throughput has to be obtained
62+
* @pthroughput: calculated throughput towards the given neighbour in multiples
63+
* of 100kpbs (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc).
6264
*
63-
* Return: The throughput towards the given neighbour in multiples of 100kpbs
64-
* (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc).
65+
* Return: true when value behind @pthroughput was set
6566
*/
66-
static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
67+
static bool batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh,
68+
u32 *pthroughput)
6769
{
6870
struct batadv_hard_iface *hard_iface = neigh->if_incoming;
6971
struct net_device *soft_iface = hard_iface->soft_iface;
@@ -77,14 +79,16 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
7779
* batman-adv interface
7880
*/
7981
if (!soft_iface)
80-
return BATADV_THROUGHPUT_DEFAULT_VALUE;
82+
return false;
8183

8284
/* if the user specified a customised value for this interface, then
8385
* return it directly
8486
*/
8587
throughput = atomic_read(&hard_iface->bat_v.throughput_override);
86-
if (throughput != 0)
87-
return throughput;
88+
if (throughput != 0) {
89+
*pthroughput = throughput;
90+
return true;
91+
}
8892

8993
/* if this is a wireless device, then ask its throughput through
9094
* cfg80211 API
@@ -111,19 +115,24 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
111115
* possible to delete this neighbor. For now set
112116
* the throughput metric to 0.
113117
*/
114-
return 0;
118+
*pthroughput = 0;
119+
return true;
115120
}
116121
if (ret)
117122
goto default_throughput;
118123

119-
if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT))
120-
return sinfo.expected_throughput / 100;
124+
if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)) {
125+
*pthroughput = sinfo.expected_throughput / 100;
126+
return true;
127+
}
121128

122129
/* try to estimate the expected throughput based on reported tx
123130
* rates
124131
*/
125-
if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE))
126-
return cfg80211_calculate_bitrate(&sinfo.txrate) / 3;
132+
if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)) {
133+
*pthroughput = cfg80211_calculate_bitrate(&sinfo.txrate) / 3;
134+
return true;
135+
}
127136

128137
goto default_throughput;
129138
}
@@ -142,8 +151,10 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
142151
hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX;
143152

144153
throughput = link_settings.base.speed;
145-
if (throughput && throughput != SPEED_UNKNOWN)
146-
return throughput * 10;
154+
if (throughput && throughput != SPEED_UNKNOWN) {
155+
*pthroughput = throughput * 10;
156+
return true;
157+
}
147158
}
148159

149160
default_throughput:
@@ -157,7 +168,8 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
157168
}
158169

159170
/* if none of the above cases apply, return the base_throughput */
160-
return BATADV_THROUGHPUT_DEFAULT_VALUE;
171+
*pthroughput = BATADV_THROUGHPUT_DEFAULT_VALUE;
172+
return true;
161173
}
162174

163175
/**
@@ -169,15 +181,21 @@ void batadv_v_elp_throughput_metric_update(struct work_struct *work)
169181
{
170182
struct batadv_hardif_neigh_node_bat_v *neigh_bat_v;
171183
struct batadv_hardif_neigh_node *neigh;
184+
u32 throughput;
185+
bool valid;
172186

173187
neigh_bat_v = container_of(work, struct batadv_hardif_neigh_node_bat_v,
174188
metric_work);
175189
neigh = container_of(neigh_bat_v, struct batadv_hardif_neigh_node,
176190
bat_v);
177191

178-
ewma_throughput_add(&neigh->bat_v.throughput,
179-
batadv_v_elp_get_throughput(neigh));
192+
valid = batadv_v_elp_get_throughput(neigh, &throughput);
193+
if (!valid)
194+
goto put_neigh;
195+
196+
ewma_throughput_add(&neigh->bat_v.throughput, throughput);
180197

198+
put_neigh:
181199
/* decrement refcounter to balance increment performed before scheduling
182200
* this task
183201
*/

0 commit comments

Comments
 (0)