From patchwork Wed Nov 8 16:24:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lionel Landwerlin X-Patchwork-Id: 10048781 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 67A1A60381 for ; Wed, 8 Nov 2017 16:24:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5DC4C2A6E7 for ; Wed, 8 Nov 2017 16:24:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5278A2A717; Wed, 8 Nov 2017 16:24:18 +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=-4.2 required=2.0 tests=BAYES_00, 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 CA0B62A6E7 for ; Wed, 8 Nov 2017 16:24:17 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4EB206E735; Wed, 8 Nov 2017 16:24:17 +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 517036E735 for ; Wed, 8 Nov 2017 16:24:16 +0000 (UTC) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 08 Nov 2017 08:24:15 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.44,364,1505804400"; d="scan'208"; a="1241547654" Received: from delly.ld.intel.com ([10.103.239.204]) by fmsmga002.fm.intel.com with ESMTP; 08 Nov 2017 08:24:14 -0800 From: Lionel Landwerlin To: intel-gfx@lists.freedesktop.org Date: Wed, 8 Nov 2017 16:24:11 +0000 Message-Id: <20171108162411.4247-4-lionel.g.landwerlin@intel.com> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171108162411.4247-1-lionel.g.landwerlin@intel.com> References: <20171108162411.4247-1-lionel.g.landwerlin@intel.com> Subject: [Intel-gfx] [PATCH i-g-t 3/3] tests/query_info: add topology query tests 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: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP We can verify that topology is consistent with previous getparam like EU_TOTAL. We also verify that CS timestamp frequency is always filled. v2: Use v2 of kernel uapi (Lionel) Fix Gen < 8 issue v3: Use query info uAPI (Lionel) Signed-off-by: Lionel Landwerlin --- tests/query_info.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) diff --git a/tests/query_info.c b/tests/query_info.c index 18a91983..66abc393 100644 --- a/tests/query_info.c +++ b/tests/query_info.c @@ -84,6 +84,72 @@ struct local_drm_i915_query_info { __u64 info_ptr; }; +#ifndef I915_PARAM_SLICE_MASK +#define I915_PARAM_SLICE_MASK 46 +#endif + +#ifndef I915_PARAM_SUBSLICE_MASK +#define I915_PARAM_SUBSLICE_MASK 47 +#endif + +#ifndef I915_QUERY_INFO_RCS_TOPOLOGY +/* Query RCS topology. + * + * drm_i915_query_info.query_params[0] should be set to one of the + * I915_RCS_TOPOLOGY_* define. + * + * drm_i915_gem_query_info.info_ptr will be written to with + * drm_i915_rcs_topology_info. + */ +#define I915_QUERY_INFO_RCS_TOPOLOGY 1 /* version 1 */ + +/* Query RCS slice topology + * + * The meaning of the drm_i915_rcs_topology_info fields is : + * + * params[0]: number of slices + * + * data: Each bit indicates whether a slice is available (1) or fused off (0). + * Formula to tell if slice X is available : + * + * (data[X / 8] >> (X % 8)) & 1 + */ +#define I915_RCS_TOPOLOGY_SLICE 0 /* version 1 */ +/* Query RCS subslice topology + * + * The meaning of the drm_i915_rcs_topology_info fields is : + * + * params[0]: number of slices + * params[1]: slice stride + * + * data: each bit indicates whether a subslice is available (1) or fused off + * (0). Formula to tell if slice X subslice Y is available : + * + * (data[(X * params[1]) + Y / 8] >> (Y % 8)) & 1 + */ +#define I915_RCS_TOPOLOGY_SUBSLICE 1 /* version 1 */ +/* Query RCS EU topology + * + * The meaning of the drm_i915_rcs_topology_info fields is : + * + * params[0]: number of slices + * params[1]: slice stride + * params[2]: subslice stride + * + * data: Each bit indicates whether a subslice is available (1) or fused off + * (0). Formula to tell if slice X subslice Y eu Z is available : + * + * (data[X * params[1] + Y * params[2] + Z / 8] >> (Z % 8)) & 1 + */ +#define I915_RCS_TOPOLOGY_EU 2 /* version 1 */ +#endif /* I915_QUERY_INFO_RCS_TOPOLOGY */ + +struct local_drm_i915_rcs_topology_info { + __u32 params[6]; + + __u8 data[]; +}; + static bool query_info_supports(int fd, int version) { struct local_drm_i915_query_info info = {}; @@ -262,13 +328,149 @@ static void test_query_engine_exec_class_instance(int fd) } +static bool query_topology_supported(int fd) +{ + struct local_drm_i915_query_info info = {}; + + info.version = 1; + info.query = I915_QUERY_INFO_RCS_TOPOLOGY; + info.query_params[0] = I915_RCS_TOPOLOGY_SLICE; + + return igt_ioctl(fd, DRM_IOCTL_I915_QUERY_INFO, &info) == 0; +} + +static void test_query_topology_pre_gen8(int fd) +{ + struct local_drm_i915_query_info info = {}; + + info.version = 1; + info.query = I915_QUERY_INFO_RCS_TOPOLOGY; + info.query_params[0] = I915_RCS_TOPOLOGY_SLICE; + + do_ioctl_err(fd, DRM_IOCTL_I915_QUERY_INFO, &info, ENODEV); +} + +static void +test_query_topology_coherent_slice_mask(int fd) +{ + struct local_drm_i915_query_info info; + struct local_drm_i915_rcs_topology_info *topology; + drm_i915_getparam_t gp; + int slice_mask, subslice_mask; + int i, topology_slices, topology_subslices_slice0; + + gp.param = I915_PARAM_SLICE_MASK; + gp.value = &slice_mask; + do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); + + gp.param = I915_PARAM_SUBSLICE_MASK; + gp.value = &subslice_mask; + do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); + + igt_debug("slice_mask=0x%x subslice_mask=0x%x\n", slice_mask, subslice_mask); + + /* Slices */ + memset(&info, 0, sizeof(info)); + info.query = I915_QUERY_INFO_RCS_TOPOLOGY; + info.query_params[0] = I915_RCS_TOPOLOGY_SLICE; + do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); + + topology = malloc(info.info_ptr_len); + memset(topology, 0, info.info_ptr_len); + info.info_ptr = to_user_pointer(topology); + do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); + + topology_slices = 0; + for (i = 0; i < (topology->params[0] / 8) + 1; i++) + topology_slices += __builtin_popcount(topology->data[i]); + + /* These 2 should always match. */ + igt_assert(__builtin_popcount(slice_mask) == topology_slices); + + free(topology); + + /* Subslices */ + memset(&info, 0, sizeof(info)); + info.query = I915_QUERY_INFO_RCS_TOPOLOGY; + info.query_params[0] = I915_RCS_TOPOLOGY_SUBSLICE; + do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); + + topology = malloc(info.info_ptr_len); + memset(topology, 0, info.info_ptr_len); + info.info_ptr = to_user_pointer(topology); + do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); + + topology_subslices_slice0 = 0; + for (i = 0; i < topology->params[1]; i++) + topology_subslices_slice0 += __builtin_popcount(topology->data[i]); + + /* I915_PARAM_SUBSLICE_MASK returns the value for slice0, we + * should match the values for the first slice of the + * topology. + */ + igt_assert(__builtin_popcount(subslice_mask) == topology_subslices_slice0); + + free(topology); +} + +static void +test_query_topology_matches_eu_total(int fd) +{ + struct local_drm_i915_query_info info; + struct local_drm_i915_rcs_topology_info *topology; + drm_i915_getparam_t gp; + int n_eus, n_eus_topology, s; + + gp.param = I915_PARAM_EU_TOTAL; + gp.value = &n_eus; + do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); + igt_debug("n_eus=%i\n", n_eus); + + memset(&info, 0, sizeof(info)); + info.query = I915_QUERY_INFO_RCS_TOPOLOGY; + info.query_params[0] = I915_RCS_TOPOLOGY_EU; + do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); + + topology = malloc(info.info_ptr_len); + memset(topology, 0, info.info_ptr_len); + info.info_ptr = to_user_pointer(topology); + do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp); + + n_eus_topology = 0; + for (s = 0; s < topology->params[0]; s++) { + int ss; + + igt_debug("slice%i:\n", s); + + for (ss = 0; ss < topology->params[1] / topology->params[2]; ss++) { + int eu, n_subslice_eus = 0; + + igt_debug("\tsubslice: %i\n", ss); + + igt_debug("\t\teu_mask:"); + for (eu = 0; eu < topology->params[2]; eu++) { + uint8_t val = topology->data[s * topology->params[1] + + ss * topology->params[2] + eu]; + igt_debug(" 0x%hhx", val); + n_subslice_eus += __builtin_popcount(val); + n_eus_topology += __builtin_popcount(val); + } + igt_debug(" (%i)\n", n_subslice_eus); + } + } + + igt_assert(n_eus_topology == n_eus); +} + igt_main { int fd = -1; + int devid; igt_fixture { fd = drm_open_driver(DRIVER_INTEL); igt_require(query_info_supports(fd, 1 /* version */)); + devid = intel_get_drm_devid(fd); } igt_subtest("query-version") @@ -286,6 +488,24 @@ igt_main igt_subtest("query-engine-exec-class-instance") test_query_engine_exec_class_instance(fd); + igt_subtest("query-topology-pre-gen8") { + igt_require(intel_gen(devid) < 8); + igt_require(query_topology_supported(fd)); + test_query_topology_pre_gen8(fd); + } + + igt_subtest("query-topology-coherent-slice-mask") { + igt_require(AT_LEAST_GEN(devid, 8)); + igt_require(query_topology_supported(fd)); + test_query_topology_coherent_slice_mask(fd); + } + + igt_subtest("query-topology-matches-eu-total") { + igt_require(AT_LEAST_GEN(devid, 8)); + igt_require(query_topology_supported(fd)); + test_query_topology_matches_eu_total(fd); + } + igt_fixture { close(fd); }