[dpdk-dev] [PATCH 1/2] examples/ip_pipeline: CPU utilization measurement and

Fan Zhang roy.fan.zhang at intel.com
Wed Jan 27 18:36:58 CET 2016


This patch adds CPU utilization measurement and rate computation to
packet framework. The measurement is done by measuring the cycles
spent while a thread pulls zero packet from RX queue. These cycles are
treated as idle cycles (or headroom). The idle thread rate is updated once
per second.

Signed-off-by: Fan Zhang <roy.fan.zhang at intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu at intel.com>
---
 examples/ip_pipeline/app.h    |  7 ++++
 examples/ip_pipeline/init.c   |  5 +++
 examples/ip_pipeline/thread.c | 81 +++++++++++++++++++++++++++++++++++++++++--
 examples/ip_pipeline/thread.h | 13 +++++++
 4 files changed, 104 insertions(+), 2 deletions(-)

diff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h
index 6510d6d..2b134f1 100644
--- a/examples/ip_pipeline/app.h
+++ b/examples/ip_pipeline/app.h
@@ -263,6 +263,11 @@ struct app_thread_data {
 
 	struct rte_ring *msgq_in;
 	struct rte_ring *msgq_out;
+
+	uint64_t time_updated;
+	uint64_t hz;
+	uint64_t headroom;
+	double headroom_rate;
 };
 
 struct app_eal_params {
@@ -421,6 +426,8 @@ struct app_eal_params {
 #define APP_MAX_CMDS                             64
 #endif
 
+#define APP_THREAD_HEADROOM_STATS_COLLECT
+
 struct app_params {
 	/* Config */
 	char app_name[APP_APPNAME_SIZE];
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index 186ca03..f4c1239 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -1379,6 +1379,11 @@ app_init_threads(struct app_params *app)
 		t->timer_period = (rte_get_tsc_hz() * APP_THREAD_TIMER_PERIOD) / 1000;
 		t->thread_req_deadline = time + t->timer_period;
 
+		t->headroom = 0;
+		t->headroom_rate = 0.0;
+		t->time_updated = time;
+		t->hz = rte_get_tsc_hz();
+
 		t->msgq_in = app_thread_msgq_in_get(app,
 				params->socket_id,
 				params->core_id,
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index 78f1bd8..0e37a26 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -39,6 +39,36 @@
 #include "app.h"
 #include "thread.h"
 
+#ifdef APP_THREAD_HEADROOM_STATS_COLLECT
+
+static void
+thread_headroom_measure_start(uint64_t *t0)
+{
+	*t0 = rte_rdtsc();
+}
+
+static void
+thread_headroom_measure_stop(int n_pkts,
+		uint64_t t0, struct app_thread_data *t)
+{
+	if (n_pkts == 0) {
+		uint64_t t1 = rte_rdtsc();
+
+		t->headroom += t1 - t0;
+	}
+}
+
+#else
+
+static void
+thread_headroom_measure_start(uint64_t *t0) {}
+
+static void
+thread_headroom_measure_stop(int n_pkts,
+		uint64_t t0, struct app_thread_data *t) {}
+
+#endif
+
 static inline void *
 thread_msg_recv(struct rte_ring *r)
 {
@@ -140,6 +170,17 @@ thread_pipeline_disable(struct app_thread_data *t,
 }
 
 static int
+thread_headroom(struct app_thread_data *t,
+		void *req)
+{
+	struct thread_show_headroom_msg_rsp *rsp = req;
+
+	rsp->headroom = t->headroom_rate;
+
+	return 0;
+}
+
+static int
 thread_msg_req_handle(struct app_thread_data *t)
 {
 	void *msg_ptr;
@@ -165,6 +206,14 @@ thread_msg_req_handle(struct app_thread_data *t)
 			thread_msg_send(t->msgq_out, rsp);
 			break;
 		}
+
+		case THREAD_MSG_REQ_HEADROOM: {
+			rsp->status = thread_headroom(t,
+				(struct thread_show_headroom_msg_req *) req);
+			thread_msg_send(t->msgq_out, rsp);
+			break;
+		}
+
 		default:
 			break;
 		}
@@ -187,15 +236,23 @@ app_thread(void *arg)
 		for (j = 0; j < n_regular; j++) {
 			struct app_thread_pipeline_data *data = &t->regular[j];
 			struct pipeline *p = data->be;
+			uint64_t t0;
+			int n_pkts;
 
-			rte_pipeline_run(p->p);
+			thread_headroom_measure_start(&t0);
+			n_pkts = rte_pipeline_run(p->p);
+			thread_headroom_measure_stop(n_pkts, t0, t);
 		}
 
 		/* Run custom pipelines */
 		for (j = 0; j < n_custom; j++) {
 			struct app_thread_pipeline_data *data = &t->custom[j];
+			uint64_t t0;
+			int n_pkts;
 
-			data->f_run(data->be);
+			thread_headroom_measure_start(&t0);
+			n_pkts = data->f_run(data->be);
+			thread_headroom_measure_stop(n_pkts, t0, t);
 		}
 
 		/* Timer */
@@ -252,6 +309,26 @@ app_thread(void *arg)
 					t_deadline = deadline;
 			}
 
+			/* Timer for thread headroom ratio update */
+			{
+				uint64_t time_current = rte_rdtsc_precise();
+				uint64_t time_diff = time_current -
+						t->time_updated;
+				uint64_t headroom = t->headroom;
+
+				if (time_diff > t->hz) {
+					t->headroom = 0;
+					t->time_updated = time_current;
+
+					if (headroom == 0)
+						t->headroom_rate = 0.0;
+					else
+						t->headroom_rate =
+							(double)headroom /
+							time_diff;
+				}
+			}
+
 			t->deadline = t_deadline;
 		}
 	}
diff --git a/examples/ip_pipeline/thread.h b/examples/ip_pipeline/thread.h
index dc877c0..70dd98a 100644
--- a/examples/ip_pipeline/thread.h
+++ b/examples/ip_pipeline/thread.h
@@ -40,6 +40,7 @@
 enum thread_msg_req_type {
 	THREAD_MSG_REQ_PIPELINE_ENABLE = 0,
 	THREAD_MSG_REQ_PIPELINE_DISABLE,
+	THREAD_MSG_REQ_HEADROOM,
 	THREAD_MSG_REQS
 };
 
@@ -81,4 +82,16 @@ struct thread_pipeline_disable_msg_rsp {
 	int status;
 };
 
+/*
+ * THREAD SHOW HEADROOM
+ */
+struct thread_show_headroom_msg_req {
+	enum thread_msg_req_type type;
+};
+struct thread_show_headroom_msg_rsp {
+	int status;
+
+	double headroom;
+};
+
 #endif /* THREAD_H_ */
-- 
2.5.0



More information about the dev mailing list