From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 62497B3D9 for ; Wed, 27 Jan 2016 18:37:04 +0100 (CET) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga104.fm.intel.com with ESMTP; 27 Jan 2016 09:37:03 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,355,1449561600"; d="scan'208";a="890372824" Received: from sie-lab-212-033.ir.intel.com (HELO silpixa00383881.ir.intel.com) ([10.237.212.33]) by fmsmga001.fm.intel.com with ESMTP; 27 Jan 2016 09:37:02 -0800 From: Fan Zhang To: dev@dpdk.org Date: Wed, 27 Jan 2016 17:36:58 +0000 Message-Id: <1453916219-26656-2-git-send-email-roy.fan.zhang@intel.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1453916219-26656-1-git-send-email-roy.fan.zhang@intel.com> References: <1453916219-26656-1-git-send-email-roy.fan.zhang@intel.com> Subject: [dpdk-dev] [PATCH 1/2] examples/ip_pipeline: CPU utilization measurement and 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, 27 Jan 2016 17:37:04 -0000 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 Acked-by: Cristian Dumitrescu --- 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