batman-adv: Ignore neighbor throughput metrics in error case
commit e7e34ffc97 upstream.
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>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
fe7343b8a3
commit
77bff7bb11
+28
-13
@@ -58,11 +58,13 @@ static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface)
|
||||
/**
|
||||
* batadv_v_elp_get_throughput() - get the throughput towards a neighbour
|
||||
* @neigh: the neighbour for which the throughput has to be obtained
|
||||
* @pthroughput: calculated throughput towards the given neighbour in multiples
|
||||
* of 100kpbs (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc).
|
||||
*
|
||||
* Return: The throughput towards the given neighbour in multiples of 100kpbs
|
||||
* (a value of '1' equals to 0.1Mbps, '10' equals 1Mbps, etc).
|
||||
* Return: true when value behind @pthroughput was set
|
||||
*/
|
||||
static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
|
||||
static bool batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh,
|
||||
u32 *pthroughput)
|
||||
{
|
||||
struct batadv_hard_iface *hard_iface = neigh->if_incoming;
|
||||
struct net_device *soft_iface = hard_iface->soft_iface;
|
||||
@@ -76,14 +78,16 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
|
||||
* batman-adv interface
|
||||
*/
|
||||
if (!soft_iface)
|
||||
return BATADV_THROUGHPUT_DEFAULT_VALUE;
|
||||
return false;
|
||||
|
||||
/* if the user specified a customised value for this interface, then
|
||||
* return it directly
|
||||
*/
|
||||
throughput = atomic_read(&hard_iface->bat_v.throughput_override);
|
||||
if (throughput != 0)
|
||||
return throughput;
|
||||
if (throughput != 0) {
|
||||
*pthroughput = throughput;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* if this is a wireless device, then ask its throughput through
|
||||
* cfg80211 API
|
||||
@@ -110,14 +114,16 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
|
||||
* possible to delete this neighbor. For now set
|
||||
* the throughput metric to 0.
|
||||
*/
|
||||
return 0;
|
||||
*pthroughput = 0;
|
||||
return true;
|
||||
}
|
||||
if (ret)
|
||||
goto default_throughput;
|
||||
if (!(sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)))
|
||||
goto default_throughput;
|
||||
|
||||
return sinfo.expected_throughput / 100;
|
||||
*pthroughput = sinfo.expected_throughput / 100;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* if not a wifi interface, check if this device provides data via
|
||||
@@ -135,8 +141,10 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
|
||||
hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX;
|
||||
|
||||
throughput = link_settings.base.speed;
|
||||
if (throughput && throughput != SPEED_UNKNOWN)
|
||||
return throughput * 10;
|
||||
if (throughput && throughput != SPEED_UNKNOWN) {
|
||||
*pthroughput = throughput * 10;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
default_throughput:
|
||||
@@ -150,7 +158,8 @@ default_throughput:
|
||||
}
|
||||
|
||||
/* if none of the above cases apply, return the base_throughput */
|
||||
return BATADV_THROUGHPUT_DEFAULT_VALUE;
|
||||
*pthroughput = BATADV_THROUGHPUT_DEFAULT_VALUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,15 +171,21 @@ void batadv_v_elp_throughput_metric_update(struct work_struct *work)
|
||||
{
|
||||
struct batadv_hardif_neigh_node_bat_v *neigh_bat_v;
|
||||
struct batadv_hardif_neigh_node *neigh;
|
||||
u32 throughput;
|
||||
bool valid;
|
||||
|
||||
neigh_bat_v = container_of(work, struct batadv_hardif_neigh_node_bat_v,
|
||||
metric_work);
|
||||
neigh = container_of(neigh_bat_v, struct batadv_hardif_neigh_node,
|
||||
bat_v);
|
||||
|
||||
ewma_throughput_add(&neigh->bat_v.throughput,
|
||||
batadv_v_elp_get_throughput(neigh));
|
||||
valid = batadv_v_elp_get_throughput(neigh, &throughput);
|
||||
if (!valid)
|
||||
goto put_neigh;
|
||||
|
||||
ewma_throughput_add(&neigh->bat_v.throughput, throughput);
|
||||
|
||||
put_neigh:
|
||||
/* decrement refcounter to balance increment performed before scheduling
|
||||
* this task
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user