From patchwork Tue Feb 22 13:56:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 12755141 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A8EE9C433EF for ; Tue, 22 Feb 2022 13:56:58 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9F41B10E7FE; Tue, 22 Feb 2022 13:56:33 +0000 (UTC) Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7812710E7F1; Tue, 22 Feb 2022 13:56:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1645538190; x=1677074190; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=k8oXj9pkWUwvSGfVFpbikXm0TD++sjG6Zkk2XcP66oI=; b=MKxeHvrW2Z1Xv7PHo+8LzgX+7Ckh1GK2QMBC4gFHHh4mRVLtyXhAv7pZ oNhl2qRchD/RnIyOTzEI6Ny3FOWbOJ4LmPe0V0hZNMxlxxFscKM4CSEXQ zghl+XnEx6b88yrx8kbIRxBElUV9y8+j23B0AF1dfmu0HSeReZ87iQBN2 d0Fo62gksz9J8P0x7zIF40rWsgwPVzSV4GHuE+kWQd9kq/iMDt6oyQDds +Ac5oHHcN/GpIOSoygT2ZSQnU3nT1GnVRMEOS71m/AZvCbdd8eD8cGN64 99dofZOD+PDFVHlwKn//s3FkdIzWZKWEG9fRF/1ymPmB2HQUpfsDt0KIC Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10265"; a="232326520" X-IronPort-AV: E=Sophos;i="5.88,387,1635231600"; d="scan'208";a="232326520" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga107.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Feb 2022 05:56:30 -0800 X-IronPort-AV: E=Sophos;i="5.88,387,1635231600"; d="scan'208";a="505534120" Received: from sjgillin-mobl.ger.corp.intel.com (HELO tursulin-mobl2.home) ([10.213.218.63]) by orsmga002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Feb 2022 05:56:28 -0800 From: Tvrtko Ursulin To: igt-dev@lists.freedesktop.org Date: Tue, 22 Feb 2022 13:56:04 +0000 Message-Id: <20220222135605.1120767-11-tvrtko.ursulin@linux.intel.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220222135605.1120767-1-tvrtko.ursulin@linux.intel.com> References: <20220222135605.1120767-1-tvrtko.ursulin@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH i-g-t 10/11] libdrmclient: Enforce client status sort order in the library X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 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, dri-devel@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Tvrtko Ursulin Some libdrmclient operations require that inactive clients are last in the list. Rather than relying on callers of the library sort routine to implement their comparison callbacks correctly, enforce this order directly in the library and let callers comparison callbacks concern themselves only with ordering they are interested in. Signed-off-by: Tvrtko Ursulin --- lib/igt_drm_clients.c | 25 +++++++++++-- lib/igt_drm_clients.h | 2 +- tools/intel_gpu_top.c | 81 +++++++++++++++++++------------------------ 3 files changed, 58 insertions(+), 50 deletions(-) diff --git a/lib/igt_drm_clients.c b/lib/igt_drm_clients.c index 6299f3632b74..e8e86969f984 100644 --- a/lib/igt_drm_clients.c +++ b/lib/igt_drm_clients.c @@ -185,10 +185,29 @@ void igt_drm_client_free(struct igt_drm_client *c) memset(c, 0, sizeof(*c)); } +struct sort_context +{ + int (*user_cmp)(const void *, const void *, void *); +}; + +static int sort_cmp(const void *_a, const void *_b, void *_ctx) +{ + const struct sort_context *ctx = _ctx; + const struct igt_drm_client *a = _a; + const struct igt_drm_client *b = _b; + int cmp = b->status - a->status; + + if (cmp == 0) + return ctx->user_cmp(_a, _b, _ctx); + else + return cmp; +} + struct igt_drm_clients * igt_drm_clients_sort(struct igt_drm_clients *clients, - int (*cmp)(const void *, const void *)) + int (*cmp)(const void *, const void *, void *)) { + struct sort_context ctx = { .user_cmp = cmp }; unsigned int active, free; struct igt_drm_client *c; int tmp; @@ -196,8 +215,8 @@ igt_drm_clients_sort(struct igt_drm_clients *clients, if (!clients) return clients; - qsort(clients->client, clients->num_clients, sizeof(*clients->client), - cmp); + qsort_r(clients->client, clients->num_clients, sizeof(*clients->client), + sort_cmp, &ctx); /* Trim excessive array space. */ active = 0; diff --git a/lib/igt_drm_clients.h b/lib/igt_drm_clients.h index 4668df2d7fd6..47547aa8b75f 100644 --- a/lib/igt_drm_clients.h +++ b/lib/igt_drm_clients.h @@ -90,7 +90,7 @@ igt_drm_clients_find(struct igt_drm_clients *clients, struct igt_drm_clients * igt_drm_clients_sort(struct igt_drm_clients *clients, - int (*cmp)(const void *, const void *)); + int (*cmp)(const void *, const void *, void *)); void igt_drm_client_update(struct igt_drm_client *c, unsigned int pid, char *name, uint64_t val[16]); diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c index fb7ec9ae6d74..fcc4e5501d3d 100644 --- a/tools/intel_gpu_top.c +++ b/tools/intel_gpu_top.c @@ -644,85 +644,74 @@ static void pmu_sample(struct engines *engines) } } -static int client_last_cmp(const void *_a, const void *_b) +static int +__client_id_cmp(const struct igt_drm_client *a, + const struct igt_drm_client *b) +{ + if (a->id > b->id) + return 1; + else if (a->id < b->id) + return -1; + else + return 0; +} + +static int client_last_cmp(const void *_a, const void *_b, void *unused) { const struct igt_drm_client *a = _a; const struct igt_drm_client *b = _b; - long tot_a, tot_b; + long val_a = a->last_runtime, val_b = b->last_runtime; /* * Sort clients in descending order of runtime in the previous sampling - * period for active ones, followed by inactive. Tie-breaker is client - * id. + * period. Tie-breaker is client id. */ - tot_a = a->status == IGT_DRM_CLIENT_ALIVE ? a->last_runtime : -1; - tot_b = b->status == IGT_DRM_CLIENT_ALIVE ? b->last_runtime : -1; - - tot_b -= tot_a; - if (tot_b > 0) + if (val_a == val_b) + return __client_id_cmp(a, b); + else if (val_b > val_a) return 1; - if (tot_b < 0) + else return -1; - - return (int)b->id - a->id; } -static int client_total_cmp(const void *_a, const void *_b) +static int client_total_cmp(const void *_a, const void *_b, void *unused) { const struct igt_drm_client *a = _a; const struct igt_drm_client *b = _b; - long tot_a, tot_b; + long val_a = a->total_runtime, val_b = b->total_runtime; - tot_a = a->status == IGT_DRM_CLIENT_ALIVE ? a->total_runtime : -1; - tot_b = b->status == IGT_DRM_CLIENT_ALIVE ? b->total_runtime : -1; - - tot_b -= tot_a; - if (tot_b > 0) + if (val_a == val_b) + return __client_id_cmp(a, b); + else if (val_b > val_a) return 1; - if (tot_b < 0) + else return -1; - - return (int)b->id - a->id; } -static int client_id_cmp(const void *_a, const void *_b) +static int client_id_cmp(const void *_a, const void *_b, void *unused) { const struct igt_drm_client *a = _a; const struct igt_drm_client *b = _b; - int id_a, id_b; - - id_a = a->status == IGT_DRM_CLIENT_ALIVE ? a->id : -1; - id_b = b->status == IGT_DRM_CLIENT_ALIVE ? b->id : -1; - - id_b -= id_a; - if (id_b > 0) - return 1; - if (id_b < 0) - return -1; - return (int)b->id - a->id; + return __client_id_cmp(a, b); } -static int client_pid_cmp(const void *_a, const void *_b) +static int client_pid_cmp(const void *_a, const void *_b, void *unused) { const struct igt_drm_client *a = _a; const struct igt_drm_client *b = _b; - int pid_a, pid_b; - - pid_a = a->status == IGT_DRM_CLIENT_ALIVE ? a->pid : INT_MAX; - pid_b = b->status == IGT_DRM_CLIENT_ALIVE ? b->pid : INT_MAX; + int val_a = a->pid, val_b = b->pid; - pid_b -= pid_a; - if (pid_b > 0) + if (val_a == val_b) + return __client_id_cmp(a, b); + else if (val_b > val_a) return -1; - if (pid_b < 0) + else return 1; - - return (int)a->id - b->id; } -static int (*client_cmp)(const void *, const void *) = client_last_cmp; +static int (*client_cmp)(const void *, const void *, void *) = client_last_cmp; static bool aggregate_pids = true; @@ -1910,7 +1899,7 @@ static void interactive_stdin(void) static void select_client_sort(void) { struct { - int (*cmp)(const void *, const void *); + int (*cmp)(const void *, const void *, void *); const char *msg; } cmp[] = { { client_last_cmp, "Sorting clients by current GPU usage." },