[RFCv2,4/6] batman-adv: add WiFi penalty

Message ID 1378312060-30922-5-git-send-email-siwu@hrz.tu-chemnitz.de (mailing list archive)
State RFC, archived
Headers

Commit Message

Simon Wunderlich Sept. 4, 2013, 4:27 p.m. UTC
  From: Simon Wunderlich <simon@open-mesh.com>

If the same interface is used for sending and receiving, there might be
throughput degradation on half-duplex interfaces such as WiFi. Add a
penalty if the same interface is used to reflect this problem in the
metric. At the same time, change the hop penalty from 30 to 15 so there
will be no change for single wifi mesh network. the effective hop
penalty will stay at 30 due to the new wifi penalty for these networks.

Signed-off-by: Simon Wunderlich <simon@open-mesh.com>
---
Changes to RFCv1:
 * use hop penalty for wifi penalty, and use half of the original hop
   penalty.
---
 bat_iv_ogm.c     |   27 +++++++++++++++++++++++----
 hard-interface.c |    2 +-
 hard-interface.h |    1 +
 soft-interface.c |    2 +-
 4 files changed, 26 insertions(+), 6 deletions(-)
  

Comments

Antonio Quartulli Sept. 25, 2013, 8:18 p.m. UTC | #1
On Wed, Sep 04, 2013 at 06:27:38PM +0200, Simon Wunderlich wrote:
> diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c
> index d32b2f2..efddadf 100644
> --- a/bat_iv_ogm.c
> +++ b/bat_iv_ogm.c
> @@ -1085,6 +1085,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
>  	uint8_t orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
>  	unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
>  	int tq_asym_penalty, inv_asym_penalty, if_num, ret = 0;
> +	int tq_iface_penalty;
>  	unsigned int combined_tq;

please, add the new variable at the end (line length sorting).

>  
>  	/* find corresponding one hop neighbor */
> @@ -1169,15 +1170,33 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
>  	inv_asym_penalty /= neigh_rq_max_cube;
>  	tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty;
>  
> -	combined_tq = batadv_ogm_packet->tq * tq_own * tq_asym_penalty;
> -	combined_tq /= BATADV_TQ_MAX_VALUE * BATADV_TQ_MAX_VALUE;
> +	/* penalize if the OGM is forwarded on the same interface. WiFi
> +	 * interfaces and other half duplex devices suffer from throughput
> +	 * drops as they can't send and receive at the same time.
> +	 */
> +	tq_iface_penalty = BATADV_TQ_MAX_VALUE;
> +	if (if_outgoing && (if_incoming == if_outgoing) &&
> +	    batadv_is_wifi_netdev(if_outgoing->net_dev))
> +		tq_iface_penalty = batadv_hop_penalty(BATADV_TQ_MAX_VALUE,
> +						      bat_priv);
> +
> +	combined_tq = batadv_ogm_packet->tq *
> +		      tq_own *
> +		      tq_asym_penalty *
> +		      tq_iface_penalty;
> +	combined_tq /= BATADV_TQ_MAX_VALUE *
> +		       BATADV_TQ_MAX_VALUE *
> +		       BATADV_TQ_MAX_VALUE;

Mh..I am not sure about the style of these assignments...but we can live with
those for now.

>  	batadv_ogm_packet->tq = combined_tq;
>  
>  	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
> -		   "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n",
> +		   "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, iface_penalty: %3i, total tq: %3i, if_incoming = %s, if_outgoing = %s\n",
>  		   orig_node->orig, orig_neigh_node->orig, total_count,
>  		   neigh_rq_count, tq_own,
> -		   tq_asym_penalty, batadv_ogm_packet->tq);
> +		   tq_asym_penalty, tq_iface_penalty,
> +		   batadv_ogm_packet->tq,

this one can go on the line above..

> +		   if_incoming ? if_incoming->net_dev->name : "NULL",
> +		   if_outgoing ? if_outgoing->net_dev->name : "NULL");
>  
>  	/* if link has the minimum required transmission quality
>  	 * consider it bidirectional

Cheers,
  

Patch

diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c
index d32b2f2..efddadf 100644
--- a/bat_iv_ogm.c
+++ b/bat_iv_ogm.c
@@ -1085,6 +1085,7 @@  static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
 	uint8_t orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
 	unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
 	int tq_asym_penalty, inv_asym_penalty, if_num, ret = 0;
+	int tq_iface_penalty;
 	unsigned int combined_tq;
 
 	/* find corresponding one hop neighbor */
@@ -1169,15 +1170,33 @@  static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
 	inv_asym_penalty /= neigh_rq_max_cube;
 	tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty;
 
-	combined_tq = batadv_ogm_packet->tq * tq_own * tq_asym_penalty;
-	combined_tq /= BATADV_TQ_MAX_VALUE * BATADV_TQ_MAX_VALUE;
+	/* penalize if the OGM is forwarded on the same interface. WiFi
+	 * interfaces and other half duplex devices suffer from throughput
+	 * drops as they can't send and receive at the same time.
+	 */
+	tq_iface_penalty = BATADV_TQ_MAX_VALUE;
+	if (if_outgoing && (if_incoming == if_outgoing) &&
+	    batadv_is_wifi_netdev(if_outgoing->net_dev))
+		tq_iface_penalty = batadv_hop_penalty(BATADV_TQ_MAX_VALUE,
+						      bat_priv);
+
+	combined_tq = batadv_ogm_packet->tq *
+		      tq_own *
+		      tq_asym_penalty *
+		      tq_iface_penalty;
+	combined_tq /= BATADV_TQ_MAX_VALUE *
+		       BATADV_TQ_MAX_VALUE *
+		       BATADV_TQ_MAX_VALUE;
 	batadv_ogm_packet->tq = combined_tq;
 
 	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
-		   "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, total tq: %3i\n",
+		   "bidirectional: orig = %-15pM neigh = %-15pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, iface_penalty: %3i, total tq: %3i, if_incoming = %s, if_outgoing = %s\n",
 		   orig_node->orig, orig_neigh_node->orig, total_count,
 		   neigh_rq_count, tq_own,
-		   tq_asym_penalty, batadv_ogm_packet->tq);
+		   tq_asym_penalty, tq_iface_penalty,
+		   batadv_ogm_packet->tq,
+		   if_incoming ? if_incoming->net_dev->name : "NULL",
+		   if_outgoing ? if_outgoing->net_dev->name : "NULL");
 
 	/* if link has the minimum required transmission quality
 	 * consider it bidirectional
diff --git a/hard-interface.c b/hard-interface.c
index c60d3ed..2a4b202 100644
--- a/hard-interface.c
+++ b/hard-interface.c
@@ -124,7 +124,7 @@  static int batadv_is_valid_iface(const struct net_device *net_dev)
  *
  * Returns true if the net device is a 802.11 wireless device, false otherwise.
  */
-static bool batadv_is_wifi_netdev(struct net_device *net_device)
+bool batadv_is_wifi_netdev(struct net_device *net_device)
 {
 #ifdef CONFIG_WIRELESS_EXT
 	/* pre-cfg80211 drivers have to implement WEXT, so it is possible to
diff --git a/hard-interface.h b/hard-interface.h
index 4989288..1a90ea5 100644
--- a/hard-interface.h
+++ b/hard-interface.h
@@ -52,6 +52,7 @@  int batadv_hardif_min_mtu(struct net_device *soft_iface);
 void batadv_update_min_mtu(struct net_device *soft_iface);
 void batadv_hardif_free_rcu(struct rcu_head *rcu);
 bool batadv_is_wifi_iface(int ifindex);
+bool batadv_is_wifi_netdev(struct net_device *net_device);
 
 static inline void
 batadv_hardif_free_ref(struct batadv_hard_iface *hard_iface)
diff --git a/soft-interface.c b/soft-interface.c
index a1f00e8..81c608d 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -672,7 +672,7 @@  static int batadv_softif_init_late(struct net_device *dev)
 	atomic_set(&bat_priv->gw.bandwidth_down, 100);
 	atomic_set(&bat_priv->gw.bandwidth_up, 20);
 	atomic_set(&bat_priv->orig_interval, 1000);
-	atomic_set(&bat_priv->hop_penalty, 30);
+	atomic_set(&bat_priv->hop_penalty, 15);
 #ifdef CONFIG_BATMAN_ADV_DEBUG
 	atomic_set(&bat_priv->log_level, 0);
 #endif