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>
This commit is contained in:
parent
ccb7276a6d
commit
e7e34ffc97
1 changed files with 34 additions and 16 deletions
|
@ -59,11 +59,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
|
* batadv_v_elp_get_throughput() - get the throughput towards a neighbour
|
||||||
* @neigh: the neighbour for which the throughput has to be obtained
|
* @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
|
* Return: true when value behind @pthroughput was set
|
||||||
* (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc).
|
|
||||||
*/
|
*/
|
||||||
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 batadv_hard_iface *hard_iface = neigh->if_incoming;
|
||||||
struct net_device *soft_iface = hard_iface->soft_iface;
|
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)
|
||||||
* batman-adv interface
|
* batman-adv interface
|
||||||
*/
|
*/
|
||||||
if (!soft_iface)
|
if (!soft_iface)
|
||||||
return BATADV_THROUGHPUT_DEFAULT_VALUE;
|
return false;
|
||||||
|
|
||||||
/* if the user specified a customised value for this interface, then
|
/* if the user specified a customised value for this interface, then
|
||||||
* return it directly
|
* return it directly
|
||||||
*/
|
*/
|
||||||
throughput = atomic_read(&hard_iface->bat_v.throughput_override);
|
throughput = atomic_read(&hard_iface->bat_v.throughput_override);
|
||||||
if (throughput != 0)
|
if (throughput != 0) {
|
||||||
return throughput;
|
*pthroughput = throughput;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* if this is a wireless device, then ask its throughput through
|
/* if this is a wireless device, then ask its throughput through
|
||||||
* cfg80211 API
|
* cfg80211 API
|
||||||
|
@ -111,19 +115,24 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
|
||||||
* possible to delete this neighbor. For now set
|
* possible to delete this neighbor. For now set
|
||||||
* the throughput metric to 0.
|
* the throughput metric to 0.
|
||||||
*/
|
*/
|
||||||
return 0;
|
*pthroughput = 0;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (ret)
|
if (ret)
|
||||||
goto default_throughput;
|
goto default_throughput;
|
||||||
|
|
||||||
if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT))
|
if (sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)) {
|
||||||
return sinfo.expected_throughput / 100;
|
*pthroughput = sinfo.expected_throughput / 100;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* try to estimate the expected throughput based on reported tx
|
/* try to estimate the expected throughput based on reported tx
|
||||||
* rates
|
* rates
|
||||||
*/
|
*/
|
||||||
if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE))
|
if (sinfo.filled & BIT(NL80211_STA_INFO_TX_BITRATE)) {
|
||||||
return cfg80211_calculate_bitrate(&sinfo.txrate) / 3;
|
*pthroughput = cfg80211_calculate_bitrate(&sinfo.txrate) / 3;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
goto default_throughput;
|
goto default_throughput;
|
||||||
}
|
}
|
||||||
|
@ -142,8 +151,10 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
|
||||||
hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX;
|
hard_iface->bat_v.flags &= ~BATADV_FULL_DUPLEX;
|
||||||
|
|
||||||
throughput = link_settings.base.speed;
|
throughput = link_settings.base.speed;
|
||||||
if (throughput && throughput != SPEED_UNKNOWN)
|
if (throughput && throughput != SPEED_UNKNOWN) {
|
||||||
return throughput * 10;
|
*pthroughput = throughput * 10;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default_throughput:
|
default_throughput:
|
||||||
|
@ -157,7 +168,8 @@ default_throughput:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if none of the above cases apply, return the base_throughput */
|
/* if none of the above cases apply, return the base_throughput */
|
||||||
return BATADV_THROUGHPUT_DEFAULT_VALUE;
|
*pthroughput = BATADV_THROUGHPUT_DEFAULT_VALUE;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -169,15 +181,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_bat_v *neigh_bat_v;
|
||||||
struct batadv_hardif_neigh_node *neigh;
|
struct batadv_hardif_neigh_node *neigh;
|
||||||
|
u32 throughput;
|
||||||
|
bool valid;
|
||||||
|
|
||||||
neigh_bat_v = container_of(work, struct batadv_hardif_neigh_node_bat_v,
|
neigh_bat_v = container_of(work, struct batadv_hardif_neigh_node_bat_v,
|
||||||
metric_work);
|
metric_work);
|
||||||
neigh = container_of(neigh_bat_v, struct batadv_hardif_neigh_node,
|
neigh = container_of(neigh_bat_v, struct batadv_hardif_neigh_node,
|
||||||
bat_v);
|
bat_v);
|
||||||
|
|
||||||
ewma_throughput_add(&neigh->bat_v.throughput,
|
valid = batadv_v_elp_get_throughput(neigh, &throughput);
|
||||||
batadv_v_elp_get_throughput(neigh));
|
if (!valid)
|
||||||
|
goto put_neigh;
|
||||||
|
|
||||||
|
ewma_throughput_add(&neigh->bat_v.throughput, throughput);
|
||||||
|
|
||||||
|
put_neigh:
|
||||||
/* decrement refcounter to balance increment performed before scheduling
|
/* decrement refcounter to balance increment performed before scheduling
|
||||||
* this task
|
* this task
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue