Skip to content
Snippets Groups Projects
Commit 5e5ca2f6 authored by Sven Eckelmann's avatar Sven Eckelmann Committed by Frieder Schrempf
Browse files

batman-adv: Ignore neighbor throughput metrics in error case


commit e7e34ffc976aaae4f465b7898303241b81ceefc3 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: default avatarSven Eckelmann <sven@narfation.org>
Signed-off-by: default avatarSimon Wunderlich <sw@simonwunderlich.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 02039d41
No related branches found
No related tags found
1 merge request!191🤖 Sync Bot: Update v6.1-ktn to Latest Stable Kernel (v6.1.129)
...@@ -60,11 +60,13 @@ static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface) ...@@ -60,11 +60,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;
...@@ -78,14 +80,16 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) ...@@ -78,14 +80,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
...@@ -112,19 +116,24 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) ...@@ -112,19 +116,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;
} }
...@@ -143,8 +152,10 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) ...@@ -143,8 +152,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:
...@@ -158,7 +169,8 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) ...@@ -158,7 +169,8 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
} }
/* 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;
} }
/** /**
...@@ -170,15 +182,21 @@ void batadv_v_elp_throughput_metric_update(struct work_struct *work) ...@@ -170,15 +182,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
*/ */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment