From patchwork Wed Oct 3 12:07:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 10624739 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 97D0013BB for ; Wed, 3 Oct 2018 12:07:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 893AF28942 for ; Wed, 3 Oct 2018 12:07:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7DC1F2896A; Wed, 3 Oct 2018 12:07:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id DE66C28942 for ; Wed, 3 Oct 2018 12:07:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0B63F6E47D; Wed, 3 Oct 2018 12:07:36 +0000 (UTC) X-Original-To: Intel-gfx@lists.freedesktop.org Delivered-To: Intel-gfx@lists.freedesktop.org Received: from mail-wr1-x442.google.com (mail-wr1-x442.google.com [IPv6:2a00:1450:4864:20::442]) by gabe.freedesktop.org (Postfix) with ESMTPS id ACC516E451 for ; Wed, 3 Oct 2018 12:07:30 +0000 (UTC) Received: by mail-wr1-x442.google.com with SMTP id z4-v6so5845843wrb.1 for ; Wed, 03 Oct 2018 05:07:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=T3nZ41zHoAWtmAdmKIADLMlZZDld4r4d4eDYA6qRIkc=; b=qvordAo1m4SbtJHYg6O9Y+ahiXxNKItxHjeUWd7eAD9DYlF4ZLgMtFZzwmFbd2QRXd Jvk89Nd2g34EA01erEh3iLmmiVwHMqAT/gTI1Rbju7Q7szunkVdeVE2z6GHZyFXk1OVh c/9IkW5cyhdkcgotU51HiIjl8BC/SyoePQC9aKkhGjYip/5+ZgfvDqTKcIqA7px0xxYf W6oJzqAej52Rkek86mnRo7cCM10yAoVip9vS9pJAz7E3zarL23RVbnKJI6Dppg5ilA9y VMEmeaeypmrIxjD8rO4E1tKnWAiWhdwnGYQAjXTGHMeJWNu6ZNBgJ58iOrEc/ZLb0kTp aLmA== X-Gm-Message-State: ABuFfohPHsytv5sFacK8/dJPGL7jl1+scJ7T9OeK6c9a7V10bOSTbpBp EKpwfmJJhHPWGrraMosf/UQ0CA9Kq6o= X-Google-Smtp-Source: ACcGV62tvZ/ETETzWvZQ3DaKDRqo7wqCwOQY9i+GeCPepXY2d9HzJk6eh1/kYomlxSIqgW5Hgyd/lA== X-Received: by 2002:adf:e348:: with SMTP id n8-v6mr1029019wrj.158.1538568449099; Wed, 03 Oct 2018 05:07:29 -0700 (PDT) Received: from localhost.localdomain ([95.144.165.37]) by smtp.gmail.com with ESMTPSA id u191-v6sm1627707wmd.31.2018.10.03.05.07.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 03 Oct 2018 05:07:28 -0700 (PDT) From: Tvrtko Ursulin X-Google-Original-From: Tvrtko Ursulin To: igt-dev@lists.freedesktop.org Date: Wed, 3 Oct 2018 13:07:17 +0100 Message-Id: <20181003120718.6898-6-tvrtko.ursulin@linux.intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181003120718.6898-1-tvrtko.ursulin@linux.intel.com> References: <20181003120718.6898-1-tvrtko.ursulin@linux.intel.com> Subject: [Intel-gfx] [RFC i-g-t 5/6] intel-gpu-top: Add queue depths and load average X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Intel-gfx@lists.freedesktop.org MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP From: Tvrtko Ursulin With the driver now exporting various request queue depths for each engine, we can display this information here. Both as raw counters, and by adding a load average like metrics composed from number of runnable and running requests in a given time period. 1s, 30s and 5m periods are used for load average. Signed-off-by: Tvrtko Ursulin --- tools/Makefile.am | 2 +- tools/intel_gpu_top.c | 122 +++++++++++++++++++++++++++++++++++++----- tools/meson.build | 2 +- 3 files changed, 110 insertions(+), 16 deletions(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index e7de4d90241c..e03842afce8d 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -29,7 +29,7 @@ intel_aubdump_la_LDFLAGS = -module -avoid-version -no-undefined intel_aubdump_la_SOURCES = aubdump.c intel_aubdump_la_LIBADD = $(top_builddir)/lib/libintel_tools.la -ldl -intel_gpu_top_LDADD = $(top_builddir)/lib/libigt_perf.la +intel_gpu_top_LDADD = $(top_builddir)/lib/libigt_perf.la -lm bin_SCRIPTS = intel_aubdump CLEANFILES = $(bin_SCRIPTS) diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c index b923c3cfbe97..8990ef17b771 100644 --- a/tools/intel_gpu_top.c +++ b/tools/intel_gpu_top.c @@ -56,6 +56,10 @@ struct pmu_counter { struct pmu_pair val; }; +#define NUM_QUEUES (3) + +#define NUM_LOADS (3) + struct engine { const char *name; const char *display_name; @@ -65,9 +69,13 @@ struct engine { unsigned int num_counters; + double qd[3]; + double load_avg[NUM_LOADS]; + struct pmu_counter busy; struct pmu_counter wait; struct pmu_counter sema; + struct pmu_counter queue[NUM_QUEUES]; }; struct engines { @@ -95,6 +103,11 @@ struct engines { struct pmu_counter imc_reads; struct pmu_counter imc_writes; + double qd_scale; + + double load_exp[NUM_LOADS]; + double load_avg[NUM_LOADS]; + struct engine engine; }; @@ -320,6 +333,13 @@ static double filename_to_double(const char *filename) return v; } +#define I915_EVENT "/sys/devices/i915/events/" + +static double i915_qd_scale(void) +{ + return filename_to_double(I915_EVENT "rcs0-queued.scale"); +} + #define RAPL_ROOT "/sys/devices/power/" #define RAPL_EVENT "/sys/devices/power/events/" @@ -453,6 +473,8 @@ static int pmu_init(struct engines *engines) engines->rc6.config = I915_PMU_RC6_RESIDENCY; _open_pmu(engines->num_counters, &engines->rc6, engines->fd); + engines->qd_scale = i915_qd_scale(); + for (i = 0; i < engines->num_engines; i++) { struct engine *engine = engine_ptr(engines, i); struct { @@ -462,6 +484,9 @@ static int pmu_init(struct engines *engines) { .pmu = &engine->busy, .counter = "busy" }, { .pmu = &engine->wait, .counter = "wait" }, { .pmu = &engine->sema, .counter = "sema" }, + { .pmu = &engine->queue[0], .counter = "queued" }, + { .pmu = &engine->queue[1], .counter = "runnable" }, + { .pmu = &engine->queue[2], .counter = "running" }, { .pmu = NULL, .counter = NULL }, }; @@ -576,12 +601,11 @@ static void fill_str(char *buf, unsigned int bufsz, char c, unsigned int num) *buf = 0; } -static void pmu_calc(struct pmu_counter *cnt, - char *buf, unsigned int bufsz, - unsigned int width, unsigned width_dec, - double d, double t, double s) +static void _pmu_calc(struct pmu_counter *cnt, + char *buf, unsigned int bufsz, + unsigned int width, unsigned width_dec, + double val) { - double val; int len; assert(bufsz >= (width + width_dec + 1)); @@ -591,8 +615,6 @@ static void pmu_calc(struct pmu_counter *cnt, return; } - val = __pmu_calc(&cnt->val, d, t, s); - len = snprintf(buf, bufsz, "%*.*f", width + width_dec, width_dec, val); if (len < 0 || len == bufsz) { fill_str(buf, bufsz, 'X', width + width_dec); @@ -600,6 +622,16 @@ static void pmu_calc(struct pmu_counter *cnt, } } +static void pmu_calc(struct pmu_counter *cnt, + char *buf, unsigned int bufsz, + unsigned int width, unsigned width_dec, + double d, double t, double s) +{ + double val = __pmu_calc(&cnt->val, d, t, s); + + _pmu_calc(cnt, buf, bufsz, width, width_dec, val); +} + static uint64_t __pmu_read_single(int fd, uint64_t *ts) { uint64_t data[2] = { }; @@ -658,10 +690,14 @@ static void pmu_sample(struct engines *engines) for (i = 0; i < engines->num_engines; i++) { struct engine *engine = engine_ptr(engines, i); + unsigned int j; update_sample(&engine->busy, val); update_sample(&engine->sema, val); update_sample(&engine->wait, val); + + for (j = 0; j < NUM_QUEUES; j++) + update_sample(&engine->queue[j], val); } } @@ -702,12 +738,19 @@ usage(const char *appname) appname, DEFAULT_PERIOD_MS); } +static double update_load(double load, double exp, double val) +{ + return val + exp * (load - val); +} + int main(int argc, char **argv) { unsigned int period_us = DEFAULT_PERIOD_MS * 1000; + const double load_period[NUM_LOADS] = { 1.0, 30.0, 900.0 }; int con_w = -1, con_h = -1; struct engines *engines; unsigned int i; + double period; int ret, ch; /* Parse options */ @@ -741,10 +784,15 @@ int main(int argc, char **argv) return 1; } + /* Load average setup. */ + period = (double)period_us / 1e6; + for (i = 0; i < NUM_LOADS; i++) + engines->load_exp[i] = exp(-period / load_period[i]); + pmu_sample(engines); for (;;) { - double t; + double t, qd = 0; #define BUFSZ 16 char freq[BUFSZ]; char fact[BUFSZ]; @@ -754,6 +802,7 @@ int main(int argc, char **argv) char reads[BUFSZ]; char writes[BUFSZ]; struct winsize ws; + unsigned int j; int lines = 0; /* Update terminal size. */ @@ -778,8 +827,44 @@ int main(int argc, char **argv) pmu_calc(&engines->imc_writes, writes, BUFSZ, 6, 0, 1.0, t, engines->imc_writes_scale); + for (i = 0; i < engines->num_engines; i++) { + struct engine *engine = engine_ptr(engines, i); + + if (!engine->num_counters) + continue; + + for (j = 0; j < NUM_QUEUES; j++) { + if (!engine->queue[j].present) + continue; + + engine->qd[j] = + __pmu_calc(&engine->queue[j].val, 1, t, + engines->qd_scale); + } + + qd += engine->qd[1] + engine->qd[2]; + + for (j = 0; j < NUM_LOADS; j++) { + engine->load_avg[j] = + update_load(engine->load_avg[j], + engines->load_exp[j], + engine->qd[1] + + engine->qd[2]); + } + } + + for (j = 0; j < NUM_LOADS; j++) { + engines->load_avg[j] = + update_load(engines->load_avg[j], + engines->load_exp[j], + qd); + } + if (lines++ < con_h) - printf("intel-gpu-top - %s/%s MHz; %s%% RC6; %s %s; %s irqs/s\n", + printf("intel-gpu-top - load avg %5.2f, %5.2f, %5.2f; %s/%s MHz; %s%% RC6; %s %s; %s irqs/s\n", + engines->load_avg[0], + engines->load_avg[1], + engines->load_avg[2], fact, freq, rc6, power, engines->rapl_unit, irq); if (lines++ < con_h) @@ -803,7 +888,7 @@ int main(int argc, char **argv) if (engine->num_counters && lines < con_h) { const char *a = " ENGINE BUSY "; - const char *b = " MI_SEMA MI_WAIT"; + const char *b = "Q r R MI_SEMA MI_WAIT"; printf("\033[7m%s%*s%s\033[0m\n", a, @@ -817,6 +902,7 @@ int main(int argc, char **argv) for (i = 0; i < engines->num_engines && lines < con_h; i++) { struct engine *engine = engine_ptr(engines, i); unsigned int max_w = con_w - 1; + char qdbuf[NUM_LOADS][BUFSZ]; unsigned int len; char sema[BUFSZ]; char wait[BUFSZ]; @@ -827,14 +913,22 @@ int main(int argc, char **argv) if (!engine->num_counters) continue; + for (j = 0; j < NUM_QUEUES; j++) + _pmu_calc(&engine->queue[j], qdbuf[j], BUFSZ, + 3, 0, engine->qd[j]); + pmu_calc(&engine->sema, sema, BUFSZ, 3, 0, 1e9, t, 100); pmu_calc(&engine->wait, wait, BUFSZ, 3, 0, 1e9, t, 100); - len = snprintf(buf, sizeof(buf), " %s%% %s%%", + + len = snprintf(buf, sizeof(buf), + " %s %s %s %s%% %s%%", + qdbuf[0], qdbuf[1], qdbuf[2], sema, wait); - pmu_calc(&engine->busy, busy, BUFSZ, 6, 2, 1e9, t, - 100); - len += printf("%16s %s%% ", engine->display_name, busy); + pmu_calc(&engine->busy, busy, BUFSZ, 6, 2, 1e9, t, 100); + + len += printf("%16s %s%% ", + engine->display_name, busy); val = __pmu_calc(&engine->busy.val, 1e9, t, 100); print_percentage_bar(val, max_w - len); diff --git a/tools/meson.build b/tools/meson.build index e4517d667299..c1dd71fada79 100644 --- a/tools/meson.build +++ b/tools/meson.build @@ -97,7 +97,7 @@ shared_library('intel_aubdump', 'aubdump.c', executable('intel_gpu_top', 'intel_gpu_top.c', install : true, install_rpath : bindir_rpathdir, - dependencies : tool_deps + [ lib_igt_perf ]) + dependencies : tool_deps + [ lib_igt_perf, math ]) conf_data = configuration_data() conf_data.set('prefix', prefix)