From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id EFF4A2BB4 for ; Wed, 9 Mar 2016 07:50:09 +0100 (CET) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP; 08 Mar 2016 22:50:08 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,310,1455004800"; d="scan'208";a="666283695" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by FMSMGA003.fm.intel.com with ESMTP; 08 Mar 2016 22:50:08 -0800 Received: from fmsmsx153.amr.corp.intel.com (10.18.125.6) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.248.2; Tue, 8 Mar 2016 22:50:08 -0800 Received: from shsmsx152.ccr.corp.intel.com (10.239.6.52) by FMSMSX153.amr.corp.intel.com (10.18.125.6) with Microsoft SMTP Server (TLS) id 14.3.248.2; Tue, 8 Mar 2016 22:50:07 -0800 Received: from shsmsx101.ccr.corp.intel.com ([169.254.1.136]) by SHSMSX152.ccr.corp.intel.com ([169.254.6.42]) with mapi id 14.03.0248.002; Wed, 9 Mar 2016 14:50:06 +0800 From: "Wan, Qun" To: "Zhang, Roy Fan" , "dev@dpdk.org" Thread-Topic: [dpdk-dev] [PATCH v2] examples/ip_pipeline: CPU utilization measurement and display Thread-Index: AQHRbXp8q5CItPQzg0KG5YhwSI95OJ9Qxpyw Date: Wed, 9 Mar 2016 06:50:05 +0000 Message-ID: <17AD763A69C1A24CA48C89AF567166204BAA5959@SHSMSX101.ccr.corp.intel.com> References: <1456150024-31304-1-git-send-email-roy.fan.zhang@intel.com> In-Reply-To: <1456150024-31304-1-git-send-email-roy.fan.zhang@intel.com> Accept-Language: en-IE, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH v2] examples/ip_pipeline: CPU utilization measurement and display X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 Mar 2016 06:50:10 -0000 Tested-ny: Qun Wan pipeline> t s1c1 headroom 57.085% -----Original Message----- From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Fan Zhang Sent: Monday, February 22, 2016 10:07 PM To: dev@dpdk.org Subject: [dpdk-dev] [PATCH v2] examples/ip_pipeline: CPU utilization measur= ement and display This patch adds CPU utilization measurement and idle cycle 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 a= s idle cycles (or headroom). A CLI command is added to display idle cycle r= ate of specific thread. The CLI command format is shown as following: t headroom Signed-off-by: Fan Zhang Acked-by: Cristian Dumitrescu --- examples/ip_pipeline/app.h | 8 +++ examples/ip_pipeline/init.c | 8 ++- examples/ip_pipeline/thread.c | 66 ++++++++++++++++++++++- examples/ip_pipeline/thread.h | 14 +++++ examples/ip_pipeline/thread_fe.c | 113 +++++++++++++++++++++++++++++++++++= ++++ examples/ip_pipeline/thread_fe.h | 6 +++ 6 files changed, 211 insertions(+), 4 deletions(-) diff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h index = 6510d6d..2c91256 100644 --- a/examples/ip_pipeline/app.h +++ b/examples/ip_pipeline/app.h @@ -263,6 +263,10 @@ struct app_thread_data { =20 struct rte_ring *msgq_in; struct rte_ring *msgq_out; + + uint64_t headroom_time; + uint64_t headroom_cycles; + double headroom_ratio; }; =20 struct app_eal_params { @@ -421,6 +425,10 @@ struct app_eal_params { #define APP_MAX_CMDS 64 #endif =20 +#ifndef APP_THREAD_HEADROOM_STATS_COLLECT +#define APP_THREAD_HEADROOM_STATS_COLLECT 1 +#endif + struct app_params { /* Config */ char app_name[APP_APPNAME_SIZE]; diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c inde= x 186ca03..af33e8f 100644 --- a/examples/ip_pipeline/init.c +++ b/examples/ip_pipeline/init.c @@ -1343,8 +1343,8 @@ app_init_pipelines(struct app_params *app) =20 data->ptype =3D ptype; =20 - data->timer_period =3D (rte_get_tsc_hz() * params->timer_period) - / 1000; + data->timer_period =3D (rte_get_tsc_hz() * + params->timer_period) / 100; } } =20 @@ -1379,6 +1379,10 @@ app_init_threads(struct app_params *app) t->timer_period =3D (rte_get_tsc_hz() * APP_THREAD_TIMER_PERIOD) / 1000; t->thread_req_deadline =3D time + t->timer_period; =20 + t->headroom_cycles =3D 0; + t->headroom_time =3D rte_get_tsc_cycles(); + t->headroom_ratio =3D 0.0; + t->msgq_in =3D 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..a0f1f12 100644 --- a/examples/ip_pipeline/thread.c +++ b/examples/ip_pipeline/thread.c @@ -39,6 +39,43 @@ #include "app.h" #include "thread.h" =20 +#if APP_THREAD_HEADROOM_STATS_COLLECT + +#define PIPELINE_RUN_REGULAR(thread, pipeline) \ +do { \ + uint64_t t0 =3D rte_rdtsc_precise(); \ + int n_pkts =3D rte_pipeline_run(pipeline->p); \ + \ + if (n_pkts =3D=3D 0) { \ + uint64_t t1 =3D rte_rdtsc_precise(); \ + \ + thread->headroom_cycles +=3D t1 - t0; \ + } \ +} while (0) + + +#define PIPELINE_RUN_CUSTOM(thread, data) \ +do { \ + uint64_t t0 =3D rte_rdtsc_precise(); \ + int n_pkts =3D data->f_run(data->be); \ + \ + if (n_pkts =3D=3D 0) { \ + uint64_t t1 =3D rte_rdtsc_precise(); \ + \ + thread->headroom_cycles +=3D t1 - t0; \ + } \ +} while (0) + +#else + +#define PIPELINE_RUN_REGULAR(thread, pipeline) \ + rte_pipeline_run(pipeline->p) + +#define PIPELINE_RUN_CUSTOM(thread, data) \ + data->f_run(data->be) + +#endif + static inline void * thread_msg_recv(struct rte_ring *r) { @@ -165,6 +202,17 @@ thread_msg_req_handle(struct app_thread_data *t) thread_msg_send(t->msgq_out, rsp); break; } + + case THREAD_MSG_REQ_HEADROOM_READ: { + struct thread_headroom_read_msg_rsp *rsp =3D + (struct thread_headroom_read_msg_rsp *) + req; + + rsp->headroom_ratio =3D t->headroom_ratio; + rsp->status =3D 0; + thread_msg_send(t->msgq_out, rsp); + break; + } default: break; } @@ -172,6 +220,18 @@ thread_msg_req_handle(struct app_thread_data *t) return 0; } =20 +static void +thread_headroom_update(struct app_thread_data *t, uint64_t time) { + uint64_t time_diff =3D time - t->headroom_time; + + t->headroom_ratio =3D + ((double) t->headroom_cycles) / ((double) time_diff); + + t->headroom_cycles =3D 0; + t->headroom_time =3D rte_rdtsc_precise(); } + int app_thread(void *arg) { @@ -188,14 +248,14 @@ app_thread(void *arg) struct app_thread_pipeline_data *data =3D &t->regular[j]; struct pipeline *p =3D data->be; =20 - rte_pipeline_run(p->p); + PIPELINE_RUN_REGULAR(t, p); } =20 /* Run custom pipelines */ for (j =3D 0; j < n_custom; j++) { struct app_thread_pipeline_data *data =3D &t->custom[j]; =20 - data->f_run(data->be); + PIPELINE_RUN_CUSTOM(t, data); } =20 /* Timer */ @@ -244,6 +304,7 @@ app_thread(void *arg) =20 if (deadline <=3D time) { thread_msg_req_handle(t); + thread_headroom_update(t, time); deadline =3D time + t->timer_period; t->thread_req_deadline =3D deadline; } @@ -252,6 +313,7 @@ app_thread(void *arg) t_deadline =3D deadline; } =20 + t->deadline =3D t_deadline; } } diff --git a/examples/ip_pipeline/thread.h b/examples/ip_pipeline/thread.h = index dc877c0..e52b22e 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 =3D 0, THREAD_MSG_REQ_PIPELINE_DISABLE, + THREAD_MSG_REQ_HEADROOM_READ, THREAD_MSG_REQS }; =20 @@ -81,4 +82,17 @@ struct thread_pipeline_disable_msg_rsp { int status; }; =20 +/* + * THREAD HEADROOM + */ +struct thread_headroom_read_msg_req { + enum thread_msg_req_type type; +}; + +struct thread_headroom_read_msg_rsp { + int status; + + double headroom_ratio; +}; + #endif /* THREAD_H_ */ diff --git a/examples/ip_pipeline/thread_fe.c b/examples/ip_pipeline/thread= _fe.c index 95f0107..4a435f7 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; } =20 +int +app_thread_headroom(struct app_params *app, + uint32_t socket_id, + uint32_t core_id, + uint32_t hyper_th_id) +{ + struct thread_headroom_read_msg_req *req; + struct thread_headroom_read_msg_rsp *rsp; + int thread_id; + int status; + + if (app =3D=3D NULL) + return -1; + + thread_id =3D 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)) =3D=3D 0)) + return -1; + + req =3D app_msg_alloc(app); + if (req =3D=3D NULL) + return -1; + + req->type =3D THREAD_MSG_REQ_HEADROOM_READ; + + rsp =3D thread_msg_send_recv(app, + socket_id, core_id, hyper_th_id, req, MSG_TIMEOUT_DEFAULT); + + if (rsp =3D=3D NULL) + return -1; + + status =3D rsp->status; + + if (status !=3D 0) + return -1; + + printf("%.3f%%\n", rsp->headroom_ratio * 100); + + + app_msg_free(app, rsp); + + return 0; +} + /* * pipeline enable */ @@ -318,9 +366,74 @@ cmdline_parse_inst_t cmd_pipeline_disable =3D { }, }; =20 + +/* + * 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 =3D parsed_result; + struct app_params *app =3D 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) !=3D 0) { + printf("Command failed\n"); + return; + } + + status =3D app_thread_headroom(app, + socket_id, + core_id, + hyper_th_id); + + if (status !=3D 0) + printf("Command failed\n"); +} + +cmdline_parse_token_string_t cmd_thread_headroom_t_string =3D + TOKEN_STRING_INITIALIZER(struct cmd_thread_headroom_result, + t_string, "t"); + +cmdline_parse_token_string_t cmd_thread_headroom_t_id_string =3D + TOKEN_STRING_INITIALIZER(struct cmd_thread_headroom_result, + t_id_string, NULL); + +cmdline_parse_token_string_t cmd_thread_headroom_headroom_string =3D + TOKEN_STRING_INITIALIZER(struct cmd_thread_headroom_result, + headroom_string, "headroom"); + +cmdline_parse_inst_t cmd_thread_headroom =3D { + .f =3D cmd_thread_headroom_parsed, + .data =3D NULL, + .help_str =3D "Display thread headroom", + .tokens =3D { + (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[] =3D { (cmdline_parse_inst_t *) &cmd_pipeline_enable, (cmdline_parse_inst_t *) &cmd_pipeline_disable, + (cmdline_parse_inst_t *) &cmd_thread_headroom, NULL, }; =20 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); =20 +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