[lttng-dev] [RFC PATCH] Fix: per-uid buffers should only be flushed once on stop

Mathieu Desnoyers mathieu.desnoyers at efficios.com
Fri Apr 26 15:18:38 EDT 2013


They were flushed once per application previously, causing workload with
many applications to trigger too many flush on stop, which in turn
caused buffer padding bloat.

* The pseudo-code for stop behavior on per-uid buffers was:

flush session's buffers
for each application:
  - stop tracing
  - wait quiescent
  - flush buffers
  - push metadata

Now doing, for per-uid buffers:

for each application:
  - stop tracing
  - wait quiescent
  - push metadata
flush session's buffers

* And for per-pid buffers:

Previously:

for each application:
  - stop tracing
  - wait quiescent
  - flush buffers
  - push metadata

Now:

for each application:
  - stop tracing
  - wait quiescent
  - push metadata
for each application:
  - flush buffers

Refs: #497

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
---
diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c
index 9bd622d..9bd4e69 100644
--- a/src/bin/lttng-sessiond/ust-app.c
+++ b/src/bin/lttng-sessiond/ust-app.c
@@ -3550,6 +3550,7 @@ int ust_app_create_event_glb(struct ltt_ust_session *usess,
 /*
  * Start tracing for a specific UST session and app.
  */
+static
 int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app)
 {
 	int ret = 0;
@@ -3642,12 +3643,11 @@ error_unlock:
 /*
  * Stop tracing for a specific UST session and app.
  */
+static
 int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app)
 {
 	int ret = 0;
-	struct lttng_ht_iter iter;
 	struct ust_app_session *ua_sess;
-	struct ust_app_channel *ua_chan;
 	struct ust_registry_session *registry;
 
 	DBG("Stopping tracing for ust app pid %d", app->pid);
@@ -3700,6 +3700,52 @@ int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app)
 
 	health_code_update();
 
+	registry = get_session_registry(ua_sess);
+	assert(registry);
+	/* Push metadata for application before freeing the application. */
+	(void) push_metadata(registry, ua_sess->consumer);
+
+	pthread_mutex_unlock(&ua_sess->lock);
+end_no_session:
+	rcu_read_unlock();
+	health_code_update();
+	return 0;
+
+error_rcu_unlock:
+	pthread_mutex_unlock(&ua_sess->lock);
+	rcu_read_unlock();
+	health_code_update();
+	return -1;
+}
+
+/*
+ * Flush buffers for a specific UST session and app.
+ */
+static
+int ust_app_flush_trace(struct ltt_ust_session *usess, struct ust_app *app)
+{
+	int ret = 0;
+	struct lttng_ht_iter iter;
+	struct ust_app_session *ua_sess;
+	struct ust_app_channel *ua_chan;
+
+	DBG("Flushing buffers for ust app pid %d", app->pid);
+
+	rcu_read_lock();
+
+	if (!app->compatible) {
+		goto end_no_session;
+	}
+
+	ua_sess = lookup_session_by_app(usess, app);
+	if (ua_sess == NULL) {
+		goto end_no_session;
+	}
+
+	pthread_mutex_lock(&ua_sess->lock);
+
+	health_code_update();
+
 	/* Flushing buffers */
 	cds_lfht_for_each_entry(ua_sess->channels->ht, &iter.iter, ua_chan,
 			node.node) {
@@ -3723,22 +3769,11 @@ int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app)
 
 	health_code_update();
 
-	registry = get_session_registry(ua_sess);
-	assert(registry);
-	/* Push metadata for application before freeing the application. */
-	(void) push_metadata(registry, ua_sess->consumer);
-
 	pthread_mutex_unlock(&ua_sess->lock);
 end_no_session:
 	rcu_read_unlock();
 	health_code_update();
 	return 0;
-
-error_rcu_unlock:
-	pthread_mutex_unlock(&ua_sess->lock);
-	rcu_read_unlock();
-	health_code_update();
-	return -1;
 }
 
 /*
@@ -3823,9 +3858,21 @@ int ust_app_stop_trace_all(struct ltt_ust_session *usess)
 
 	rcu_read_lock();
 
-	/* Flush all per UID buffers associated to that session. */
-	if (usess->buffer_type == LTTNG_BUFFER_PER_UID) {
+	cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+		ret = ust_app_stop_trace(usess, app);
+		if (ret < 0) {
+			/* Continue to next apps even on error */
+			continue;
+		}
+	}
+
+	/* Flush buffers */
+	switch (usess->buffer_type) {
+	case LTTNG_BUFFER_PER_UID:
+	{
 		struct buffer_reg_uid *reg;
+
+		/* Flush all per UID buffers associated to that session. */
 		cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) {
 			struct buffer_reg_channel *reg_chan;
 			struct consumer_socket *socket;
@@ -3848,14 +3895,20 @@ int ust_app_stop_trace_all(struct ltt_ust_session *usess)
 				(void) consumer_flush_channel(socket, reg_chan->consumer_key);
 			}
 		}
+		break;
 	}
-
-	cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
-		ret = ust_app_stop_trace(usess, app);
-		if (ret < 0) {
-			/* Continue to next apps even on error */
-			continue;
+	case LTTNG_BUFFER_PER_PID:
+		cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+			ret = ust_app_flush_trace(usess, app);
+			if (ret < 0) {
+				/* Continue to next apps even on error */
+				continue;
+			}
 		}
+		break;
+	default:
+		assert(0);
+		break;
 	}
 
 	rcu_read_unlock();
diff --git a/src/bin/lttng-sessiond/ust-app.h b/src/bin/lttng-sessiond/ust-app.h
index e0aa17a..255a75c 100644
--- a/src/bin/lttng-sessiond/ust-app.h
+++ b/src/bin/lttng-sessiond/ust-app.h
@@ -257,8 +257,6 @@ int ust_app_register_done(int sock)
 int ust_app_version(struct ust_app *app);
 void ust_app_unregister(int sock);
 unsigned long ust_app_list_count(void);
-int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app);
-int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app);
 int ust_app_start_trace_all(struct ltt_ust_session *usess);
 int ust_app_stop_trace_all(struct ltt_ust_session *usess);
 int ust_app_destroy_trace_all(struct ltt_ust_session *usess);

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com



More information about the lttng-dev mailing list