[lttng-dev] [RFC PATCH lttng-modules] Use call_rcu_sched for pid untrack

Mathieu Desnoyers mathieu.desnoyers at efficios.com
Thu Sep 28 18:12:00 UTC 2017


Automatically following PIDs require untrack to complete faster than the
slow one-synchronize-sched-per-untrack scheme.

Use call_rcu_sched() instead.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
CC: dong.zhou.08 at gmail.com
---
 lttng-events.c      |  4 ++--
 lttng-events.h      |  4 ++++
 lttng-tracker-pid.c | 27 +++++++++++++++++----------
 3 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/lttng-events.c b/lttng-events.c
index 21c41133..5c80c6b4 100644
--- a/lttng-events.c
+++ b/lttng-events.c
@@ -920,8 +920,8 @@ int lttng_session_track_pid(struct lttng_session *session, int pid)
 
 			lpf = session->pid_tracker;
 			rcu_assign_pointer(session->pid_tracker, NULL);
-			synchronize_trace();
-			lttng_pid_tracker_destroy(lpf);
+			call_rcu_sched(&lpf->rcu,
+					lttng_pid_tracker_destroy_rcu);
 		}
 		ret = 0;
 	} else {
diff --git a/lttng-events.h b/lttng-events.h
index 17dd8d3a..ddb4be7b 100644
--- a/lttng-events.h
+++ b/lttng-events.h
@@ -486,10 +486,12 @@ DECLARE_PER_CPU(struct lttng_dynamic_len_stack, lttng_dynamic_len_stack);
 
 struct lttng_pid_tracker {
 	struct hlist_head pid_hash[LTTNG_PID_TABLE_SIZE];
+	struct rcu_head rcu;
 };
 
 struct lttng_pid_hash_node {
 	struct hlist_node hlist;
+	struct rcu_head rcu;
 	int pid;
 };
 
@@ -610,6 +612,8 @@ int lttng_session_untrack_pid(struct lttng_session *session, int pid);
 
 int lttng_session_list_tracker_pids(struct lttng_session *session);
 
+void lttng_pid_tracker_destroy_rcu(struct rcu_head *rcu);
+
 void lttng_clock_ref(void);
 void lttng_clock_unref(void);
 
diff --git a/lttng-tracker-pid.c b/lttng-tracker-pid.c
index d74d8c92..bf194e79 100644
--- a/lttng-tracker-pid.c
+++ b/lttng-tracker-pid.c
@@ -91,19 +91,18 @@ int lttng_pid_tracker_add(struct lttng_pid_tracker *lpf, int pid)
 }
 
 static
+void free_pid_hash_node_rcu(struct rcu_head *rcu)
+{
+	struct lttng_pid_hash_node *e =
+			container_of(rcu, struct lttng_pid_hash_node, rcu);
+	kfree(e);
+}
+
+static
 void pid_tracker_del_node_rcu(struct lttng_pid_hash_node *e)
 {
 	hlist_del_rcu(&e->hlist);
-	/*
-	 * We choose to use a heavyweight synchronize on removal here,
-	 * since removal of a PID from the tracker mask is a rare
-	 * operation, and we don't want to use more cache lines than
-	 * what we really need when doing the PID lookups, so we don't
-	 * want to afford adding a rcu_head field to those pid hash
-	 * node.
-	 */
-	synchronize_trace();
-	kfree(e);
+	call_rcu_sched(&e->rcu, free_pid_hash_node_rcu);
 }
 
 /*
@@ -156,3 +155,11 @@ void lttng_pid_tracker_destroy(struct lttng_pid_tracker *lpf)
 	}
 	kfree(lpf);
 }
+
+void lttng_pid_tracker_destroy_rcu(struct rcu_head *rcu)
+{
+	struct lttng_pid_tracker *lpf =
+		container_of(rcu, struct lttng_pid_tracker, rcu);
+
+	lttng_pid_tracker_destroy(lpf);
+}
-- 
2.11.0



More information about the lttng-dev mailing list