From patchwork Tue May 2 15:08:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: oscar.mateo@intel.com X-Patchwork-Id: 9708611 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 24D226021C for ; Tue, 2 May 2017 22:08:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 15672284DA for ; Tue, 2 May 2017 22:08:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 09F2F284EE; Tue, 2 May 2017 22:08:22 +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=-2.7 required=2.0 tests=BAYES_00, DATE_IN_PAST_06_12, 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 65EE2284DA for ; Tue, 2 May 2017 22:08:21 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1B0C16E28C; Tue, 2 May 2017 22:08:21 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTPS id 05F0C6E28C for ; Tue, 2 May 2017 22:08:20 +0000 (UTC) Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 May 2017 15:08:15 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.38,281,1491289200"; d="scan'208";a="96846117" Received: from omateolo-linux.fm.intel.com ([10.1.27.118]) by fmsmga006.fm.intel.com with ESMTP; 02 May 2017 15:08:14 -0700 From: Oscar Mateo To: intel-gfx@lists.freedesktop.org Date: Tue, 2 May 2017 15:08:18 +0000 Message-Id: <1493737698-5352-1-git-send-email-oscar.mateo@intel.com> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 Subject: [Intel-gfx] [RFC] benchmarks/gem_slice_shutdown: microbenchmark for slice shutdown delays X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Cc: Dmitry Rogozhkin Cc: Chris Wilson Signed-off-by: Oscar Mateo --- benchmarks/Makefile.sources | 1 + benchmarks/gem_slice_shutdown.c | 295 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 296 insertions(+) create mode 100644 benchmarks/gem_slice_shutdown.c diff --git a/benchmarks/Makefile.sources b/benchmarks/Makefile.sources index 3a94115..591b5ae 100644 --- a/benchmarks/Makefile.sources +++ b/benchmarks/Makefile.sources @@ -13,6 +13,7 @@ benchmarks_prog_list = \ gem_mmap \ gem_prw \ gem_set_domain \ + gem_slice_shutdown \ gem_syslatency \ gem_wsim \ kms_vblank \ diff --git a/benchmarks/gem_slice_shutdown.c b/benchmarks/gem_slice_shutdown.c new file mode 100644 index 0000000..dcb17c1 --- /dev/null +++ b/benchmarks/gem_slice_shutdown.c @@ -0,0 +1,295 @@ +/* + * Copyright © 2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Oscar Mateo + * + */ + +/* + * This tool measures time to change the configuration of number of slices + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "drm.h" +#include "ioctl_wrappers.h" +#include "drmtest.h" +#include "intel_io.h" +#include "igt_stats.h" +#include "intel_chipset.h" +#include "intel_bufmgr.h" + +#define GEN8_R_PWR_CLK_STATE (0x20C8) +#define GEN8_RPCS_ENABLE (1 << 31) +#define GEN8_RPCS_S_CNT_ENABLE (1 << 18) +#define GEN8_RPCS_S_CNT_SHIFT 15 +#define GEN8_RPCS_S_CNT_MASK (0x7 << GEN8_RPCS_S_CNT_SHIFT) +#define GEN8_RPCS_SS_CNT_ENABLE (1 << 11) +#define GEN8_RPCS_SS_CNT_SHIFT 8 +#define GEN8_RPCS_SS_CNT_MASK (0x7 << GEN8_RPCS_SS_CNT_SHIFT) +#define GEN8_RPCS_EU_MAX_SHIFT 4 +#define GEN8_RPCS_EU_MAX_MASK (0xf << GEN8_RPCS_EU_MAX_SHIFT) +#define GEN8_RPCS_EU_MIN_SHIFT 0 +#define GEN8_RPCS_EU_MIN_MASK (0xf << GEN8_RPCS_EU_MIN_SHIFT) + +static const char *yesno(bool x) +{ + return x ? "yes" : "no"; +} + +static void print_rpcs_config(uint32_t rpcs_config) +{ + bool rpcs_enable, s_enable, ss_enable; + uint s_count, ss_count, eu_max, eu_min; + + rpcs_enable = rpcs_config & GEN8_RPCS_ENABLE; + s_enable = rpcs_config & GEN8_RPCS_S_CNT_ENABLE; + ss_enable = rpcs_config & GEN8_RPCS_SS_CNT_ENABLE; + s_count = (rpcs_config & GEN8_RPCS_S_CNT_MASK) >> GEN8_RPCS_S_CNT_SHIFT; + ss_count = (rpcs_config & GEN8_RPCS_SS_CNT_MASK) >> GEN8_RPCS_SS_CNT_SHIFT; + eu_max = (rpcs_config & GEN8_RPCS_EU_MAX_MASK) >> GEN8_RPCS_EU_MAX_SHIFT; + eu_min = (rpcs_config & GEN8_RPCS_EU_MIN_MASK) >> GEN8_RPCS_EU_MIN_SHIFT; + printf("RPCS enabled: %s\n", yesno(rpcs_enable)); + printf("Slice count enabled: %s, count: %u\n", yesno(s_enable), s_count); + printf("Subslice count enabled: %s, count: %u\n", yesno(ss_enable), ss_count); + printf("EU max: %u, min: %u\n", eu_max, eu_min); +} + +static void init_buffer(drm_intel_bufmgr *bufmgr, + struct igt_buf *buf, + uint32_t size) +{ + buf->bo = drm_intel_bo_alloc(bufmgr, "", size, 4096); + buf->size = size; + buf->tiling = I915_TILING_NONE; + buf->stride = 4096; +} + +static double elapsed(const struct timespec *start, const struct timespec *end) +{ + return 1e6*(end->tv_sec - start->tv_sec) + 1e-3*(end->tv_nsec - start->tv_nsec); +} + +#define MI_STORE_REGISTER_MEM_64_BIT_ADDR ((0x24 << 23) | 2) + +static uint32_t do_read_pwrclk_state(drm_intel_bufmgr *bufmgr, + struct intel_batchbuffer *batch, + drm_intel_context *context) +{ + uint32_t rpcs_config; + uint32_t *data; + drm_intel_bo *dst_bo; + + dst_bo = drm_intel_bo_alloc(bufmgr, "dst", 4, 4096); + + BEGIN_BATCH(3, 1); + OUT_BATCH(MI_STORE_REGISTER_MEM_64_BIT_ADDR); + OUT_BATCH(GEN8_R_PWR_CLK_STATE); + OUT_RELOC(dst_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); + ADVANCE_BATCH(); + + intel_batchbuffer_flush_with_context(batch, context); + + drm_intel_bo_map(dst_bo, 1); + + data = dst_bo->virtual; + rpcs_config = *data; + + drm_intel_bo_unmap(dst_bo); + + drm_intel_bo_unreference(dst_bo); + + return rpcs_config; +} + +#define LOCAL_MI_LOAD_REGISTER_IMM (0x22 << 23) + +#define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|((len)-2)) +#define PIPE_CONTROL_CS_STALL (1<<20) +#define PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH (1<<12) +#define PIPE_CONTROL_FLUSH_ENABLE (1<<7) +#define PIPE_CONTROL_DC_FLUSH_ENABLE (1<<5) +#define PIPE_CONTROL_DEPTH_CACHE_FLUSH (1<<0) + +static void emit_config_slice_count(drm_intel_bufmgr *bufmgr, + struct intel_batchbuffer *batch, + drm_intel_context *context, + uint32_t rpcs_config) +{ + drm_intel_bo *dst_bo; + + dst_bo = drm_intel_bo_alloc(bufmgr, "scratch", 4, 4096); + + BEGIN_BATCH(9, 1); + OUT_BATCH(LOCAL_MI_LOAD_REGISTER_IMM | 1); + OUT_BATCH(GEN8_R_PWR_CLK_STATE); + OUT_BATCH(rpcs_config); + OUT_BATCH(GFX_OP_PIPE_CONTROL(6)); + OUT_BATCH(PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH | + PIPE_CONTROL_DEPTH_CACHE_FLUSH | + PIPE_CONTROL_DC_FLUSH_ENABLE | + PIPE_CONTROL_FLUSH_ENABLE | + PIPE_CONTROL_CS_STALL); + OUT_RELOC(dst_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); + OUT_BATCH(0); + OUT_BATCH(0); + OUT_BATCH(0); + ADVANCE_BATCH(); + + drm_intel_bo_unreference(dst_bo); +} + +static void do_test(igt_render_copyfunc_t rendercopy, + drm_intel_bufmgr *bufmgr, + drm_intel_context *context, + struct intel_batchbuffer *batch, + uint32_t rpcs_config, + struct igt_buf *src, + struct igt_buf *dst, + uint c) +{ + rpcs_config &= ~GEN8_RPCS_S_CNT_MASK; + rpcs_config |= (c << GEN8_RPCS_S_CNT_SHIFT); + + emit_config_slice_count(bufmgr, batch, context, rpcs_config); + rendercopy(batch, context, src, 0, 0, 0, 0, dst, 0, 0); + drm_intel_bo_wait_rendering(dst->bo); +} + +static void do_measures(igt_render_copyfunc_t rendercopy, + drm_intel_bufmgr *bufmgr, + drm_intel_context *context, + struct intel_batchbuffer *batch, + uint32_t rpcs_config, + struct igt_buf *src, + struct igt_buf *dst, + uint c1, uint c2) +{ + uint c = c1; + struct igt_mean real[2], baseline[2]; + struct timespec start, end; + int i, j; + + for (i = 0; i < 2; i++) { + igt_mean_init(&real[i]); + igt_mean_init(&baseline[i]); + } + + /* Initial config and warm up */ + do_test(rendercopy, bufmgr, context, batch, rpcs_config, src, dst, c); + +#define LOOPS 1000 + for (j = 0; j < LOOPS; j++) { + c = c2; + for (i = 0; i < 2; i++) { + clock_gettime(CLOCK_MONOTONIC, &start); + do_test(rendercopy, bufmgr, context, batch, + rpcs_config, src, dst, c); + clock_gettime(CLOCK_MONOTONIC, &end); + + igt_mean_add(&real[i], elapsed(&start, &end)); + + clock_gettime(CLOCK_MONOTONIC, &start); + do_test(rendercopy, bufmgr, context, batch, + rpcs_config, src, dst, c); + clock_gettime(CLOCK_MONOTONIC, &end); + + igt_mean_add(&baseline[i], elapsed(&start, &end)); + + c = c1; + } + } + + printf("Slice poweron time (%u -> %u): %7.3f us\n", c1, c2, + igt_mean_get(&real[0]) - igt_mean_get(&baseline[0])); + printf("Slice shutdown time (%u -> %u): %7.3f us\n", c2, c1, + igt_mean_get(&real[1]) - igt_mean_get(&baseline[1])); + + printf("\n"); +} + +static void slice_shutdown(int fd, int devid) +{ + igt_render_copyfunc_t rendercopy = igt_get_render_copyfunc(devid); + drm_intel_bufmgr *bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); + drm_intel_context *context = drm_intel_gem_context_create(bufmgr); + struct intel_batchbuffer *batch = intel_batchbuffer_alloc(bufmgr, devid); + struct igt_buf src, dst; + uint32_t rpcs_config; + bool rpcs_enable, s_enable; + int s_count; + uint i, j; + + init_buffer(bufmgr, &src, 10*4096*4096); + init_buffer(bufmgr, &dst, 10*4096*4096); + + rpcs_config = do_read_pwrclk_state(bufmgr, batch, context); + print_rpcs_config(rpcs_config); + + rpcs_enable = rpcs_config & GEN8_RPCS_ENABLE; + s_enable = rpcs_config & GEN8_RPCS_S_CNT_ENABLE; + + if (!rpcs_enable || !s_enable) { + fprintf(stderr, "We need slice count to be already enabled\n"); + exit(-1); + } + + s_count = (rpcs_config & GEN8_RPCS_S_CNT_MASK) >> GEN8_RPCS_S_CNT_SHIFT; + + for (i = 1; i <= s_count; i++) + for (j = i + 1; j <= s_count; j++) + do_measures(rendercopy, bufmgr, context, batch, + rpcs_config, &src, &dst, i, j); + + intel_batchbuffer_free(batch); + drm_intel_gem_context_destroy(context); + drm_intel_bufmgr_destroy(bufmgr); +} + +int main(int argc, char **argv) +{ + int fd, devid; + + fd = drm_open_driver(DRIVER_INTEL); + + devid = intel_get_drm_devid(fd); + if (intel_gen(devid) < 8) { + fprintf(stderr, "gen8+ required, yours is gen%u\n", + intel_gen(devid)); + exit(-1); + } + + slice_shutdown(fd, devid); +}