DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/2] Add CPU utilization to packet framework
@ 2016-01-27 17:36 Fan Zhang
  2016-01-27 17:36 ` [dpdk-dev] [PATCH 1/2] examples/ip_pipeline: CPU utilization measurement and Fan Zhang
  2016-01-27 17:36 ` [dpdk-dev] [PATCH 2/2] examples/ip_pipeline: add CLI command to display CPU Fan Zhang
  0 siblings, 2 replies; 3+ messages in thread
From: Fan Zhang @ 2016-01-27 17:36 UTC (permalink / raw)
  To: dev

This patchset adds CPU utilization rate computation and CLI command
support to packet framework. The thread idle rate is updated once per
second. User can use thread CLI command to display it.

Fan Zhang (2):
  examples/ip_pipeline: CPU utilization measurement and rate computation
  examples/ip_pipeline: add CLI command to display CPU utilization rate

 examples/ip_pipeline/app.h       |   7 +++
 examples/ip_pipeline/init.c      |   5 ++
 examples/ip_pipeline/thread.c    |  81 +++++++++++++++++++++++++++-
 examples/ip_pipeline/thread.h    |  13 +++++
 examples/ip_pipeline/thread_fe.c | 114 +++++++++++++++++++++++++++++++++++++++
 examples/ip_pipeline/thread_fe.h |   6 +++
 6 files changed, 224 insertions(+), 2 deletions(-)

-- 
2.5.0

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

* [dpdk-dev] [PATCH 1/2] examples/ip_pipeline: CPU utilization measurement and
  2016-01-27 17:36 [dpdk-dev] [PATCH 0/2] Add CPU utilization to packet framework Fan Zhang
@ 2016-01-27 17:36 ` Fan Zhang
  2016-01-27 17:36 ` [dpdk-dev] [PATCH 2/2] examples/ip_pipeline: add CLI command to display CPU Fan Zhang
  1 sibling, 0 replies; 3+ messages in thread
From: Fan Zhang @ 2016-01-27 17:36 UTC (permalink / raw)
  To: dev

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@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@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

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

* [dpdk-dev] [PATCH 2/2] examples/ip_pipeline: add CLI command to display CPU
  2016-01-27 17:36 [dpdk-dev] [PATCH 0/2] Add CPU utilization to packet framework Fan Zhang
  2016-01-27 17:36 ` [dpdk-dev] [PATCH 1/2] examples/ip_pipeline: CPU utilization measurement and Fan Zhang
@ 2016-01-27 17:36 ` Fan Zhang
  1 sibling, 0 replies; 3+ messages in thread
From: Fan Zhang @ 2016-01-27 17:36 UTC (permalink / raw)
  To: dev

This patch adds idle cycle (or headroom) rate display CLI command to
packet framework. The CLI command format is shown as following:

t <thread_id> headroom

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
 examples/ip_pipeline/thread_fe.c | 114 +++++++++++++++++++++++++++++++++++++++
 examples/ip_pipeline/thread_fe.h |   6 +++
 2 files changed, 120 insertions(+)

diff --git a/examples/ip_pipeline/thread_fe.c b/examples/ip_pipeline/thread_fe.c
index 95f0107..e939237 100644
--- a/examples/ip_pipeline/thread_fe.c
+++ b/examples/ip_pipeline/thread_fe.c
@@ -170,6 +170,54 @@ app_pipeline_disable(struct app_params *app,
 	return 0;
 }
 
+int
+app_thread_headroom(struct app_params *app,
+		uint32_t socket_id,
+		uint32_t core_id,
+		uint32_t hyper_th_id)
+{
+	struct thread_show_headroom_msg_req *req;
+	struct thread_show_headroom_msg_rsp *rsp;
+	int thread_id;
+	int status;
+
+	if (app == NULL)
+		return -1;
+
+	thread_id = cpu_core_map_get_lcore_id(app->core_map,
+			socket_id,
+			core_id,
+			hyper_th_id);
+
+	if ((thread_id < 0) ||
+		((app->core_mask & (1LLU << thread_id)) == 0))
+		return -1;
+
+	req = app_msg_alloc(app);
+	if (req == NULL)
+		return -1;
+
+	req->type = THREAD_MSG_REQ_HEADROOM;
+
+	rsp = thread_msg_send_recv(app,
+		socket_id, core_id, hyper_th_id, req, MSG_TIMEOUT_DEFAULT);
+
+	if (rsp == NULL)
+		return -1;
+
+	status = rsp->status;
+
+	if (status == 0) {
+		printf("Core %u: idle CPU rate %f%%\n",
+				core_id, rsp->headroom * 100);
+	} else {
+		app_msg_free(app, rsp);
+		return -1;
+	}
+
+	return 0;
+}
+
 /*
  * pipeline enable
  */
@@ -318,9 +366,75 @@ cmdline_parse_inst_t cmd_pipeline_disable = {
 	},
 };
 
+
+/*
+ * thread headroom
+ */
+
+struct cmd_thread_headroom_result {
+	cmdline_fixed_string_t t_string;
+	cmdline_fixed_string_t t_id_string;
+	cmdline_fixed_string_t headroom_string;
+};
+
+static void
+cmd_thread_headroom_parsed(
+	void *parsed_result,
+	__rte_unused struct cmdline *cl,
+	 void *data)
+{
+	struct cmd_thread_headroom_result *params = parsed_result;
+	struct app_params *app = data;
+	int status;
+	uint32_t core_id, socket_id, hyper_th_id;
+
+	if (parse_pipeline_core(&socket_id,
+			&core_id,
+			&hyper_th_id,
+			params->t_id_string) != 0) {
+		printf("Command failed\n");
+		return;
+	}
+
+	status = app_thread_headroom(app,
+			socket_id,
+			core_id,
+			hyper_th_id);
+
+	if (status != 0)
+		printf("Command failed\n");
+}
+
+cmdline_parse_token_string_t cmd_thread_headroom_t_string =
+	TOKEN_STRING_INITIALIZER(struct cmd_thread_headroom_result,
+		t_string, "t");
+
+cmdline_parse_token_string_t cmd_thread_headroom_t_id_string =
+	TOKEN_STRING_INITIALIZER(struct cmd_thread_headroom_result,
+		t_id_string,
+		NULL);
+
+cmdline_parse_token_string_t cmd_thread_headroom_headroom_string =
+	TOKEN_STRING_INITIALIZER(struct cmd_thread_headroom_result,
+		headroom_string, "headroom");
+
+cmdline_parse_inst_t cmd_thread_headroom = {
+	.f = cmd_thread_headroom_parsed,
+	.data = NULL,
+	.help_str = "Display thread headroom",
+	.tokens = {
+		(void *)&cmd_thread_headroom_t_string,
+		(void *)&cmd_thread_headroom_t_id_string,
+		(void *)&cmd_thread_headroom_headroom_string,
+		NULL,
+	},
+};
+
+
 static cmdline_parse_ctx_t thread_cmds[] = {
 	(cmdline_parse_inst_t *) &cmd_pipeline_enable,
 	(cmdline_parse_inst_t *) &cmd_pipeline_disable,
+	(cmdline_parse_inst_t *) &cmd_thread_headroom,
 	NULL,
 };
 
diff --git a/examples/ip_pipeline/thread_fe.h b/examples/ip_pipeline/thread_fe.h
index 52352c1..2fd4ee8 100644
--- a/examples/ip_pipeline/thread_fe.h
+++ b/examples/ip_pipeline/thread_fe.h
@@ -92,4 +92,10 @@ app_pipeline_disable(struct app_params *app,
 		uint32_t hyper_th_id,
 		uint32_t pipeline_id);
 
+int
+app_thread_headroom(struct app_params *app,
+		uint32_t core_id,
+		uint32_t socket_id,
+		uint32_t hyper_th_id);
+
 #endif /* THREAD_FE_H_ */
-- 
2.5.0

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

end of thread, other threads:[~2016-01-27 17:37 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-27 17:36 [dpdk-dev] [PATCH 0/2] Add CPU utilization to packet framework Fan Zhang
2016-01-27 17:36 ` [dpdk-dev] [PATCH 1/2] examples/ip_pipeline: CPU utilization measurement and Fan Zhang
2016-01-27 17:36 ` [dpdk-dev] [PATCH 2/2] examples/ip_pipeline: add CLI command to display CPU Fan Zhang

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).