Received: by 2002:ab2:60d1:0:b0:1f7:5705:b850 with SMTP id i17csp667903lqm; Wed, 1 May 2024 11:51:11 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCUjLCf1ayedSwJ3RpYi4yiskLvMKqWrmBgsGOCW6eZLsfNp8uPXwFwDfMZS9Bzg1i63P+NNRKC/a82rEw0jcLyHPKqRIMAp5cfUmtf5fg== X-Google-Smtp-Source: AGHT+IGaXNXzAYvao/9BZf7szEJr5Ubcf/7esCSyzIwr78KmCkHeX5tzJfznBXl73T5AhmnOLYZb X-Received: by 2002:a2e:9785:0:b0:2dc:14d5:4621 with SMTP id y5-20020a2e9785000000b002dc14d54621mr3059717lji.34.1714589471460; Wed, 01 May 2024 11:51:11 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1714589471; cv=pass; d=google.com; s=arc-20160816; b=D4YFRREk4eH3d+w56MAbG9RCrGSC8EacuWE9KUhxh805YsBtKKQBCZfdTYOCmDig8n QwN8wdHZqhOzdzKvUi95rP6PI6p6covdvGSGCbXW06tVrbg6TNjtPydi17QTUCvIeRQG wBSs/SWxC1CD1bRlsTtHC5ItRxAyVEx3RAWMXfb/20uLlT1doJBJ3afYhG96iV/dmToy tDyvYpZN8uRfcn++SojVkvHThQJzdgw0n8ai9fyBySNaaOwCxPJFyGDBebRquLqgIHog 2H1C+4X5VUnQc/bE9YEUWfixqJni8ulovrnv5mTA1J89X48fe3zA2/NAP4qVtV3Khc0r Gazg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=+3ul8eHERhaB1Q0b6GHpgV70AbHXAl/sQjvCYpB41R4=; fh=5C2lsSOJXyuSMZ81JrD8u4iKKMyk14YVWDTVO4bI+rE=; b=PosTaVzS+bs/qrz9/Ty2Uowr4CVTnyCKuGBIPjg9oiDbZk1f7geWsl1UhMDnuNXubz +jTHQtOVyEmf5MpmfiW0lVD6ychrmcNV+7ejZYzMfh5GONYx8rZUyOpAlZEPGd2nO4gS pI4jCe9na2rvQj+ljq21WPHMJdOu/BO4byGwjdyP2oLlQp90FGkSEPZCNUdU0+0Zkwav 2OxgJKHhhOQoWpufZBRIVO8dT5Bh00lnIyZmMpH73D51KU/72Y1SS+yryz23rWtxT7FY hlRkNoWOTlI2PnCE8jHjFn3+qcQZ+OqQbQRTLeKgOPh7Cf4Vs4LPR9yWiT75Exna3/um xSgQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@collabora.com header.s=mail header.b=XQmRb5Dw; arc=pass (i=1 spf=pass spfdomain=collabora.com dkim=pass dkdomain=collabora.com dmarc=pass fromdomain=collabora.com); spf=pass (google.com: domain of linux-kernel+bounces-165696-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-165696-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=collabora.com Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id gn34-20020a1709070d2200b00a5590e074a5si14968247ejc.547.2024.05.01.11.51.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 May 2024 11:51:11 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-165696-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@collabora.com header.s=mail header.b=XQmRb5Dw; arc=pass (i=1 spf=pass spfdomain=collabora.com dkim=pass dkdomain=collabora.com dmarc=pass fromdomain=collabora.com); spf=pass (google.com: domain of linux-kernel+bounces-165696-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-165696-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=collabora.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 08D091F23D97 for ; Wed, 1 May 2024 18:51:11 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 43E2D161304; Wed, 1 May 2024 18:50:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="XQmRb5Dw" Received: from madrid.collaboradmins.com (madrid.collaboradmins.com [46.235.227.194]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD1BC1805A for ; Wed, 1 May 2024 18:50:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.235.227.194 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714589458; cv=none; b=Q7xscaNXC/W//WhBJ950S9l+TLGsW0SCKSu6z7/p2Fnx4mbcH4xNEcf1d8T6mWbohOjacSYkpPnUZSXG7SQ2qW09pSbLFGZxY8lWRczPeBKlVRUoaC1oSY3H6N3hiKdcvrN3K/SKLPWPfytauoxZFN6wU11eO2Bl/d7euM7pFaI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714589458; c=relaxed/simple; bh=fmR6Y2iZ0ul/zqlZu3wJj92Mn58/IbpPaqkgp5e3wv8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=m9tWqwKjz11bCcGcVrxZmCnBIMJ0lXWB7vwACGrpbhOZlEcDy4LDveTvxGWmzTQqr/rHm/YnjnIQ7r3uv3MX528UvJdW36eaOU3ZVTdc4ZW/94eGZTr/gTbHOazSJxHs6njNqT40gEP3O9TVC3Vdj1AM7vHvWARp9wfui8Krpps= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=XQmRb5Dw; arc=none smtp.client-ip=46.235.227.194 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1714589454; bh=fmR6Y2iZ0ul/zqlZu3wJj92Mn58/IbpPaqkgp5e3wv8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XQmRb5DwY/6A+Hdy0xsYDTItkKHOV0yc7BERY054zF/pfTy9fOL0fVVSSUxzFnqbh ywkVJWhBgdSjwUc0DUWjQV4BJxKSN0unimawA8BsY+MMzSDehl+AZVzxeJyuk4iqoK YSpsCtag4JH2h7vSpjMcZc2Me/wqi8IOymL9+Dh7t/DLoP0mjF4u08Oqqi3LPkL/5i I4sLhk3u3d9Hn6bWgGIVke/UIRwYxx5982DfJyJl1w9ANqw09KyV3BeyXJsb8+xoeS r7Koi8K3ip5d5apQrP80ZoDc2WwKDtTrTVxvt2nbY46plHSli5/m1drZ8j6h4MVv6/ OUJZBi0EB2QPA== Received: from localhost.localdomain (cola.collaboradmins.com [195.201.22.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: alarumbe) by madrid.collaboradmins.com (Postfix) with ESMTPSA id 5F4CF37820A4; Wed, 1 May 2024 18:50:54 +0000 (UTC) From: =?UTF-8?q?Adri=C3=A1n=20Larumbe?= To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter Cc: kernel@collabora.com, Adrian Larumbe , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Rob Clark , Tvrtko Ursulin Subject: [PATCH v2 1/1] drm: Add ioctl for querying a DRM device's list of open client PIDs Date: Wed, 1 May 2024 19:50:43 +0100 Message-ID: <20240501185047.3126832-2-adrian.larumbe@collabora.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240501185047.3126832-1-adrian.larumbe@collabora.com> References: <20240501185047.3126832-1-adrian.larumbe@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Up to this day, all fdinfo-based GPU profilers must traverse the entire /proc directory structure to find open DRM clients with fdinfo file descriptors. This is inefficient and time-consuming. This patch adds a new DRM ioctl that allows users to obtain a list of PIDs for clients who have opened the DRM device. Output from the ioctl isn't human-readable, and it's meant to be retrieved only by GPU profilers like gputop and nvtop. Cc: Rob Clark Cc: Tvrtko Ursulin Signed-off-by: Adrián Larumbe --- drivers/gpu/drm/drm_internal.h | 1 + drivers/gpu/drm/drm_ioctl.c | 89 ++++++++++++++++++++++++++++++++++ include/uapi/drm/drm.h | 7 +++ 3 files changed, 97 insertions(+) diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 690505a1f7a5..6f78954cae16 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -243,6 +243,7 @@ static inline void drm_debugfs_encoder_remove(struct drm_encoder *encoder) drm_ioctl_t drm_version; drm_ioctl_t drm_getunique; drm_ioctl_t drm_getclient; +drm_ioctl_t drm_getclients; /* drm_syncobj.c */ void drm_syncobj_open(struct drm_file *file_private); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index e368fc084c77..da7057376581 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -207,6 +207,93 @@ int drm_getclient(struct drm_device *dev, void *data, } } +/* + * Get list of client PIDs who have opened a DRM file + * + * \param dev DRM device we are querying + * \param data IOCTL command input. + * \param file_priv DRM file private. + * + * \return zero on success or a negative number on failure. + * + * Traverses list of open clients for the given DRM device, and + * copies them into userpace as an array of PIDs + */ +int drm_getclients(struct drm_device *dev, void *data, + struct drm_file *file_priv) + +{ + struct drm_get_clients *get_clients = data; + ssize_t size = get_clients->len; + char __user *pid_buf; + ssize_t offset = 0; + int ret = 0; + + /* + * We do not want to show clients of display only devices so + * as to avoid confusing UM GPU profilers + */ + if (!dev->render) { + get_clients->len = 0; + return 0; + } + + /* + * An input size of zero means UM wants to know the size of the PID buffer + * We round it up to the nearest multiple of the page size so that we can have + * some spare headroom in case more clients came in between successive calls + * of this ioctl, and also to simplify parsing of the PIDs buffer, because + * sizeof(pid_t) will hopefully always divide PAGE_SIZE + */ + if (size == 0) { + get_clients->len = + roundup(atomic_read(&dev->open_count) * sizeof(pid_t), PAGE_SIZE); + return 0; + } + + pid_buf = (char *)(void *)get_clients->user_data; + + if (!pid_buf) + return -EINVAL; + + mutex_lock(&dev->filelist_mutex); + list_for_each_entry_reverse(file_priv, &dev->filelist, lhead) { + pid_t pid_num; + + if ((size - offset) < sizeof(pid_t)) + break; + + rcu_read_lock(); + pid_num = pid_vnr(rcu_dereference(file_priv->pid)); + rcu_read_unlock(); + + /* We do not want to return the profiler's PID */ + if (pid_vnr(task_tgid(current)) == pid_num) + continue; + + ret = copy_to_user(pid_buf + offset, &pid_num, sizeof(pid_t)); + if (ret) + break; + + offset += sizeof(pid_t); + } + mutex_unlock(&dev->filelist_mutex); + + if (ret) + return -EFAULT; + + if ((size - offset) >= sizeof(pid_t)) { + pid_t pid_zero = 0; + + ret = copy_to_user(pid_buf + offset, + &pid_zero, sizeof(pid_t)); + if (ret) + return -EFAULT; + } + + return 0; +} + /* * Get statistics information. * @@ -672,6 +759,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER), + + DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENTS, drm_getclients, DRM_RENDER_ALLOW), }; #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE(drm_ioctls) diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 16122819edfe..c47aa9de51ab 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -1024,6 +1024,11 @@ struct drm_crtc_queue_sequence { __u64 user_data; /* user data passed to event */ }; +struct drm_get_clients { + __u64 user_data; + __kernel_size_t len; +}; + #if defined(__cplusplus) } #endif @@ -1236,6 +1241,8 @@ extern "C" { #define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct drm_syncobj_transfer) #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL DRM_IOWR(0xCD, struct drm_syncobj_timeline_array) +#define DRM_IOCTL_GET_CLIENTS DRM_IOWR(0xD1, struct drm_get_clients) + /** * DRM_IOCTL_MODE_GETFB2 - Get framebuffer metadata. * -- 2.44.0