b.a.t.m.a.n.lists.open-mesh.org archive mirror
 help / color / mirror / Atom feed
* [B.A.T.M.A.N.] [RFC 0/6] B.A.T.M.A.N. V - fallback to tp meter estimation if throughput otherwise not available
@ 2018-05-08 16:41 Marek Lindner
  2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 1/6] batman-adv: tp_meter - prevent concurrent tp_meter sessions by using workqueue Marek Lindner
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Marek Lindner @ 2018-05-08 16:41 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

Under normal circumstances B.A.T.M.A.N. V retrieves the neighbor
throughput values to populate its metric tables from the various
drivers such as WiFi throughput tables and Ethernet throughput..
Whenever the interface drivers do not export link throughput 
information manual overrides become necessary. To further 
automate and thus better support these setups, ELP may call
the batman-adv throughput meter to schedule a throughput
estimation to be used to populate the metric table. 

Antonio Quartulli (3):
  batman-adv: tp_meter - prevent concurrent tp_meter sessions by using
    workqueue
  batman-adv: tp_meter - don't check for existing session
  batman-adv: to_meter - add option to perform one-hop test

Marek Lindner (3):
  batman-adv: tp_meter - allow up to 10 queued sessions
  batman-adv: tp_meter - add caller distinction
  batman-adv: ELP - use tp meter to estimate the throughput if otherwise
    not available

 include/uapi/linux/batadv_packet.h |   1 +
 net/batman-adv/bat_v_elp.c         |  62 ++++-
 net/batman-adv/bat_v_elp.h         |  19 ++
 net/batman-adv/main.c              |  10 +-
 net/batman-adv/main.h              |   7 +-
 net/batman-adv/netlink.c           |   3 +-
 net/batman-adv/routing.c           |   5 +-
 net/batman-adv/tp_meter.c          | 431 +++++++++++++++++------------
 net/batman-adv/tp_meter.h          |  11 +-
 net/batman-adv/types.h             |  32 ++-
 10 files changed, 393 insertions(+), 188 deletions(-)

-- 
2.17.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [B.A.T.M.A.N.] [RFC 1/6] batman-adv: tp_meter - prevent concurrent tp_meter sessions by using workqueue
  2018-05-08 16:41 [B.A.T.M.A.N.] [RFC 0/6] B.A.T.M.A.N. V - fallback to tp meter estimation if throughput otherwise not available Marek Lindner
@ 2018-05-08 16:41 ` Marek Lindner
  2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 2/6] batman-adv: tp_meter - don't check for existing session Marek Lindner
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marek Lindner @ 2018-05-08 16:41 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

From: Antonio Quartulli <a@unstable.cc>

To ensure that no more than one tp_meter session runs at the
same time, use an ordered workqueue instead of spawning
one kthread per session.

Signed-off-by: Antonio Quartulli <a@unstable.cc>
---
 net/batman-adv/main.c     | 10 ++++--
 net/batman-adv/tp_meter.c | 73 ++++++++++++++++++---------------------
 net/batman-adv/tp_meter.h |  3 +-
 net/batman-adv/types.h    |  5 ++-
 4 files changed, 48 insertions(+), 43 deletions(-)

diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 69c0d85b..cd3f1924 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -91,6 +91,10 @@ static int __init batadv_init(void)
 	if (ret < 0)
 		return ret;
 
+	ret = batadv_tp_meter_init();
+	if (ret < 0)
+		goto err_tp_meter;
+
 	INIT_LIST_HEAD(&batadv_hardif_list);
 	batadv_algo_init();
 
@@ -99,7 +103,6 @@ static int __init batadv_init(void)
 	batadv_v_init();
 	batadv_iv_init();
 	batadv_nc_init();
-	batadv_tp_meter_init();
 
 	batadv_event_workqueue = create_singlethread_workqueue("bat_events");
 	if (!batadv_event_workqueue)
@@ -118,9 +121,11 @@ static int __init batadv_init(void)
 	return 0;
 
 err_create_wq:
+	batadv_tp_meter_destroy();
+err_tp_meter:
 	batadv_tt_cache_destroy();
 
-	return -ENOMEM;
+	return ret;
 }
 
 static void __exit batadv_exit(void)
@@ -138,6 +143,7 @@ static void __exit batadv_exit(void)
 	rcu_barrier();
 
 	batadv_tt_cache_destroy();
+	batadv_tp_meter_destroy();
 }
 
 /**
diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
index 11520de9..55e93abc 100644
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -32,7 +32,6 @@
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/kref.h>
-#include <linux/kthread.h>
 #include <linux/list.h>
 #include <linux/netdevice.h>
 #include <linux/param.h>
@@ -97,6 +96,9 @@
 
 static u8 batadv_tp_prerandom[4096] __read_mostly;
 
+/* ordered work queue */
+static struct workqueue_struct *batadv_tp_meter_queue;
+
 /**
  * batadv_tp_session_cookie() - generate session cookie based on session ids
  * @session: TP session identifier
@@ -812,15 +814,18 @@ static int batadv_tp_wait_available(struct batadv_tp_vars *tp_vars, size_t plen)
  *
  * Return: nothing, this function never returns
  */
-static int batadv_tp_send(void *arg)
+static void batadv_tp_send(struct work_struct *work)
 {
-	struct batadv_tp_vars *tp_vars = arg;
-	struct batadv_priv *bat_priv = tp_vars->bat_priv;
 	struct batadv_hard_iface *primary_if = NULL;
 	struct batadv_orig_node *orig_node = NULL;
+	struct batadv_tp_vars *tp_vars;
 	size_t payload_len, packet_len;
+	struct batadv_priv *bat_priv;
 	int err = 0;
 
+	tp_vars = container_of(work, struct batadv_tp_vars, test_work);
+	bat_priv = tp_vars->bat_priv;
+
 	if (unlikely(tp_vars->role != BATADV_TP_SENDER)) {
 		err = BATADV_TP_REASON_DST_UNREACHABLE;
 		tp_vars->reason = err;
@@ -901,40 +906,17 @@ static int batadv_tp_send(void *arg)
 	batadv_tp_sender_cleanup(bat_priv, tp_vars);
 
 	batadv_tp_vars_put(tp_vars);
-
-	do_exit(0);
 }
 
 /**
- * batadv_tp_start_kthread() - start new thread which manages the tp meter
- *  sender
+ * batadv_tp_start_work - start new thread which manages the tp meter sender
  * @tp_vars: the private data of the current TP meter session
  */
-static void batadv_tp_start_kthread(struct batadv_tp_vars *tp_vars)
+static void batadv_tp_start_work(struct batadv_tp_vars *tp_vars)
 {
-	struct task_struct *kthread;
-	struct batadv_priv *bat_priv = tp_vars->bat_priv;
-	u32 session_cookie;
-
-	kref_get(&tp_vars->refcount);
-	kthread = kthread_create(batadv_tp_send, tp_vars, "kbatadv_tp_meter");
-	if (IS_ERR(kthread)) {
-		session_cookie = batadv_tp_session_cookie(tp_vars->session,
-							  tp_vars->icmp_uid);
-		pr_err("batadv: cannot create tp meter kthread\n");
-		batadv_tp_batctl_error_notify(BATADV_TP_REASON_MEMORY_ERROR,
-					      tp_vars->other_end,
-					      bat_priv, session_cookie);
-
-		/* drop reserved reference for kthread */
-		batadv_tp_vars_put(tp_vars);
-
-		/* cleanup of failed tp meter variables */
-		batadv_tp_sender_cleanup(bat_priv, tp_vars);
-		return;
-	}
-
-	wake_up_process(kthread);
+        /* init work item that will actually execute the test and schedule it */
+        INIT_WORK(&tp_vars->test_work, batadv_tp_send);
+        queue_work(batadv_tp_meter_queue, &tp_vars->test_work);
 }
 
 /**
@@ -1053,13 +1035,10 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
 	/* init work item for finished tp tests */
 	INIT_DELAYED_WORK(&tp_vars->finish_work, batadv_tp_sender_finish);
 
-	/* start tp kthread. This way the write() call issued from userspace can
-	 * happily return and avoid to block
+	/* schedule the tp worker. This way the write() call issued from
+	 * userspace can happily return and avoid to block
 	 */
-	batadv_tp_start_kthread(tp_vars);
-
-	/* don't return reference to new tp_vars */
-	batadv_tp_vars_put(tp_vars);
+	batadv_tp_start_work(tp_vars);
 }
 
 /**
@@ -1499,7 +1478,23 @@ void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb)
 /**
  * batadv_tp_meter_init() - initialize global tp_meter structures
  */
-void __init batadv_tp_meter_init(void)
+int __init batadv_tp_meter_init(void)
 {
 	get_random_bytes(batadv_tp_prerandom, sizeof(batadv_tp_prerandom));
+
+	batadv_tp_meter_queue = alloc_ordered_workqueue("bat_tp_meter", 0);
+	if (!batadv_tp_meter_queue)
+		return -ENOMEM;
+
+	return 0;
+}
+
+/**
+ * batadv_tp_meter_destroy() - destroy tp meter memory allocations
+ */
+void batadv_tp_meter_destroy(void)
+{
+	flush_workqueue(batadv_tp_meter_queue);
+	destroy_workqueue(batadv_tp_meter_queue);
+	batadv_tp_meter_queue = NULL;
 }
diff --git a/net/batman-adv/tp_meter.h b/net/batman-adv/tp_meter.h
index 68e60097..ab0bde26 100644
--- a/net/batman-adv/tp_meter.h
+++ b/net/batman-adv/tp_meter.h
@@ -25,7 +25,8 @@
 
 struct sk_buff;
 
-void batadv_tp_meter_init(void);
+int batadv_tp_meter_init(void);
+void batadv_tp_meter_destroy(void);
 void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
 		     u32 test_length, u32 *cookie);
 void batadv_tp_stop(struct batadv_priv *bat_priv, const u8 *dst,
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 360357f8..c4bc8221 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1354,7 +1354,10 @@ struct batadv_tp_vars {
 	/** @finish_work: work item for the finishing procedure */
 	struct delayed_work finish_work;
 
-	/** @test_length: test length in milliseconds */
+        /** @test_work: work item for the test process */
+	struct work_struct test_work;
+
+        /** @test_length: test length in milliseconds */
 	u32 test_length;
 
 	/** @session: TP session identifier */
-- 
2.17.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [B.A.T.M.A.N.] [RFC 2/6] batman-adv: tp_meter - don't check for existing session
  2018-05-08 16:41 [B.A.T.M.A.N.] [RFC 0/6] B.A.T.M.A.N. V - fallback to tp meter estimation if throughput otherwise not available Marek Lindner
  2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 1/6] batman-adv: tp_meter - prevent concurrent tp_meter sessions by using workqueue Marek Lindner
@ 2018-05-08 16:41 ` Marek Lindner
  2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 3/6] batman-adv: tp_meter - allow up to 10 queued sessions Marek Lindner
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marek Lindner @ 2018-05-08 16:41 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

From: Antonio Quartulli <a@unstable.cc>

Since the conversion from kthread to queue worker it is not possible
to run more than one "sender" session at a time.
For this reason, checking if another session to the same destination
is already scheduled is not useful anymore.

Remove such check and allow the user to enqueue a new session to
a previously targeted node.

Signed-off-by: Antonio Quartulli <a@unstable.cc>
---
 net/batman-adv/tp_meter.c | 16 +---------------
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
index 55e93abc..d91d371d 100644
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -939,21 +939,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
 	session_cookie = batadv_tp_session_cookie(session_id, icmp_uid);
 	*cookie = session_cookie;
 
-	/* look for an already existing test towards this node */
-	spin_lock_bh(&bat_priv->tp_list_lock);
-	tp_vars = batadv_tp_list_find(bat_priv, dst);
-	if (tp_vars) {
-		spin_unlock_bh(&bat_priv->tp_list_lock);
-		batadv_tp_vars_put(tp_vars);
-		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
-			   "Meter: test to or from the same node already ongoing, aborting\n");
-		batadv_tp_batctl_error_notify(BATADV_TP_REASON_ALREADY_ONGOING,
-					      dst, bat_priv, session_cookie);
-		return;
-	}
-
 	if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM)) {
-		spin_unlock_bh(&bat_priv->tp_list_lock);
 		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
 			   "Meter: too many ongoing sessions, aborting (SEND)\n");
 		batadv_tp_batctl_error_notify(BATADV_TP_REASON_TOO_MANY, dst,
@@ -963,7 +949,6 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
 
 	tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC);
 	if (!tp_vars) {
-		spin_unlock_bh(&bat_priv->tp_list_lock);
 		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
 			   "Meter: %s cannot allocate list elements\n",
 			   __func__);
@@ -1021,6 +1006,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
 	spin_lock_init(&tp_vars->prerandom_lock);
 
 	kref_get(&tp_vars->refcount);
+	spin_lock_bh(&bat_priv->tp_list_lock);
 	hlist_add_head_rcu(&tp_vars->list, &bat_priv->tp_list);
 	spin_unlock_bh(&bat_priv->tp_list_lock);
 
-- 
2.17.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [B.A.T.M.A.N.] [RFC 3/6] batman-adv: tp_meter - allow up to 10 queued sessions
  2018-05-08 16:41 [B.A.T.M.A.N.] [RFC 0/6] B.A.T.M.A.N. V - fallback to tp meter estimation if throughput otherwise not available Marek Lindner
  2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 1/6] batman-adv: tp_meter - prevent concurrent tp_meter sessions by using workqueue Marek Lindner
  2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 2/6] batman-adv: tp_meter - don't check for existing session Marek Lindner
@ 2018-05-08 16:41 ` Marek Lindner
  2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 4/6] batman-adv: tp_meter - add caller distinction Marek Lindner
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marek Lindner @ 2018-05-08 16:41 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
---
 net/batman-adv/main.h     | 6 ++++--
 net/batman-adv/tp_meter.c | 5 +++--
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 8da3c933..89dfaf87 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -137,9 +137,11 @@
 #define BATADV_NC_NODE_TIMEOUT 10000 /* Milliseconds */
 
 /**
- * BATADV_TP_MAX_NUM - maximum number of simultaneously active tp sessions
+ * BATADV_TP_MAX_NUM_QUEUE - maximum number of queued (outgoing) tp sessions
+ * BATADV_TP_MAX_NUM_RECV - maximum number of simultaneous receiving streams
  */
-#define BATADV_TP_MAX_NUM 5
+#define BATADV_TP_MAX_NUM_QUEUE 10
+#define BATADV_TP_MAX_NUM_RECV 1
 
 /**
  * enum batadv_mesh_state - State of a soft interface
diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
index d91d371d..eb7862cd 100644
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -939,7 +939,8 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
 	session_cookie = batadv_tp_session_cookie(session_id, icmp_uid);
 	*cookie = session_cookie;
 
-	if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM)) {
+	if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM_QUEUE)) {
+		spin_unlock_bh(&bat_priv->tp_list_lock);
 		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
 			   "Meter: too many ongoing sessions, aborting (SEND)\n");
 		batadv_tp_batctl_error_notify(BATADV_TP_REASON_TOO_MANY, dst,
@@ -1316,7 +1317,7 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv,
 	if (tp_vars)
 		goto out_unlock;
 
-	if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM)) {
+	if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM_RECV)) {
 		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
 			   "Meter: too many ongoing sessions, aborting (RECV)\n");
 		goto out_unlock;
-- 
2.17.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [B.A.T.M.A.N.] [RFC 4/6] batman-adv: tp_meter - add caller distinction
  2018-05-08 16:41 [B.A.T.M.A.N.] [RFC 0/6] B.A.T.M.A.N. V - fallback to tp meter estimation if throughput otherwise not available Marek Lindner
                   ` (2 preceding siblings ...)
  2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 3/6] batman-adv: tp_meter - allow up to 10 queued sessions Marek Lindner
@ 2018-05-08 16:41 ` Marek Lindner
  2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 5/6] batman-adv: to_meter - add option to perform one-hop test Marek Lindner
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Marek Lindner @ 2018-05-08 16:41 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

The throughput meter can be called from user space as well as from
the batman-adv kernel module itself. Add infrastructure to handle
the different callers.

Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
---
 net/batman-adv/netlink.c  |   2 +-
 net/batman-adv/tp_meter.c | 102 +++++++++++++++++++++-----------------
 net/batman-adv/tp_meter.h |   2 +-
 net/batman-adv/types.h    |  15 +++++-
 4 files changed, 72 insertions(+), 49 deletions(-)

diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 0d9459b6..88bf6c6f 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -378,7 +378,7 @@ batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info)
 	}
 
 	bat_priv = netdev_priv(soft_iface);
-	batadv_tp_start(bat_priv, dst, test_length, &cookie);
+	batadv_tp_start(bat_priv, dst, test_length, &cookie, BATADV_TP_USERSPACE);
 
 	ret = batadv_netlink_tp_meter_put(msg, cookie);
 
diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
index eb7862cd..f7bb45d3 100644
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -215,50 +215,68 @@ static void batadv_tp_update_rto(struct batadv_tp_vars *tp_vars,
 }
 
 /**
- * batadv_tp_batctl_notify() - send client status result to client
- * @reason: reason for tp meter session stop
- * @dst: destination of tp_meter session
+ * batadv_tp_caller_notify() - send tp meter status result to caller
  * @bat_priv: the bat priv with all the soft interface information
- * @start_time: start of transmission in jiffies
- * @total_sent: bytes acked to the receiver
- * @cookie: cookie of tp_meter session
+ * @tp_vars: the private data of the current TP meter session
+ * @reason: reason for tp meter session stop
  */
-static void batadv_tp_batctl_notify(enum batadv_tp_meter_reason reason,
-				    const u8 *dst, struct batadv_priv *bat_priv,
-				    unsigned long start_time, u64 total_sent,
-				    u32 cookie)
+static void batadv_tp_caller_notify(struct batadv_priv *bat_priv,
+				    struct batadv_tp_vars *tp_vars,
+				    enum batadv_tp_meter_reason reason)
 {
-	u32 test_time;
-	u8 result;
 	u32 total_bytes;
+	u32 test_time;
+	u32 cookie;
+	bool reason_is_error;
 
-	if (!batadv_tp_is_error(reason)) {
-		result = BATADV_TP_REASON_COMPLETE;
-		test_time = jiffies_to_msecs(jiffies - start_time);
-		total_bytes = total_sent;
-	} else {
-		result = reason;
-		test_time = 0;
-		total_bytes = 0;
-	}
+	reason_is_error = batadv_tp_is_error(reason);
 
-	batadv_netlink_tpmeter_notify(bat_priv, dst, result, test_time,
-				      total_bytes, cookie);
+	switch (tp_vars->caller) {
+	case BATADV_TP_USERSPACE:
+		cookie = batadv_tp_session_cookie(tp_vars->session, tp_vars->icmp_uid);
+
+		if (reason_is_error) {
+			batadv_netlink_tpmeter_notify(bat_priv, tp_vars->other_end,
+						      reason, 0, 0, cookie);
+			return;
+		}
+
+		test_time = jiffies_to_msecs(jiffies - tp_vars->start_time);
+		total_bytes = atomic64_read(&tp_vars->tot_sent);
+		batadv_netlink_tpmeter_notify(bat_priv, tp_vars->other_end,
+					      BATADV_TP_REASON_COMPLETE, test_time,
+					      total_bytes, cookie);
+
+		break;
+	case BATADV_TP_ELP:
+		break;
+	default:
+		break;
+	}
 }
 
 /**
- * batadv_tp_batctl_error_notify() - send client error result to client
+ * batadv_tp_caller_init_error() - report early tp meter errors to caller
+ * @bat_priv: the bat priv with all the soft interface information
+ * @caller: caller of tp meter session (user space or ELP)
  * @reason: reason for tp meter session stop
  * @dst: destination of tp_meter session
- * @bat_priv: the bat priv with all the soft interface information
  * @cookie: cookie of tp_meter session
  */
-static void batadv_tp_batctl_error_notify(enum batadv_tp_meter_reason reason,
-					  const u8 *dst,
-					  struct batadv_priv *bat_priv,
-					  u32 cookie)
+static void batadv_tp_caller_init_error(struct batadv_priv *bat_priv,
+					enum batadv_tp_meter_caller caller,
+					enum batadv_tp_meter_reason reason,
+					const u8 *dst, u32 cookie)
 {
-	batadv_tp_batctl_notify(reason, dst, bat_priv, 0, 0, cookie);
+	switch (caller) {
+	case BATADV_TP_USERSPACE:
+		batadv_netlink_tpmeter_notify(bat_priv, dst, reason, 0, 0, cookie);
+		break;
+	case BATADV_TP_ELP:
+		break;
+	default:
+		break;
+	}
 }
 
 /**
@@ -411,8 +429,6 @@ static void batadv_tp_sender_cleanup(struct batadv_priv *bat_priv,
 static void batadv_tp_sender_end(struct batadv_priv *bat_priv,
 				 struct batadv_tp_vars *tp_vars)
 {
-	u32 session_cookie;
-
 	batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
 		   "Test towards %pM finished..shutting down (reason=%d)\n",
 		   tp_vars->other_end, tp_vars->reason);
@@ -425,15 +441,7 @@ static void batadv_tp_sender_end(struct batadv_priv *bat_priv,
 		   "Final values: cwnd=%u ss_threshold=%u\n",
 		   tp_vars->cwnd, tp_vars->ss_threshold);
 
-	session_cookie = batadv_tp_session_cookie(tp_vars->session,
-						  tp_vars->icmp_uid);
-
-	batadv_tp_batctl_notify(tp_vars->reason,
-				tp_vars->other_end,
-				bat_priv,
-				tp_vars->start_time,
-				atomic64_read(&tp_vars->tot_sent),
-				session_cookie);
+	batadv_tp_caller_notify(bat_priv, tp_vars, tp_vars->reason);
 }
 
 /**
@@ -925,9 +933,10 @@ static void batadv_tp_start_work(struct batadv_tp_vars *tp_vars)
  * @dst: the receiver MAC address
  * @test_length: test length in milliseconds
  * @cookie: session cookie
+ * @caller: caller of tp meter session (user space or ELP)
  */
 void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
-		     u32 test_length, u32 *cookie)
+		     u32 test_length, u32 *cookie, enum batadv_tp_meter_caller caller)
 {
 	struct batadv_tp_vars *tp_vars;
 	u8 session_id[2];
@@ -943,8 +952,8 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
 		spin_unlock_bh(&bat_priv->tp_list_lock);
 		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
 			   "Meter: too many ongoing sessions, aborting (SEND)\n");
-		batadv_tp_batctl_error_notify(BATADV_TP_REASON_TOO_MANY, dst,
-					      bat_priv, session_cookie);
+		batadv_tp_caller_init_error(bat_priv, caller, BATADV_TP_REASON_TOO_MANY,
+					    dst, session_cookie);
 		return;
 	}
 
@@ -953,8 +962,8 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
 		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
 			   "Meter: %s cannot allocate list elements\n",
 			   __func__);
-		batadv_tp_batctl_error_notify(BATADV_TP_REASON_MEMORY_ERROR,
-					      dst, bat_priv, session_cookie);
+		batadv_tp_caller_init_error(bat_priv, caller, BATADV_TP_REASON_MEMORY_ERROR,
+					    dst, session_cookie);
 		return;
 	}
 
@@ -962,6 +971,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
 	ether_addr_copy(tp_vars->other_end, dst);
 	kref_init(&tp_vars->refcount);
 	tp_vars->role = BATADV_TP_SENDER;
+	tp_vars->caller = caller;
 	atomic_set(&tp_vars->sending, 1);
 	memcpy(tp_vars->session, session_id, sizeof(session_id));
 	tp_vars->icmp_uid = icmp_uid;
diff --git a/net/batman-adv/tp_meter.h b/net/batman-adv/tp_meter.h
index ab0bde26..d844575d 100644
--- a/net/batman-adv/tp_meter.h
+++ b/net/batman-adv/tp_meter.h
@@ -28,7 +28,7 @@ struct sk_buff;
 int batadv_tp_meter_init(void);
 void batadv_tp_meter_destroy(void);
 void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
-		     u32 test_length, u32 *cookie);
+		     u32 test_length, u32 *cookie, enum batadv_tp_meter_caller caller);
 void batadv_tp_stop(struct batadv_priv *bat_priv, const u8 *dst,
 		    u8 return_value);
 void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb);
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index c4bc8221..826b3b42 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1323,6 +1323,16 @@ enum batadv_tp_meter_role {
 	BATADV_TP_SENDER
 };
 
+/**
+ * enum batadv_tp_meter_caller - initiator of the tp meter session
+ * @BATADV_TP_USERSPACE: initiated by user space
+ * @BATADV_TP_ELP: initiated by ELP
+ */
+enum batadv_tp_meter_caller {
+	BATADV_TP_USERSPACE,
+	BATADV_TP_ELP
+};
+
 /**
  * struct batadv_tp_vars - tp meter private variables per session
  */
@@ -1345,7 +1355,10 @@ struct batadv_tp_vars {
 	/** @role: receiver/sender modi */
 	enum batadv_tp_meter_role role;
 
-	/** @sending: sending binary semaphore: 1 if sending, 0 is not */
+        /** @caller: caller of tp meter session (user space or ELP) */
+	enum batadv_tp_meter_caller caller;
+
+        /** @sending: sending binary semaphore: 1 if sending, 0 is not */
 	atomic_t sending;
 
 	/** @reason: reason for a stopped session */
-- 
2.17.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [B.A.T.M.A.N.] [RFC 5/6] batman-adv: to_meter - add option to perform one-hop test
  2018-05-08 16:41 [B.A.T.M.A.N.] [RFC 0/6] B.A.T.M.A.N. V - fallback to tp meter estimation if throughput otherwise not available Marek Lindner
                   ` (3 preceding siblings ...)
  2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 4/6] batman-adv: tp_meter - add caller distinction Marek Lindner
@ 2018-05-08 16:41 ` Marek Lindner
  2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 6/6] batman-adv: ELP - use tp meter to estimate the throughput if otherwise not available Marek Lindner
  2018-05-08 18:36 ` [B.A.T.M.A.N.] [RFC 0/6] B.A.T.M.A.N. V - fallback to tp meter estimation if throughput " Sven Eckelmann
  6 siblings, 0 replies; 8+ messages in thread
From: Marek Lindner @ 2018-05-08 16:41 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Antonio Quartulli

From: Antonio Quartulli <a@unstable.cc>

A link test is a TP session ran over a specific one-hop link,
rather than towards an originator in the mesh.

Signed-off-by: Antonio Quartulli <a@unstable.cc>
---
 include/uapi/linux/batadv_packet.h |   1 +
 net/batman-adv/netlink.c           |   3 +-
 net/batman-adv/routing.c           |   5 +-
 net/batman-adv/tp_meter.c          | 220 +++++++++++++++++++----------
 net/batman-adv/tp_meter.h          |   8 +-
 net/batman-adv/types.h             |   3 +
 6 files changed, 161 insertions(+), 79 deletions(-)

diff --git a/include/uapi/linux/batadv_packet.h b/include/uapi/linux/batadv_packet.h
index 894d8d2f..fc89ab6b 100644
--- a/include/uapi/linux/batadv_packet.h
+++ b/include/uapi/linux/batadv_packet.h
@@ -355,6 +355,7 @@ struct batadv_icmp_tp_packet {
 enum batadv_icmp_tp_subtype {
 	BATADV_TP_MSG	= 0,
 	BATADV_TP_ACK,
+	BATADV_TP_MSG_LINK,
 };
 
 #define BATADV_RR_LEN 16
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 88bf6c6f..064020cc 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -378,7 +378,8 @@ batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info)
 	}
 
 	bat_priv = netdev_priv(soft_iface);
-	batadv_tp_start(bat_priv, dst, test_length, &cookie, BATADV_TP_USERSPACE);
+	batadv_tp_start(bat_priv, dst, NULL, test_length, &cookie,
+			BATADV_TP_USERSPACE);
 
 	ret = batadv_netlink_tp_meter_put(msg, cookie);
 
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index cc3ed93a..2a2c1ffe 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -229,6 +229,7 @@ bool batadv_check_management_packet(struct sk_buff *skb,
  * otherwise.
  */
 static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
+				      struct batadv_hard_iface *recv_if,
 				      struct sk_buff *skb)
 {
 	struct batadv_hard_iface *primary_if = NULL;
@@ -281,7 +282,7 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
 		if (!pskb_may_pull(skb, sizeof(struct batadv_icmp_tp_packet)))
 			goto out;
 
-		batadv_tp_meter_recv(bat_priv, skb);
+		batadv_tp_meter_recv(bat_priv, recv_if, skb);
 		ret = NET_RX_SUCCESS;
 		/* skb was consumed */
 		skb = NULL;
@@ -418,7 +419,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
 
 	/* packet for me */
 	if (batadv_is_my_mac(bat_priv, icmph->dst))
-		return batadv_recv_my_icmp_packet(bat_priv, skb);
+		return batadv_recv_my_icmp_packet(bat_priv, recv_if, skb);
 
 	/* TTL exceeded */
 	if (icmph->ttl < 2)
diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
index f7bb45d3..1526286b 100644
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -378,6 +378,9 @@ static void batadv_tp_vars_release(struct kref *ref)
 	}
 	spin_unlock_bh(&tp_vars->unacked_lock);
 
+	if (tp_vars->hardif_neigh)
+		batadv_hardif_neigh_put(tp_vars->hardif_neigh);
+
 	kfree_rcu(tp_vars, rcu);
 }
 
@@ -591,26 +594,57 @@ static void batadv_tp_fill_prerandom(struct batadv_tp_vars *tp_vars,
  * not reachable, BATADV_TP_REASON_MEMORY_ERROR if the packet couldn't be
  * allocated
  */
-static int batadv_tp_send_msg(struct batadv_tp_vars *tp_vars, const u8 *src,
-			      struct batadv_orig_node *orig_node,
-			      u32 seqno, size_t len, const u8 *session,
-			      int uid, u32 timestamp)
+static int batadv_tp_send_msg(struct batadv_priv *bat_priv,
+			      struct batadv_tp_vars *tp_vars, u32 seqno,
+			      size_t len, const u8 *session, int uid,
+			      u32 timestamp)
 {
+	struct batadv_hard_iface *primary_if = NULL;
+	struct batadv_orig_node *orig_node = NULL;
 	struct batadv_icmp_tp_packet *icmp;
 	struct sk_buff *skb;
-	int r;
-	u8 *data;
+	int r, ret = 0;
+	u8 *data, *src, *dst, subtype;
+	struct net_device *netdev;
 	size_t data_len;
 
-	skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
-	if (unlikely(!skb))
-		return BATADV_TP_REASON_MEMORY_ERROR;
+	/* link test */
+	if (tp_vars->hardif_neigh) {
+		dst = tp_vars->hardif_neigh->addr;
+		src = tp_vars->hardif_neigh->if_incoming->net_dev->dev_addr;
+		subtype = BATADV_TP_MSG_LINK;
+		netdev = tp_vars->hardif_neigh->if_incoming->net_dev;
+	} else {
+		orig_node = batadv_orig_hash_find(bat_priv, tp_vars->other_end);
+		if (unlikely(!orig_node)) {
+			ret = BATADV_TP_REASON_DST_UNREACHABLE;
+			goto out;
+		}
+
+
+		primary_if = batadv_primary_if_get_selected(bat_priv);
+		if (unlikely(!primary_if)) {
+			ret = BATADV_TP_REASON_DST_UNREACHABLE;
+			goto out;
+		}
+
+		dst = orig_node->orig;
+		src = primary_if->net_dev->dev_addr;
+		subtype = BATADV_TP_MSG;
+		netdev = NULL;
+	}
+
+	skb = netdev_alloc_skb_ip_align(netdev, len + ETH_HLEN);
+	if (unlikely(!skb)) {
+		ret = BATADV_TP_REASON_MEMORY_ERROR;
+		goto out;
+	}
 
 	skb_reserve(skb, ETH_HLEN);
 	icmp = skb_put(skb, sizeof(*icmp));
 
 	/* fill the icmp header */
-	ether_addr_copy(icmp->dst, orig_node->orig);
+	ether_addr_copy(icmp->dst, dst);
 	ether_addr_copy(icmp->orig, src);
 	icmp->version = BATADV_COMPAT_VERSION;
 	icmp->packet_type = BATADV_ICMP;
@@ -618,7 +652,7 @@ static int batadv_tp_send_msg(struct batadv_tp_vars *tp_vars, const u8 *src,
 	icmp->msg_type = BATADV_TP;
 	icmp->uid = uid;
 
-	icmp->subtype = BATADV_TP_MSG;
+	icmp->subtype = subtype;
 	memcpy(icmp->session, session, sizeof(icmp->session));
 	icmp->seqno = htonl(seqno);
 	icmp->timestamp = htonl(timestamp);
@@ -627,11 +661,23 @@ static int batadv_tp_send_msg(struct batadv_tp_vars *tp_vars, const u8 *src,
 	data = skb_put(skb, data_len);
 	batadv_tp_fill_prerandom(tp_vars, data, data_len);
 
-	r = batadv_send_skb_to_orig(skb, orig_node, NULL);
-	if (r == NET_XMIT_SUCCESS)
-		return 0;
+	if (tp_vars->hardif_neigh)
+		r = batadv_send_skb_packet(skb,
+					   tp_vars->hardif_neigh->if_incoming,
+					   dst);
+	else
+		r = batadv_send_skb_to_orig(skb, orig_node, NULL);
+
+	if (unlikely(r != NET_XMIT_SUCCESS))
+		ret = BATADV_TP_REASON_CANT_SEND;
 
-	return BATADV_TP_REASON_CANT_SEND;
+out:
+	if (likely(primary_if))
+		batadv_hardif_put(primary_if);
+	if (likely(orig_node))
+		batadv_orig_node_put(orig_node);
+
+	return ret;
 }
 
 /**
@@ -650,7 +696,6 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,
 	struct batadv_tp_vars *tp_vars;
 	size_t packet_len, mss;
 	u32 rtt, recv_ack, cwnd;
-	unsigned char *dev_addr;
 
 	packet_len = BATADV_TP_PLEN;
 	mss = BATADV_TP_PLEN;
@@ -672,13 +717,11 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,
 			      (u32)atomic_read(&tp_vars->last_acked)))
 		goto out;
 
-	primary_if = batadv_primary_if_get_selected(bat_priv);
-	if (unlikely(!primary_if))
-		goto out;
-
-	orig_node = batadv_orig_hash_find(bat_priv, icmp->orig);
-	if (unlikely(!orig_node))
-		goto out;
+	if (!tp_vars->hardif_neigh) {
+		primary_if = batadv_primary_if_get_selected(bat_priv);
+		if (unlikely(!primary_if))
+			goto out;
+	}
 
 	/* update RTO with the new sampled RTT, if any */
 	rtt = jiffies_to_msecs(jiffies) - ntohl(icmp->timestamp);
@@ -700,8 +743,11 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,
 			goto out;
 
 		/* if this is the third duplicate ACK do Fast Retransmit */
-		batadv_tp_send_msg(tp_vars, primary_if->net_dev->dev_addr,
-				   orig_node, recv_ack, packet_len,
+
+		/* if we have a hardif_neigh, it means that this is a LINK test,
+		 * therefore use the according function
+		 */
+		batadv_tp_send_msg(bat_priv, tp_vars, recv_ack, packet_len,
 				   icmp->session, icmp->uid,
 				   jiffies_to_msecs(jiffies));
 
@@ -738,9 +784,7 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,
 				 * immediately as specified by NewReno (see
 				 * Section 3.2 of RFC6582 for details)
 				 */
-				dev_addr = primary_if->net_dev->dev_addr;
-				batadv_tp_send_msg(tp_vars, dev_addr,
-						   orig_node, recv_ack,
+				batadv_tp_send_msg(bat_priv, tp_vars, recv_ack,
 						   packet_len, icmp->session,
 						   icmp->uid,
 						   jiffies_to_msecs(jiffies));
@@ -824,8 +868,6 @@ static int batadv_tp_wait_available(struct batadv_tp_vars *tp_vars, size_t plen)
  */
 static void batadv_tp_send(struct work_struct *work)
 {
-	struct batadv_hard_iface *primary_if = NULL;
-	struct batadv_orig_node *orig_node = NULL;
 	struct batadv_tp_vars *tp_vars;
 	size_t payload_len, packet_len;
 	struct batadv_priv *bat_priv;
@@ -840,20 +882,6 @@ static void batadv_tp_send(struct work_struct *work)
 		goto out;
 	}
 
-	orig_node = batadv_orig_hash_find(bat_priv, tp_vars->other_end);
-	if (unlikely(!orig_node)) {
-		err = BATADV_TP_REASON_DST_UNREACHABLE;
-		tp_vars->reason = err;
-		goto out;
-	}
-
-	primary_if = batadv_primary_if_get_selected(bat_priv);
-	if (unlikely(!primary_if)) {
-		err = BATADV_TP_REASON_DST_UNREACHABLE;
-		tp_vars->reason = err;
-		goto out;
-	}
-
 	/* assume that all the hard_interfaces have a correctly
 	 * configured MTU, so use the soft_iface MTU as MSS.
 	 * This might not be true and in that case the fragmentation
@@ -880,10 +908,9 @@ static void batadv_tp_send(struct work_struct *work)
 		 */
 		packet_len = payload_len + sizeof(struct batadv_unicast_packet);
 
-		err = batadv_tp_send_msg(tp_vars, primary_if->net_dev->dev_addr,
-					 orig_node, tp_vars->last_sent,
-					 packet_len,
-					 tp_vars->session, tp_vars->icmp_uid,
+		err = batadv_tp_send_msg(bat_priv, tp_vars, tp_vars->last_sent,
+					 packet_len, tp_vars->session,
+					 tp_vars->icmp_uid,
 					 jiffies_to_msecs(jiffies));
 
 		/* something went wrong during the preparation/transmission */
@@ -905,11 +932,6 @@ static void batadv_tp_send(struct work_struct *work)
 	}
 
 out:
-	if (likely(primary_if))
-		batadv_hardif_put(primary_if);
-	if (likely(orig_node))
-		batadv_orig_node_put(orig_node);
-
 	batadv_tp_sender_end(bat_priv, tp_vars);
 	batadv_tp_sender_cleanup(bat_priv, tp_vars);
 
@@ -936,17 +958,20 @@ static void batadv_tp_start_work(struct batadv_tp_vars *tp_vars)
  * @caller: caller of tp meter session (user space or ELP)
  */
 void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
+		     struct batadv_hardif_neigh_node *neigh,
 		     u32 test_length, u32 *cookie, enum batadv_tp_meter_caller caller)
 {
 	struct batadv_tp_vars *tp_vars;
 	u8 session_id[2];
 	u8 icmp_uid;
-	u32 session_cookie;
+	u32 session_cookie = 0;
 
 	get_random_bytes(session_id, sizeof(session_id));
 	get_random_bytes(&icmp_uid, 1);
-	session_cookie = batadv_tp_session_cookie(session_id, icmp_uid);
-	*cookie = session_cookie;
+	if (cookie) {
+		session_cookie = batadv_tp_session_cookie(session_id, icmp_uid);
+		*cookie = session_cookie;
+	}
 
 	if (!atomic_add_unless(&bat_priv->tp_num, 1, BATADV_TP_MAX_NUM_QUEUE)) {
 		spin_unlock_bh(&bat_priv->tp_list_lock);
@@ -969,6 +994,10 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
 
 	/* initialize tp_vars */
 	ether_addr_copy(tp_vars->other_end, dst);
+	if (neigh) {
+		kref_get(&neigh->refcount);
+		tp_vars->hardif_neigh = neigh;
+	}
 	kref_init(&tp_vars->refcount);
 	tp_vars->role = BATADV_TP_SENDER;
 	tp_vars->caller = caller;
@@ -1139,29 +1168,42 @@ static void batadv_tp_receiver_shutdown(struct timer_list *t)
  * Return: 0 on success, a positive integer representing the reason of the
  * failure otherwise
  */
-static int batadv_tp_send_ack(struct batadv_priv *bat_priv, const u8 *dst,
+static int batadv_tp_send_ack(struct batadv_priv *bat_priv,
+			      struct batadv_tp_vars *tp_vars,
 			      u32 seq, __be32 timestamp, const u8 *session,
 			      int socket_index)
 {
 	struct batadv_hard_iface *primary_if = NULL;
-	struct batadv_orig_node *orig_node;
+	struct batadv_orig_node *orig_node = NULL;
 	struct batadv_icmp_tp_packet *icmp;
+	struct net_device *netdev = NULL;
 	struct sk_buff *skb;
+	u8 *src, *dst;
 	int r, ret;
 
-	orig_node = batadv_orig_hash_find(bat_priv, dst);
-	if (unlikely(!orig_node)) {
-		ret = BATADV_TP_REASON_DST_UNREACHABLE;
-		goto out;
-	}
+	if (tp_vars->hardif_neigh) {
+		dst = tp_vars->hardif_neigh->addr;
+		src = tp_vars->hardif_neigh->if_incoming->net_dev->dev_addr;
+		netdev = tp_vars->hardif_neigh->if_incoming->net_dev;
+	} else {
+		orig_node = batadv_orig_hash_find(bat_priv, tp_vars->other_end);
+		if (unlikely(!orig_node)) {
+			ret = BATADV_TP_REASON_DST_UNREACHABLE;
+			goto out;
+		}
 
-	primary_if = batadv_primary_if_get_selected(bat_priv);
-	if (unlikely(!primary_if)) {
-		ret = BATADV_TP_REASON_DST_UNREACHABLE;
-		goto out;
+		primary_if = batadv_primary_if_get_selected(bat_priv);
+		if (unlikely(!primary_if)) {
+			ret = BATADV_TP_REASON_DST_UNREACHABLE;
+			goto out;
+		}
+
+		dst = orig_node->orig;
+		src = primary_if->net_dev->dev_addr;
+		netdev = NULL;
 	}
 
-	skb = netdev_alloc_skb_ip_align(NULL, sizeof(*icmp) + ETH_HLEN);
+	skb = netdev_alloc_skb_ip_align(netdev, sizeof(*icmp) + ETH_HLEN);
 	if (unlikely(!skb)) {
 		ret = BATADV_TP_REASON_MEMORY_ERROR;
 		goto out;
@@ -1183,7 +1225,13 @@ static int batadv_tp_send_ack(struct batadv_priv *bat_priv, const u8 *dst,
 	icmp->timestamp = timestamp;
 
 	/* send the ack */
-	r = batadv_send_skb_to_orig(skb, orig_node, NULL);
+	if (tp_vars->hardif_neigh)
+		r = batadv_send_skb_packet(skb,
+					   tp_vars->hardif_neigh->if_incoming,
+					   dst);
+	else
+		r = batadv_send_skb_to_orig(skb, orig_node, NULL);
+
 	if (unlikely(r < 0) || r == NET_XMIT_DROP) {
 		ret = BATADV_TP_REASON_DST_UNREACHABLE;
 		goto out;
@@ -1317,8 +1365,10 @@ static void batadv_tp_ack_unordered(struct batadv_tp_vars *tp_vars)
  */
 static struct batadv_tp_vars *
 batadv_tp_init_recv(struct batadv_priv *bat_priv,
+		    struct batadv_hard_iface *recv_if,
 		    const struct batadv_icmp_tp_packet *icmp)
 {
+	struct batadv_hardif_neigh_node *neigh = NULL;
 	struct batadv_tp_vars *tp_vars;
 
 	spin_lock_bh(&bat_priv->tp_list_lock);
@@ -1333,15 +1383,30 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv,
 		goto out_unlock;
 	}
 
+	/* the sender is starting a LINK test, therefore we have retrieve its
+	 * corresponding hardif_neigh_node that we'll use later to send ACKs
+	 * back
+	 */
+	if (icmp->subtype == BATADV_TP_MSG_LINK) {
+		neigh = batadv_hardif_neigh_get(recv_if, icmp->orig);
+		if (!neigh) {
+			batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
+				   "Meter: %s() can't retrieve sender neigh object for %pM\n",
+				   __func__, icmp->orig);
+			goto out_unlock;
+		}
+	}
+
 	tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC);
 	if (!tp_vars)
-		goto out_unlock;
+		goto err_neigh_put;
 
 	ether_addr_copy(tp_vars->other_end, icmp->orig);
 	tp_vars->role = BATADV_TP_RECEIVER;
 	memcpy(tp_vars->session, icmp->session, sizeof(tp_vars->session));
 	tp_vars->last_recv = BATADV_TP_FIRST_SEQ;
 	tp_vars->bat_priv = bat_priv;
+	tp_vars->hardif_neigh = neigh;
 	kref_init(&tp_vars->refcount);
 
 	spin_lock_init(&tp_vars->unacked_lock);
@@ -1354,7 +1419,10 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv,
 	timer_setup(&tp_vars->timer, batadv_tp_receiver_shutdown, 0);
 
 	batadv_tp_reset_receiver_timer(tp_vars);
+	goto out_unlock;
 
+err_neigh_put:
+	batadv_hardif_neigh_put(neigh);
 out_unlock:
 	spin_unlock_bh(&bat_priv->tp_list_lock);
 
@@ -1369,6 +1437,7 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv,
  * Process a received TP MSG packet
  */
 static void batadv_tp_recv_msg(struct batadv_priv *bat_priv,
+			       struct batadv_hard_iface *recv_if,
 			       const struct sk_buff *skb)
 {
 	const struct batadv_icmp_tp_packet *icmp;
@@ -1383,7 +1452,7 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv,
 	 * first packet is lost, the tp meter does not work anymore!
 	 */
 	if (seqno == BATADV_TP_FIRST_SEQ) {
-		tp_vars = batadv_tp_init_recv(bat_priv, icmp);
+		tp_vars = batadv_tp_init_recv(bat_priv, recv_if, icmp);
 		if (!tp_vars) {
 			batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
 				   "Meter: seqno != BATADV_TP_FIRST_SEQ cannot initiate connection\n");
@@ -1439,7 +1508,7 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv,
 	 * is going to be sent is a duplicate (the sender will count them and
 	 * possibly enter Fast Retransmit as soon as it has reached 3)
 	 */
-	batadv_tp_send_ack(bat_priv, icmp->orig, tp_vars->last_recv,
+	batadv_tp_send_ack(bat_priv, tp_vars, tp_vars->last_recv,
 			   icmp->timestamp, icmp->session, icmp->uid);
 out:
 	if (likely(tp_vars))
@@ -1451,7 +1520,9 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv,
  * @bat_priv: the bat priv with all the soft interface information
  * @skb: the buffer containing the received packet
  */
-void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb)
+void batadv_tp_meter_recv(struct batadv_priv *bat_priv,
+                          struct batadv_hard_iface *recv_if,
+                          struct sk_buff *skb)
 {
 	struct batadv_icmp_tp_packet *icmp;
 
@@ -1459,7 +1530,8 @@ void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb)
 
 	switch (icmp->subtype) {
 	case BATADV_TP_MSG:
-		batadv_tp_recv_msg(bat_priv, skb);
+	case BATADV_TP_MSG_LINK:
+		batadv_tp_recv_msg(bat_priv, recv_if, skb);
 		break;
 	case BATADV_TP_ACK:
 		batadv_tp_recv_ack(bat_priv, skb);
diff --git a/net/batman-adv/tp_meter.h b/net/batman-adv/tp_meter.h
index d844575d..3a1be483 100644
--- a/net/batman-adv/tp_meter.h
+++ b/net/batman-adv/tp_meter.h
@@ -28,9 +28,13 @@ struct sk_buff;
 int batadv_tp_meter_init(void);
 void batadv_tp_meter_destroy(void);
 void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
-		     u32 test_length, u32 *cookie, enum batadv_tp_meter_caller caller);
+		     struct batadv_hardif_neigh_node *neigh,
+		     u32 test_length, u32 *cookie,
+		     enum batadv_tp_meter_caller caller);
 void batadv_tp_stop(struct batadv_priv *bat_priv, const u8 *dst,
 		    u8 return_value);
-void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb);
+void batadv_tp_meter_recv(struct batadv_priv *bat_priv,
+			  struct batadv_hard_iface *recv_if,
+			  struct sk_buff *skb);
 
 #endif /* _NET_BATMAN_ADV_TP_METER_H_ */
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 826b3b42..98dccc6c 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1454,6 +1454,9 @@ struct batadv_tp_vars {
 
 	/** @rcu: struct used for freeing in an RCU-safe manner */
 	struct rcu_head rcu;
+
+	/** @neigh_node: in case of LINK test, represents the other-end */
+	struct batadv_hardif_neigh_node *hardif_neigh;
 };
 
 /**
-- 
2.17.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [B.A.T.M.A.N.] [RFC 6/6] batman-adv: ELP - use tp meter to estimate the throughput if otherwise not available
  2018-05-08 16:41 [B.A.T.M.A.N.] [RFC 0/6] B.A.T.M.A.N. V - fallback to tp meter estimation if throughput otherwise not available Marek Lindner
                   ` (4 preceding siblings ...)
  2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 5/6] batman-adv: to_meter - add option to perform one-hop test Marek Lindner
@ 2018-05-08 16:41 ` Marek Lindner
  2018-05-08 18:36 ` [B.A.T.M.A.N.] [RFC 0/6] B.A.T.M.A.N. V - fallback to tp meter estimation if throughput " Sven Eckelmann
  6 siblings, 0 replies; 8+ messages in thread
From: Marek Lindner @ 2018-05-08 16:41 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
---
 net/batman-adv/bat_v_elp.c | 62 ++++++++++++++++++++++++++++++++++++--
 net/batman-adv/bat_v_elp.h | 19 ++++++++++++
 net/batman-adv/main.h      |  1 +
 net/batman-adv/tp_meter.c  | 25 +++++++++++++--
 net/batman-adv/types.h     |  9 ++++++
 5 files changed, 111 insertions(+), 5 deletions(-)

diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
index 28687493..028dc3ab 100644
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -51,6 +51,7 @@
 #include "originator.h"
 #include "routing.h"
 #include "send.h"
+#include "tp_meter.h"
 
 /**
  * batadv_v_elp_start_timer() - restart timer for ELP periodic work
@@ -67,6 +68,41 @@ static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface)
 			   msecs_to_jiffies(msecs));
 }
 
+/**
+ * batadv_v_elp_tp_start() - start a tp meter session for a neighbor
+ * @neigh: neighbor to run tp meter on
+ */
+static void batadv_v_elp_tp_start(struct batadv_hardif_neigh_node *neigh)
+{
+	struct batadv_hard_iface *hard_iface = neigh->if_incoming;
+	struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+
+	neigh->bat_v.tp_meter_running = true;
+	batadv_tp_start(bat_priv, neigh->addr, neigh, 10, NULL, BATADV_TP_ELP);
+}
+
+/**
+ * batadv_v_elp_tp_fail() - handle tp meter session failure
+ * @neigh: neighbor to run tp meter on
+ */
+void batadv_v_elp_tp_fail(struct batadv_hardif_neigh_node *neigh)
+{
+	neigh->bat_v.tp_meter_running = false;
+}
+
+/**
+ * batadv_v_elp_tp_finish() - post-process tp meter results
+ * @neigh: neighbor tp meter on
+ * @throughput: tp meter throughput result
+ */
+void batadv_v_elp_tp_finish(struct batadv_hardif_neigh_node *neigh,
+			    u32 throughput)
+{
+	ewma_throughput_add(&neigh->bat_v.throughput, throughput);
+	neigh->bat_v.last_tp_meter_run = jiffies;
+	neigh->bat_v.tp_meter_running = false;
+}
+
 /**
  * batadv_v_elp_get_throughput() - get the throughput towards a neighbour
  * @neigh: the neighbour for which the throughput has to be obtained
@@ -80,6 +116,7 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
 	struct ethtool_link_ksettings link_settings;
 	struct net_device *real_netdev;
 	struct station_info sinfo;
+	u32 last_tp_run_msecs;
 	u32 throughput;
 	int ret;
 
@@ -112,10 +149,13 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
 			 */
 			return 0;
 		}
+
+		/* unsupported WiFi driver */
 		if (ret)
-			goto default_throughput;
+			goto fallback_throughput;
+
 		if (!(sinfo.filled & BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT)))
-			goto default_throughput;
+			goto fallback_throughput;
 
 		return sinfo.expected_throughput / 100;
 	}
@@ -139,6 +179,24 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
 			return throughput * 10;
 	}
 
+fallback_throughput:
+	last_tp_run_msecs = jiffies_to_msecs(jiffies - neigh->bat_v.last_tp_meter_run);
+
+	/* check the tp_meter_running flag before checking the timestamp to
+	 * avoid a race condition where a new tp meter session is scheduled
+	 * right after the previous tp meter session has completed
+	 */
+	if (!neigh->bat_v.tp_meter_running &&
+	    last_tp_run_msecs > BATADV_ELP_TP_RUN_INTERVAL)
+		batadv_v_elp_tp_start(neigh);
+
+	/* discard too old tp test results */
+	if (last_tp_run_msecs > 2 * BATADV_ELP_TP_RUN_INTERVAL)
+		neigh->bat_v.tp_meter_throughput = 0;
+
+	if (!neigh->bat_v.tp_meter_throughput)
+		return neigh->bat_v.tp_meter_throughput;
+
 default_throughput:
 	if (!(hard_iface->bat_v.flags & BATADV_WARNING_DEFAULT)) {
 		batadv_info(hard_iface->soft_iface,
diff --git a/net/batman-adv/bat_v_elp.h b/net/batman-adv/bat_v_elp.h
index e8c7b7fd..d0605054 100644
--- a/net/batman-adv/bat_v_elp.h
+++ b/net/batman-adv/bat_v_elp.h
@@ -33,4 +33,23 @@ int batadv_v_elp_packet_recv(struct sk_buff *skb,
 			     struct batadv_hard_iface *if_incoming);
 void batadv_v_elp_throughput_metric_update(struct work_struct *work);
 
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+
+void batadv_v_elp_tp_fail(struct batadv_hardif_neigh_node *neigh);
+void batadv_v_elp_tp_finish(struct batadv_hardif_neigh_node *neigh,
+			    u32 throughput);
+
+#else
+
+static inline void batadv_v_elp_tp_fail(struct batadv_hardif_neigh_node *neigh)
+{
+}
+
+static inline void
+batadv_v_elp_tp_finish(struct batadv_hardif_neigh_node *neigh, u32 throughput)
+{
+}
+
+#endif /* CONFIG_BATMAN_ADV_BATMAN_V */
+
 #endif /* _NET_BATMAN_ADV_BAT_V_ELP_H_ */
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 89dfaf87..ed4ae913 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -69,6 +69,7 @@
 #define BATADV_ELP_MIN_PROBE_SIZE 200 /* bytes */
 #define BATADV_ELP_PROBE_MAX_TX_DIFF 100 /* milliseconds */
 #define BATADV_ELP_MAX_AGE 64
+#define BATADV_ELP_TP_RUN_INTERVAL 60000 /* milliseconds */
 #define BATADV_OGM_MAX_ORIGDIFF 5
 #define BATADV_OGM_MAX_AGE 64
 
diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
index 1526286b..e7a3c24e 100644
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -56,6 +56,7 @@
 #include "netlink.h"
 #include "originator.h"
 #include "send.h"
+#include "bat_v_elp.h"
 
 /**
  * BATADV_TP_DEF_TEST_LENGTH - Default test length if not specified by the user
@@ -225,6 +226,7 @@ static void batadv_tp_caller_notify(struct batadv_priv *bat_priv,
 				    enum batadv_tp_meter_reason reason)
 {
 	u32 total_bytes;
+	u64 throughput;
 	u32 test_time;
 	u32 cookie;
 	bool reason_is_error;
@@ -249,6 +251,21 @@ static void batadv_tp_caller_notify(struct batadv_priv *bat_priv,
 
 		break;
 	case BATADV_TP_ELP:
+		if (reason_is_error) {
+			batadv_v_elp_tp_fail(tp_vars->hardif_neigh);
+			return;
+		}
+
+		test_time = jiffies_to_msecs(jiffies - tp_vars->start_time);
+		total_bytes = atomic64_read(&tp_vars->tot_sent);
+
+		/* The following calculation includes these steps:
+		 * - convert bytes to bits
+		 * - divide bits by the test length (msecs)
+		 * - convert result from bits/ms to 0.1Mb/s (* 1024 * 10 / 1000)
+		 */
+		throughput = total_bytes * 8 >> ilog2(test_time) / 10;
+		batadv_v_elp_tp_finish(tp_vars->hardif_neigh, throughput);
 		break;
 	default:
 		break;
@@ -266,13 +283,15 @@ static void batadv_tp_caller_notify(struct batadv_priv *bat_priv,
 static void batadv_tp_caller_init_error(struct batadv_priv *bat_priv,
 					enum batadv_tp_meter_caller caller,
 					enum batadv_tp_meter_reason reason,
-					const u8 *dst, u32 cookie)
+					const u8 *dst, u32 cookie,
+					struct batadv_hardif_neigh_node *hardif_neigh)
 {
 	switch (caller) {
 	case BATADV_TP_USERSPACE:
 		batadv_netlink_tpmeter_notify(bat_priv, dst, reason, 0, 0, cookie);
 		break;
 	case BATADV_TP_ELP:
+		batadv_v_elp_tp_fail(hardif_neigh);
 		break;
 	default:
 		break;
@@ -978,7 +997,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
 		batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
 			   "Meter: too many ongoing sessions, aborting (SEND)\n");
 		batadv_tp_caller_init_error(bat_priv, caller, BATADV_TP_REASON_TOO_MANY,
-					    dst, session_cookie);
+					    dst, session_cookie, neigh);
 		return;
 	}
 
@@ -988,7 +1007,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
 			   "Meter: %s cannot allocate list elements\n",
 			   __func__);
 		batadv_tp_caller_init_error(bat_priv, caller, BATADV_TP_REASON_MEMORY_ERROR,
-					    dst, session_cookie);
+					    dst, session_cookie, neigh);
 		return;
 	}
 
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 98dccc6c..54fabcb1 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -583,6 +583,15 @@ struct batadv_hardif_neigh_node_bat_v {
 
 	/** @metric_work: work queue callback item for metric update */
 	struct work_struct metric_work;
+
+	/** @tp_meter_running: tp meter measurements towards this neighbor in progress */
+	bool tp_meter_running;
+
+	/** @last_tp_meter_run: timestamp of last tp meter measurement completion */
+	unsigned long last_tp_meter_run;
+
+	/** @tp_meter_throughput: throughput information measured by tp meter */
+	unsigned long tp_meter_throughput;
 };
 
 /**
-- 
2.17.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC 0/6] B.A.T.M.A.N. V - fallback to tp meter estimation if throughput otherwise not available
  2018-05-08 16:41 [B.A.T.M.A.N.] [RFC 0/6] B.A.T.M.A.N. V - fallback to tp meter estimation if throughput otherwise not available Marek Lindner
                   ` (5 preceding siblings ...)
  2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 6/6] batman-adv: ELP - use tp meter to estimate the throughput if otherwise not available Marek Lindner
@ 2018-05-08 18:36 ` Sven Eckelmann
  6 siblings, 0 replies; 8+ messages in thread
From: Sven Eckelmann @ 2018-05-08 18:36 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

[-- Attachment #1: Type: text/plain, Size: 18589 bytes --]

Name of failed tests
====================

ecsv/pu
-------

 * checkpatch ./net/batman-adv/bat_v_elp.c
 * checkpatch ./net/batman-adv/tp_meter.c
 * checkpatch ./net/batman-adv/types.h
 * headers
 * kerneldoc ./net/batman-adv/routing.c
 * kerneldoc ./net/batman-adv/tp_meter.c
 * kerneldoc ./net/batman-adv/types.h
 * kerneldoc include/uapi/linux/batadv_packet.h
 * smatch linux-3.10 CONFIG_BATMAN_ADV_BLA=n CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=n
 * smatch linux-3.10 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=n
 * smatch linux-3.11 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=n CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=n
 * smatch linux-3.15 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=n
 * smatch linux-3.16 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=n CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=n CONFIG_BATMAN_ADV_NC=n CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=y
 * smatch linux-3.16 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_DEBUGFS=n CONFIG_BATMAN_ADV_DEBUG=n CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=n
 * smatch linux-3.18 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=y
 * smatch linux-3.19 CONFIG_BATMAN_ADV_BLA=n CONFIG_BATMAN_ADV_DAT=n CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_BATMAN_ADV_NC=n CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=y
 * smatch linux-3.19 CONFIG_BATMAN_ADV_BLA=n CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_DEBUGFS=n CONFIG_BATMAN_ADV_DEBUG=n CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=n
 * smatch linux-3.4 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=n CONFIG_BATMAN_ADV_DEBUGFS=n CONFIG_BATMAN_ADV_DEBUG=n CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=n CONFIG_BATMAN_ADV_BATMAN_V=n
 * smatch linux-3.5 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=n CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=n
 * smatch linux-3.7 CONFIG_BATMAN_ADV_BLA=n CONFIG_BATMAN_ADV_DAT=n CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=n
 * smatch linux-4.0 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=n CONFIG_BATMAN_ADV_DEBUGFS=n CONFIG_BATMAN_ADV_DEBUG=n CONFIG_BATMAN_ADV_NC=n CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=y
 * smatch linux-4.10 CONFIG_BATMAN_ADV_BLA=n CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=n
 * smatch linux-4.10 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=n CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_BATMAN_ADV_NC=n CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=y
 * smatch linux-4.11 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=n CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_BATMAN_ADV_NC=n CONFIG_BATMAN_ADV_MCAST=n CONFIG_BATMAN_ADV_BATMAN_V=y
 * smatch linux-4.12 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=n CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_BATMAN_ADV_NC=n CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=y
 * smatch linux-4.15 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=n CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=n
 * smatch linux-4.4 CONFIG_BATMAN_ADV_BLA=n CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=n CONFIG_BATMAN_ADV_NC=n CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=n
 * smatch linux-4.6 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=n CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=n CONFIG_BATMAN_ADV_NC=n CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=y
 * smatch linux-4.6 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=n CONFIG_BATMAN_ADV_NC=n CONFIG_BATMAN_ADV_MCAST=n CONFIG_BATMAN_ADV_BATMAN_V=n
 * smatch linux-4.8 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_DEBUGFS=n CONFIG_BATMAN_ADV_DEBUG=n CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=n CONFIG_BATMAN_ADV_BATMAN_V=n
 * smatch linux-4.9 CONFIG_BATMAN_ADV_BLA=n CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_BATMAN_ADV_NC=n CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=n
 * sparse linux-3.10 cfg: BLA=n DAT=y DEBUGFS=y DEBUG=y NC=y MCAST=y BATMAN_V=n
 * sparse linux-3.10 cfg: BLA=y DAT=y DEBUGFS=y DEBUG=y NC=y MCAST=y BATMAN_V=n
 * sparse linux-3.11 cfg: BLA=y DAT=n DEBUGFS=y DEBUG=y NC=y MCAST=y BATMAN_V=n
 * sparse linux-3.15 cfg: BLA=y DAT=y DEBUGFS=y DEBUG=y NC=y MCAST=y BATMAN_V=n
 * sparse linux-3.16 cfg: BLA=y DAT=n DEBUGFS=y DEBUG=n NC=n MCAST=y BATMAN_V=y
 * sparse linux-3.16 cfg: BLA=y DAT=y DEBUGFS=n DEBUG=n NC=y MCAST=y BATMAN_V=n
 * sparse linux-3.18 cfg: BLA=y DAT=y DEBUGFS=y DEBUG=y NC=y MCAST=y BATMAN_V=y
 * sparse linux-3.19 cfg: BLA=n DAT=n DEBUGFS=y DEBUG=y NC=n MCAST=y BATMAN_V=y
 * sparse linux-3.19 cfg: BLA=n DAT=y DEBUGFS=n DEBUG=n NC=y MCAST=y BATMAN_V=n
 * sparse linux-3.4 cfg: BLA=y DAT=n DEBUGFS=n DEBUG=n NC=y MCAST=n BATMAN_V=n
 * sparse linux-3.5 cfg: BLA=y DAT=n DEBUGFS=y DEBUG=y NC=y MCAST=y BATMAN_V=n
 * sparse linux-3.7 cfg: BLA=n DAT=n DEBUGFS=y DEBUG=y NC=y MCAST=y BATMAN_V=n
 * sparse linux-4.0 cfg: BLA=y DAT=n DEBUGFS=n DEBUG=n NC=n MCAST=y BATMAN_V=y
 * sparse linux-4.10 cfg: BLA=n DAT=y DEBUGFS=y DEBUG=y NC=y MCAST=y BATMAN_V=n
 * sparse linux-4.10 cfg: BLA=y DAT=n DEBUGFS=y DEBUG=y NC=n MCAST=y BATMAN_V=y
 * sparse linux-4.11 cfg: BLA=y DAT=n DEBUGFS=y DEBUG=y NC=n MCAST=n BATMAN_V=y
 * sparse linux-4.12 cfg: BLA=y DAT=n DEBUGFS=y DEBUG=y NC=n MCAST=y BATMAN_V=y
 * sparse linux-4.15 cfg: BLA=y DAT=y DEBUGFS=y DEBUG=n NC=y MCAST=y BATMAN_V=n
 * sparse linux-4.4 cfg: BLA=n DAT=y DEBUGFS=y DEBUG=n NC=n MCAST=y BATMAN_V=n
 * sparse linux-4.6 cfg: BLA=y DAT=n DEBUGFS=y DEBUG=n NC=n MCAST=y BATMAN_V=y
 * sparse linux-4.6 cfg: BLA=y DAT=y DEBUGFS=y DEBUG=n NC=n MCAST=n BATMAN_V=n
 * sparse linux-4.8 cfg: BLA=y DAT=y DEBUGFS=n DEBUG=n NC=y MCAST=n BATMAN_V=n
 * sparse linux-4.9 cfg: BLA=n DAT=y DEBUGFS=y DEBUG=y NC=n MCAST=y BATMAN_V=n


Output of different failed tests
================================

ecsv/pu: checkpatch ./net/batman-adv/bat_v_elp.c
------------------------------------------------

    WARNING: line over 80 characters
    #183: FILE: ./net/batman-adv/bat_v_elp.c:183:
    +   last_tp_run_msecs = jiffies_to_msecs(jiffies - neigh->bat_v.last_tp_meter_run);
    
    total: 0 errors, 1 warnings, 0 checks, 604 lines checked

ecsv/pu: checkpatch ./net/batman-adv/tp_meter.c
-----------------------------------------------

    WARNING: line over 80 characters
    #238: FILE: ./net/batman-adv/tp_meter.c:238:
    +           cookie = batadv_tp_session_cookie(tp_vars->session, tp_vars->icmp_uid);
    
    WARNING: line over 80 characters
    #241: FILE: ./net/batman-adv/tp_meter.c:241:
    +                   batadv_netlink_tpmeter_notify(bat_priv, tp_vars->other_end,
    
    WARNING: line over 80 characters
    #249: FILE: ./net/batman-adv/tp_meter.c:249:
    +                                         BATADV_TP_REASON_COMPLETE, test_time,
    
    WARNING: line over 80 characters
    #287: FILE: ./net/batman-adv/tp_meter.c:287:
    +                                   struct batadv_hardif_neigh_node *hardif_neigh)
    
    WARNING: line over 80 characters
    #291: FILE: ./net/batman-adv/tp_meter.c:291:
    +           batadv_netlink_tpmeter_notify(bat_priv, dst, reason, 0, 0, cookie);
    
    CHECK: Please don't use multiple blank lines
    #643: FILE: ./net/batman-adv/tp_meter.c:643:
    +
    +
    
    ERROR: code indent should use tabs where possible
    #966: FILE: ./net/batman-adv/tp_meter.c:966:
    +        /* init work item that will actually execute the test and schedule it */$
    
    ERROR: code indent should use tabs where possible
    #967: FILE: ./net/batman-adv/tp_meter.c:967:
    +        INIT_WORK(&tp_vars->test_work, batadv_tp_send);$
    
    WARNING: please, no spaces at the start of a line
    #967: FILE: ./net/batman-adv/tp_meter.c:967:
    +        INIT_WORK(&tp_vars->test_work, batadv_tp_send);$
    
    ERROR: code indent should use tabs where possible
    #968: FILE: ./net/batman-adv/tp_meter.c:968:
    +        queue_work(batadv_tp_meter_queue, &tp_vars->test_work);$
    
    WARNING: please, no spaces at the start of a line
    #968: FILE: ./net/batman-adv/tp_meter.c:968:
    +        queue_work(batadv_tp_meter_queue, &tp_vars->test_work);$
    
    WARNING: line over 80 characters
    #981: FILE: ./net/batman-adv/tp_meter.c:981:
    +                u32 test_length, u32 *cookie, enum batadv_tp_meter_caller caller)
    
    WARNING: line over 80 characters
    #999: FILE: ./net/batman-adv/tp_meter.c:999:
    +           batadv_tp_caller_init_error(bat_priv, caller, BATADV_TP_REASON_TOO_MANY,
    
    WARNING: Possible unnecessary 'out of memory' message
    #1006: FILE: ./net/batman-adv/tp_meter.c:1006:
    +   if (!tp_vars) {
    +           batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
    
    WARNING: line over 80 characters
    #1009: FILE: ./net/batman-adv/tp_meter.c:1009:
    +           batadv_tp_caller_init_error(bat_priv, caller, BATADV_TP_REASON_MEMORY_ERROR,
    
    ERROR: code indent should use tabs where possible
    #1543: FILE: ./net/batman-adv/tp_meter.c:1543:
    +                          struct batadv_hard_iface *recv_if,$
    
    WARNING: please, no spaces at the start of a line
    #1543: FILE: ./net/batman-adv/tp_meter.c:1543:
    +                          struct batadv_hard_iface *recv_if,$
    
    ERROR: code indent should use tabs where possible
    #1544: FILE: ./net/batman-adv/tp_meter.c:1544:
    +                          struct sk_buff *skb)$
    
    WARNING: please, no spaces at the start of a line
    #1544: FILE: ./net/batman-adv/tp_meter.c:1544:
    +                          struct sk_buff *skb)$
    
    total: 5 errors, 13 warnings, 1 checks, 1588 lines checked

ecsv/pu: checkpatch ./net/batman-adv/types.h
--------------------------------------------

    WARNING: line over 80 characters
    #587: FILE: ./net/batman-adv/types.h:587:
    +   /** @tp_meter_running: tp meter measurements towards this neighbor in progress */
    
    CHECK: Avoid using bool structure members because of possible alignment issues - see: https://lkml.org/lkml/2017/11/21/384
    #588: FILE: ./net/batman-adv/types.h:588:
    +   bool tp_meter_running;
    
    WARNING: line over 80 characters
    #590: FILE: ./net/batman-adv/types.h:590:
    +   /** @last_tp_meter_run: timestamp of last tp meter measurement completion */
    
    ERROR: code indent should use tabs where possible
    #1367: FILE: ./net/batman-adv/types.h:1367:
    +        /** @caller: caller of tp meter session (user space or ELP) */$
    
    ERROR: code indent should use tabs where possible
    #1370: FILE: ./net/batman-adv/types.h:1370:
    +        /** @sending: sending binary semaphore: 1 if sending, 0 is not */$
    
    ERROR: code indent should use tabs where possible
    #1379: FILE: ./net/batman-adv/types.h:1379:
    +        /** @test_work: work item for the test process */$
    
    ERROR: code indent should use tabs where possible
    #1382: FILE: ./net/batman-adv/types.h:1382:
    +        /** @test_length: test length in milliseconds */$
    
    total: 4 errors, 2 warnings, 1 checks, 2455 lines checked

ecsv/pu: headers
----------------

    diff --git a/build/net/batman-adv/bat_v_elp.h b/build/net/batman-adv/bat_v_elp.h
    index d87886b..cc6af92 100644
    --- a/build/net/batman-adv/bat_v_elp.h
    +++ b/build/net/batman-adv/bat_v_elp.h
    @@ -19,6 +19,8 @@
     #ifndef _NET_BATMAN_ADV_BAT_V_ELP_H_
     #define _NET_BATMAN_ADV_BAT_V_ELP_H_
     
     #include "main.h" // IWYU pragma: keep
    +
    +#include <linux/types.h>
     
     struct sk_buff;
    diff --git a/build/net/batman-adv/tp_meter.c b/build/net/batman-adv/tp_meter.c
    index 770a95d..442580a 100644
    --- a/build/net/batman-adv/tp_meter.c
    +++ b/build/net/batman-adv/tp_meter.c
    @@ -17,6 +17,8 @@
      */
     
     #include "tp_meter.h"
     #include "main.h" // IWYU pragma: keep
     
     #include <linux/atomic.h>
    @@ -24,7 +26,7 @@
     #include <linux/byteorder/generic.h>
     #include <linux/cache.h>
     #include <linux/compiler.h>
    -#include <linux/err.h>
    +#include <linux/errno.h>
     #include <linux/etherdevice.h>
     #include <linux/gfp.h>
     #include <linux/if_ether.h>
    @@ -35,7 +37,6 @@
     #include <linux/list.h>
    +#include <linux/log2.h>
     #include <linux/netdevice.h>
     #include <linux/param.h>
    -#include <linux/printk.h>
     #include <linux/random.h>
     #include <linux/rculist.h>
     #include <linux/rcupdate.h>
    @@ -51,12 +52,12 @@
     #include <uapi/linux/batadv_packet.h>
     #include <uapi/linux/batman_adv.h>
     
    +#include "bat_v_elp.h"
     #include "hard-interface.h"
     #include "log.h"
     #include "netlink.h"
     #include "originator.h"
     #include "send.h"
    -#include "bat_v_elp.h"
     
     /**
      * BATADV_TP_DEF_TEST_LENGTH - Default test length if not specified by the user

ecsv/pu: kerneldoc ./net/batman-adv/routing.c
---------------------------------------------

    ./net/batman-adv/routing.c:234: warning: Function parameter or member 'recv_if' not described in 'batadv_recv_my_icmp_packet'

ecsv/pu: kerneldoc ./net/batman-adv/tp_meter.c
----------------------------------------------

    ./net/batman-adv/tp_meter.c:288: warning: Function parameter or member 'hardif_neigh' not described in 'batadv_tp_caller_init_error'
    ./net/batman-adv/tp_meter.c:620: warning: Function parameter or member 'bat_priv' not described in 'batadv_tp_send_msg'
    ./net/batman-adv/tp_meter.c:620: warning: Excess function parameter 'src' description in 'batadv_tp_send_msg'
    ./net/batman-adv/tp_meter.c:620: warning: Excess function parameter 'orig_node' description in 'batadv_tp_send_msg'
    ./net/batman-adv/tp_meter.c:889: warning: Function parameter or member 'work' not described in 'batadv_tp_send'
    ./net/batman-adv/tp_meter.c:889: warning: Excess function parameter 'arg' description in 'batadv_tp_send'
    ./net/batman-adv/tp_meter.c:982: warning: Function parameter or member 'neigh' not described in 'batadv_tp_start'
    ./net/batman-adv/tp_meter.c:1194: warning: Function parameter or member 'tp_vars' not described in 'batadv_tp_send_ack'
    ./net/batman-adv/tp_meter.c:1194: warning: Excess function parameter 'dst' description in 'batadv_tp_send_ack'
    ./net/batman-adv/tp_meter.c:1389: warning: Function parameter or member 'recv_if' not described in 'batadv_tp_init_recv'
    ./net/batman-adv/tp_meter.c:1461: warning: Function parameter or member 'recv_if' not described in 'batadv_tp_recv_msg'
    ./net/batman-adv/tp_meter.c:1545: warning: Function parameter or member 'recv_if' not described in 'batadv_tp_meter_recv'
    ./net/batman-adv/tp_meter.c:1570: warning: No description found for return value of 'batadv_tp_meter_init'

ecsv/pu: kerneldoc ./net/batman-adv/types.h
-------------------------------------------

    ./net/batman-adv/types.h:1469: warning: Function parameter or member 'hardif_neigh' not described in 'batadv_tp_vars'

ecsv/pu: kerneldoc include/uapi/linux/batadv_packet.h
-----------------------------------------------------

    include/uapi/linux/batadv_packet.h:359: warning: Enum value 'BATADV_TP_MSG_LINK' not described in enum 'batadv_icmp_tp_subtype'

ecsv/pu: smatch linux-4.0 CONFIG_BATMAN_ADV_BLA=y CONFIG_BATMAN_ADV_DAT=n CONFIG_BATMAN_ADV_DEBUGFS=n CONFIG_BATMAN_ADV_DEBUG=n CONFIG_BATMAN_ADV_NC=n CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=y
---------------------------------------------------------------------------

    /home/build_test/build_env/tmp.CtNjyfTqvL/build/net/batman-adv/tp_meter.c:1086 batadv_tp_start() error:  locking inconsistency.  We assume 'spin_lock:&bat_priv->tp_list_lock' is both locked and unlocked at the start.
    /home/build_test/build_env/tmp.CtNjyfTqvL/build/net/batman-adv/tp_meter.c:1086 batadv_tp_start() error:  locking inconsistency.  We assume 'bottom_half:' is both locked and unlocked at the start.
    /home/build_test/build_env/tmp.CtNjyfTqvL/build/net/batman-adv/tp_meter.c:1086 batadv_tp_start() warn: inconsistent returns 'spin_lock:&bat_priv->tp_list_lock'.
      Locked on:   line 1011
      Unlocked on: line 1001
                   line 1086
    /home/build_test/build_env/tmp.CtNjyfTqvL/build/net/batman-adv/tp_meter.c:1086 batadv_tp_start() warn: inconsistent returns 'bottom_half:'.
      Locked on:   line 1011
      Unlocked on: line 1001
                   line 1086

ecsv/pu: smatch linux-4.9 CONFIG_BATMAN_ADV_BLA=n CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y CONFIG_BATMAN_ADV_NC=n CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_BATMAN_V=n
---------------------------------------------------------------------------

    /home/build_test/build_env/tmp.CtNjyfTqvL/build/net/batman-adv/tp_meter.c:1086 batadv_tp_start() error:  locking inconsistency.  We assume 'spin_lock:&bat_priv->tp_list_lock' is both locked and unlocked at the start.
    /home/build_test/build_env/tmp.CtNjyfTqvL/build/net/batman-adv/tp_meter.c:1086 batadv_tp_start() error:  locking inconsistency.  We assume 'bottom_half:' is both locked and unlocked at the start.

ecsv/pu: sparse linux-4.9 cfg: BLA=n DAT=y DEBUGFS=y DEBUG=y NC=n MCAST=y BATMAN_V=n
---------------------------------------------------------------------------

    /home/build_test/build_env/tmp.CtNjyfTqvL/build/net/batman-adv/tp_meter.c:996:31: warning: context imbalance in 'batadv_tp_start' - unexpected unlock


Statistics
==========

ecsv/pu
-------

Failed tests:                54
Started build tests:         30
Tested Linux versions:       21
Tested configs:              27

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-05-08 18:36 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-08 16:41 [B.A.T.M.A.N.] [RFC 0/6] B.A.T.M.A.N. V - fallback to tp meter estimation if throughput otherwise not available Marek Lindner
2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 1/6] batman-adv: tp_meter - prevent concurrent tp_meter sessions by using workqueue Marek Lindner
2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 2/6] batman-adv: tp_meter - don't check for existing session Marek Lindner
2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 3/6] batman-adv: tp_meter - allow up to 10 queued sessions Marek Lindner
2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 4/6] batman-adv: tp_meter - add caller distinction Marek Lindner
2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 5/6] batman-adv: to_meter - add option to perform one-hop test Marek Lindner
2018-05-08 16:41 ` [B.A.T.M.A.N.] [RFC 6/6] batman-adv: ELP - use tp meter to estimate the throughput if otherwise not available Marek Lindner
2018-05-08 18:36 ` [B.A.T.M.A.N.] [RFC 0/6] B.A.T.M.A.N. V - fallback to tp meter estimation if throughput " Sven Eckelmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).