From patchwork Tue Oct 1 02:48:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1991301 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XHj776t8nz1xtj for ; Tue, 1 Oct 2024 12:48:35 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1svSw6-0004mw-0N; Tue, 01 Oct 2024 02:48:26 +0000 Received: from mail-pf1-f179.google.com ([209.85.210.179]) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1svSw4-0004mZ-W1 for kernel-team@lists.ubuntu.com; Tue, 01 Oct 2024 02:48:25 +0000 Received: by mail-pf1-f179.google.com with SMTP id d2e1a72fcca58-71788bfe60eso3732445b3a.1 for ; Mon, 30 Sep 2024 19:48:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727750902; x=1728355702; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LI8AY0GZBzf0Hih1Ufvr709LhTfbKQtgM0Qb3Bhtvmo=; b=p5yufgwkRANFgDuob6UU7Hq5xHcYvDXbZ4zSAVzR4r2y6sVTNHn1QUgEtqLUt1Ttu1 YSS2RNRCmdEETCaCAmykMJnIII/R/C9/lMweUFMoFrhmufgIobfFRcpcSwmEFl2SRNpV BFweyb07WRvgTfKSBIyAZrnpUcH/3Tf4HnqvSVwFVZ3QfeqCCiJlrSo8ZeO1fwXKroYV REg91Mfo8s1HM5MYroD7yMEsEGu2FPcCx4KvOWaK2TAhxtZ8Camqk0wGbMTYzgN2QMYO TbHskzTnoaMwiH+TWXDMhB/WLe/67zDZGXFn0bftxXNmrvcK9C4+3ZsGpVaaC/AJVSal NoQw== X-Gm-Message-State: AOJu0Yz1DGe7v4q8R11MBFThn+F1JSh0Mz0IYMHvU5J2xI9S1fCSCIZq 2D1n2BHwBoOq2+s/bsr5qFor99nsXwfCvrw8SujcFmNshKML2SE1caaT5Q== X-Google-Smtp-Source: AGHT+IHB0+L3QUNjtGO3qQ2SVLGX1vfJCW+30YSBbQzfoxBp/lDRW+/XpSje0fosLUMdKqlbur2gLA== X-Received: by 2002:a05:6a20:c781:b0:1cf:4418:4517 with SMTP id adf61e73a8af0-1d4fa6bf73fmr20367662637.29.1727750902403; Mon, 30 Sep 2024 19:48:22 -0700 (PDT) Received: from yewun.. (125-229-129-140.hinet-ip.hinet.net. [125.229.129.140]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-7e6db2c668asm7277802a12.45.2024.09.30.19.48.20 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Sep 2024 19:48:21 -0700 (PDT) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 1/3][SRU][Unstable][Oracular] drm: Use XArray instead of IDR for minors Date: Tue, 1 Oct 2024 10:48:14 +0800 Message-ID: <20241001024816.111283-2-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241001024816.111283-1-vicamo.yang@canonical.com> References: <20241001024816.111283-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.210.179; envelope-from=vicamo@gmail.com; helo=mail-pf1-f179.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Michał Winiarski BugLink: https://bugs.launchpad.net/bugs/2078773 IDR is deprecated, and since XArray manages its own state with internal locking, it simplifies the locking on DRM side. Additionally, don't use the IRQ-safe variant, since operating on drm minor is not done in IRQ context. Suggested-by: Matthew Wilcox Signed-off-by: Michał Winiarski Acked-by: James Zhu Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20240823163048.2676257-2-michal.winiarski@intel.com Signed-off-by: Christian König (cherry picked from commit 5fbca8b48b3050ae7fb611a8b09af60012ed6de1) Signed-off-by: You-Sheng Yang --- drivers/gpu/drm/drm_drv.c | 63 ++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 93543071a5008..ae675a588a1df 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -54,8 +55,7 @@ MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl"); MODULE_DESCRIPTION("DRM shared core routines"); MODULE_LICENSE("GPL and additional rights"); -static DEFINE_SPINLOCK(drm_minor_lock); -static struct idr drm_minors_idr; +static DEFINE_XARRAY_ALLOC(drm_minors_xa); /* * If the drm core fails to init for whatever reason, @@ -101,26 +101,23 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev, static void drm_minor_alloc_release(struct drm_device *dev, void *data) { struct drm_minor *minor = data; - unsigned long flags; WARN_ON(dev != minor->dev); put_device(minor->kdev); - if (minor->type == DRM_MINOR_ACCEL) { + if (minor->type == DRM_MINOR_ACCEL) accel_minor_remove(minor->index); - } else { - spin_lock_irqsave(&drm_minor_lock, flags); - idr_remove(&drm_minors_idr, minor->index); - spin_unlock_irqrestore(&drm_minor_lock, flags); - } + else + xa_erase(&drm_minors_xa, minor->index); } +#define DRM_MINOR_LIMIT(t) ({ typeof(t) _t = (t); XA_LIMIT(64 * _t, 64 * _t + 63); }) + static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type) { struct drm_minor *minor; - unsigned long flags; - int r; + int index, r; minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL); if (!minor) @@ -129,24 +126,17 @@ static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type) minor->type = type; minor->dev = dev; - idr_preload(GFP_KERNEL); if (type == DRM_MINOR_ACCEL) { r = accel_minor_alloc(); + index = r; } else { - spin_lock_irqsave(&drm_minor_lock, flags); - r = idr_alloc(&drm_minors_idr, - NULL, - 64 * type, - 64 * (type + 1), - GFP_NOWAIT); - spin_unlock_irqrestore(&drm_minor_lock, flags); + r = xa_alloc(&drm_minors_xa, &index, NULL, DRM_MINOR_LIMIT(type), GFP_KERNEL); } - idr_preload_end(); if (r < 0) return r; - minor->index = r; + minor->index = index; r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor); if (r) @@ -163,7 +153,7 @@ static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type) static int drm_minor_register(struct drm_device *dev, enum drm_minor_type type) { struct drm_minor *minor; - unsigned long flags; + void *entry; int ret; DRM_DEBUG("\n"); @@ -189,9 +179,12 @@ static int drm_minor_register(struct drm_device *dev, enum drm_minor_type type) if (minor->type == DRM_MINOR_ACCEL) { accel_minor_replace(minor, minor->index); } else { - spin_lock_irqsave(&drm_minor_lock, flags); - idr_replace(&drm_minors_idr, minor, minor->index); - spin_unlock_irqrestore(&drm_minor_lock, flags); + entry = xa_store(&drm_minors_xa, minor->index, minor, GFP_KERNEL); + if (xa_is_err(entry)) { + ret = xa_err(entry); + goto err_debugfs; + } + WARN_ON(entry); } DRM_DEBUG("new minor registered %d\n", minor->index); @@ -205,20 +198,16 @@ static int drm_minor_register(struct drm_device *dev, enum drm_minor_type type) static void drm_minor_unregister(struct drm_device *dev, enum drm_minor_type type) { struct drm_minor *minor; - unsigned long flags; minor = *drm_minor_get_slot(dev, type); if (!minor || !device_is_registered(minor->kdev)) return; /* replace @minor with NULL so lookups will fail from now on */ - if (minor->type == DRM_MINOR_ACCEL) { + if (minor->type == DRM_MINOR_ACCEL) accel_minor_replace(NULL, minor->index); - } else { - spin_lock_irqsave(&drm_minor_lock, flags); - idr_replace(&drm_minors_idr, NULL, minor->index); - spin_unlock_irqrestore(&drm_minor_lock, flags); - } + else + xa_store(&drm_minors_xa, minor->index, NULL, GFP_KERNEL); device_del(minor->kdev); dev_set_drvdata(minor->kdev, NULL); /* safety belt */ @@ -237,13 +226,12 @@ static void drm_minor_unregister(struct drm_device *dev, enum drm_minor_type typ struct drm_minor *drm_minor_acquire(unsigned int minor_id) { struct drm_minor *minor; - unsigned long flags; - spin_lock_irqsave(&drm_minor_lock, flags); - minor = idr_find(&drm_minors_idr, minor_id); + xa_lock(&drm_minors_xa); + minor = xa_load(&drm_minors_xa, minor_id); if (minor) drm_dev_get(minor->dev); - spin_unlock_irqrestore(&drm_minor_lock, flags); + xa_unlock(&drm_minors_xa); if (!minor) { return ERR_PTR(-ENODEV); @@ -1071,7 +1059,7 @@ static void drm_core_exit(void) unregister_chrdev(DRM_MAJOR, "drm"); debugfs_remove(drm_debugfs_root); drm_sysfs_destroy(); - idr_destroy(&drm_minors_idr); + WARN_ON(!xa_empty(&drm_minors_xa)); drm_connector_ida_destroy(); } @@ -1080,7 +1068,6 @@ static int __init drm_core_init(void) int ret; drm_connector_ida_init(); - idr_init(&drm_minors_idr); drm_memcpy_init_early(); ret = drm_sysfs_init(); From patchwork Tue Oct 1 02:48:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1991302 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XHj795Pfdz1xtg for ; Tue, 1 Oct 2024 12:48:37 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1svSw9-0004oC-6N; Tue, 01 Oct 2024 02:48:29 +0000 Received: from mail-pf1-f174.google.com ([209.85.210.174]) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1svSw6-0004mu-RF for kernel-team@lists.ubuntu.com; Tue, 01 Oct 2024 02:48:27 +0000 Received: by mail-pf1-f174.google.com with SMTP id d2e1a72fcca58-71957eb256bso4548943b3a.3 for ; Mon, 30 Sep 2024 19:48:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727750904; x=1728355704; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RTVp+INk1GmfMH+L/mzDAt0qwvj94kun6qUX+42INjI=; b=m/wP3UA/NmlHXF2b0rStmMie44fInDe+KvLHJ3aTpIIOQW23wEZtTMbn4c9AiOYOhx 3pKYKDphYI6ElnXxaLZmIRpFMZL9aKMwO4SN96oPuLvry1gvyMLbiEKX4w7wy+Cmg8fm 3EKUWcmhB2JdHsiYqOVcBb5c9/4l4STkZjuAvwsGezdMwbsb6Oif+abUJ0J6a4UDlHlq n3LLJYkdjDUxY2i80Q7RzIhGB8LcySGJuJTnpVjb+fLDaU7TmzjN2GXSfEy+fBwCmi1Y dBv0/3CicZZ6otLkb2Rqv2kcJnYscRv1q1j4GFzSwCT4NzUUqWqlvDxUSX7b2iTFvy5N O8Pg== X-Gm-Message-State: AOJu0Yw0yUrb678IWXT3a3UsDb0BvtWDA9OyVRps0Fjn7dbq7a7I2seF JRlh1O6P2URb+cZDOvUPKzuDQgtov78rMp5y9l/a5T+GV8FYDraxHNcnQQ== X-Google-Smtp-Source: AGHT+IGHLSHmT8ghWLXSNAe65o7TTNtgu5iDMivp/i/oXdnERmuGFay7r1gghOHUhlJwIlEv6DXjPw== X-Received: by 2002:a05:6a00:997:b0:717:85d4:939c with SMTP id d2e1a72fcca58-71b26076b90mr24628755b3a.23.1727750903994; Mon, 30 Sep 2024 19:48:23 -0700 (PDT) Received: from yewun.. (125-229-129-140.hinet-ip.hinet.net. [125.229.129.140]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-7e6db2c668asm7277802a12.45.2024.09.30.19.48.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Sep 2024 19:48:23 -0700 (PDT) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 2/3][SRU][Unstable][Oracular] accel: Use XArray instead of IDR for minors Date: Tue, 1 Oct 2024 10:48:15 +0800 Message-ID: <20241001024816.111283-3-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241001024816.111283-1-vicamo.yang@canonical.com> References: <20241001024816.111283-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.210.174; envelope-from=vicamo@gmail.com; helo=mail-pf1-f174.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Michał Winiarski BugLink: https://bugs.launchpad.net/bugs/2078773 Accel minor management is based on DRM (and is also using struct drm_minor internally), since DRM is using XArray for minors, it makes sense to also convert accel. As the two implementations are identical (only difference being the underlying xarray), move the accel_minor_* functionality to DRM. Signed-off-by: Michał Winiarski Acked-by: James Zhu Acked-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/20240823163048.2676257-3-michal.winiarski@intel.com Signed-off-by: Christian König (cherry picked from commit 45c4d994b82b08f0ce5eb50f8da29379c92a391e) Signed-off-by: You-Sheng Yang --- drivers/accel/drm_accel.c | 110 +++------------------------------ drivers/gpu/drm/drm_drv.c | 66 ++++++++++---------- drivers/gpu/drm/drm_file.c | 2 +- drivers/gpu/drm/drm_internal.h | 4 -- include/drm/drm_accel.h | 18 +----- include/drm/drm_file.h | 5 ++ 6 files changed, 47 insertions(+), 158 deletions(-) diff --git a/drivers/accel/drm_accel.c b/drivers/accel/drm_accel.c index 16c3edb8c46ee..aa826033b0ceb 100644 --- a/drivers/accel/drm_accel.c +++ b/drivers/accel/drm_accel.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include @@ -18,8 +18,7 @@ #include #include -static DEFINE_SPINLOCK(accel_minor_lock); -static struct idr accel_minors_idr; +DEFINE_XARRAY_ALLOC(accel_minors_xa); static struct dentry *accel_debugfs_root; @@ -117,99 +116,6 @@ void accel_set_device_instance_params(struct device *kdev, int index) kdev->type = &accel_sysfs_device_minor; } -/** - * accel_minor_alloc() - Allocates a new accel minor - * - * This function access the accel minors idr and allocates from it - * a new id to represent a new accel minor - * - * Return: A new id on success or error code in case idr_alloc failed - */ -int accel_minor_alloc(void) -{ - unsigned long flags; - int r; - - spin_lock_irqsave(&accel_minor_lock, flags); - r = idr_alloc(&accel_minors_idr, NULL, 0, ACCEL_MAX_MINORS, GFP_NOWAIT); - spin_unlock_irqrestore(&accel_minor_lock, flags); - - return r; -} - -/** - * accel_minor_remove() - Remove an accel minor - * @index: The minor id to remove. - * - * This function access the accel minors idr and removes from - * it the member with the id that is passed to this function. - */ -void accel_minor_remove(int index) -{ - unsigned long flags; - - spin_lock_irqsave(&accel_minor_lock, flags); - idr_remove(&accel_minors_idr, index); - spin_unlock_irqrestore(&accel_minor_lock, flags); -} - -/** - * accel_minor_replace() - Replace minor pointer in accel minors idr. - * @minor: Pointer to the new minor. - * @index: The minor id to replace. - * - * This function access the accel minors idr structure and replaces the pointer - * that is associated with an existing id. Because the minor pointer can be - * NULL, we need to explicitly pass the index. - * - * Return: 0 for success, negative value for error - */ -void accel_minor_replace(struct drm_minor *minor, int index) -{ - unsigned long flags; - - spin_lock_irqsave(&accel_minor_lock, flags); - idr_replace(&accel_minors_idr, minor, index); - spin_unlock_irqrestore(&accel_minor_lock, flags); -} - -/* - * Looks up the given minor-ID and returns the respective DRM-minor object. The - * refence-count of the underlying device is increased so you must release this - * object with accel_minor_release(). - * - * The object can be only a drm_minor that represents an accel device. - * - * As long as you hold this minor, it is guaranteed that the object and the - * minor->dev pointer will stay valid! However, the device may get unplugged and - * unregistered while you hold the minor. - */ -static struct drm_minor *accel_minor_acquire(unsigned int minor_id) -{ - struct drm_minor *minor; - unsigned long flags; - - spin_lock_irqsave(&accel_minor_lock, flags); - minor = idr_find(&accel_minors_idr, minor_id); - if (minor) - drm_dev_get(minor->dev); - spin_unlock_irqrestore(&accel_minor_lock, flags); - - if (!minor) { - return ERR_PTR(-ENODEV); - } else if (drm_dev_is_unplugged(minor->dev)) { - drm_dev_put(minor->dev); - return ERR_PTR(-ENODEV); - } - - return minor; -} - -static void accel_minor_release(struct drm_minor *minor) -{ - drm_dev_put(minor->dev); -} - /** * accel_open - open method for ACCEL file * @inode: device inode @@ -227,7 +133,7 @@ int accel_open(struct inode *inode, struct file *filp) struct drm_minor *minor; int retcode; - minor = accel_minor_acquire(iminor(inode)); + minor = drm_minor_acquire(&accel_minors_xa, iminor(inode)); if (IS_ERR(minor)) return PTR_ERR(minor); @@ -246,7 +152,7 @@ int accel_open(struct inode *inode, struct file *filp) err_undo: atomic_dec(&dev->open_count); - accel_minor_release(minor); + drm_minor_release(minor); return retcode; } EXPORT_SYMBOL_GPL(accel_open); @@ -257,7 +163,7 @@ static int accel_stub_open(struct inode *inode, struct file *filp) struct drm_minor *minor; int err; - minor = accel_minor_acquire(iminor(inode)); + minor = drm_minor_acquire(&accel_minors_xa, iminor(inode)); if (IS_ERR(minor)) return PTR_ERR(minor); @@ -274,7 +180,7 @@ static int accel_stub_open(struct inode *inode, struct file *filp) err = 0; out: - accel_minor_release(minor); + drm_minor_release(minor); return err; } @@ -290,15 +196,13 @@ void accel_core_exit(void) unregister_chrdev(ACCEL_MAJOR, "accel"); debugfs_remove(accel_debugfs_root); accel_sysfs_destroy(); - idr_destroy(&accel_minors_idr); + WARN_ON(!xa_empty(&accel_minors_xa)); } int __init accel_core_init(void) { int ret; - idr_init(&accel_minors_idr); - ret = accel_sysfs_init(); if (ret < 0) { DRM_ERROR("Cannot create ACCEL class: %d\n", ret); diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index ae675a588a1df..7e0fa5a2a3182 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -55,7 +55,7 @@ MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl"); MODULE_DESCRIPTION("DRM shared core routines"); MODULE_LICENSE("GPL and additional rights"); -static DEFINE_XARRAY_ALLOC(drm_minors_xa); +DEFINE_XARRAY_ALLOC(drm_minors_xa); /* * If the drm core fails to init for whatever reason, @@ -83,6 +83,18 @@ DEFINE_STATIC_SRCU(drm_unplug_srcu); * registered and unregistered dynamically according to device-state. */ +static struct xarray *drm_minor_get_xa(enum drm_minor_type type) +{ + if (type == DRM_MINOR_PRIMARY || type == DRM_MINOR_RENDER) + return &drm_minors_xa; +#if IS_ENABLED(CONFIG_DRM_ACCEL) + else if (type == DRM_MINOR_ACCEL) + return &accel_minors_xa; +#endif + else + return ERR_PTR(-EOPNOTSUPP); +} + static struct drm_minor **drm_minor_get_slot(struct drm_device *dev, enum drm_minor_type type) { @@ -106,18 +118,18 @@ static void drm_minor_alloc_release(struct drm_device *dev, void *data) put_device(minor->kdev); - if (minor->type == DRM_MINOR_ACCEL) - accel_minor_remove(minor->index); - else - xa_erase(&drm_minors_xa, minor->index); + xa_erase(drm_minor_get_xa(minor->type), minor->index); } -#define DRM_MINOR_LIMIT(t) ({ typeof(t) _t = (t); XA_LIMIT(64 * _t, 64 * _t + 63); }) +#define DRM_MINOR_LIMIT(t) ({ \ + typeof(t) _t = (t); \ + _t == DRM_MINOR_ACCEL ? XA_LIMIT(0, ACCEL_MAX_MINORS) : XA_LIMIT(64 * _t, 64 * _t + 63); \ +}) static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type) { struct drm_minor *minor; - int index, r; + int r; minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL); if (!minor) @@ -126,18 +138,11 @@ static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type) minor->type = type; minor->dev = dev; - if (type == DRM_MINOR_ACCEL) { - r = accel_minor_alloc(); - index = r; - } else { - r = xa_alloc(&drm_minors_xa, &index, NULL, DRM_MINOR_LIMIT(type), GFP_KERNEL); - } - + r = xa_alloc(drm_minor_get_xa(type), &minor->index, + NULL, DRM_MINOR_LIMIT(type), GFP_KERNEL); if (r < 0) return r; - minor->index = index; - r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor); if (r) return r; @@ -176,16 +181,12 @@ static int drm_minor_register(struct drm_device *dev, enum drm_minor_type type) goto err_debugfs; /* replace NULL with @minor so lookups will succeed from now on */ - if (minor->type == DRM_MINOR_ACCEL) { - accel_minor_replace(minor, minor->index); - } else { - entry = xa_store(&drm_minors_xa, minor->index, minor, GFP_KERNEL); - if (xa_is_err(entry)) { - ret = xa_err(entry); - goto err_debugfs; - } - WARN_ON(entry); + entry = xa_store(drm_minor_get_xa(type), minor->index, minor, GFP_KERNEL); + if (xa_is_err(entry)) { + ret = xa_err(entry); + goto err_debugfs; } + WARN_ON(entry); DRM_DEBUG("new minor registered %d\n", minor->index); return 0; @@ -204,10 +205,7 @@ static void drm_minor_unregister(struct drm_device *dev, enum drm_minor_type typ return; /* replace @minor with NULL so lookups will fail from now on */ - if (minor->type == DRM_MINOR_ACCEL) - accel_minor_replace(NULL, minor->index); - else - xa_store(&drm_minors_xa, minor->index, NULL, GFP_KERNEL); + xa_store(drm_minor_get_xa(type), minor->index, NULL, GFP_KERNEL); device_del(minor->kdev); dev_set_drvdata(minor->kdev, NULL); /* safety belt */ @@ -223,15 +221,15 @@ static void drm_minor_unregister(struct drm_device *dev, enum drm_minor_type typ * minor->dev pointer will stay valid! However, the device may get unplugged and * unregistered while you hold the minor. */ -struct drm_minor *drm_minor_acquire(unsigned int minor_id) +struct drm_minor *drm_minor_acquire(struct xarray *minor_xa, unsigned int minor_id) { struct drm_minor *minor; - xa_lock(&drm_minors_xa); - minor = xa_load(&drm_minors_xa, minor_id); + xa_lock(minor_xa); + minor = xa_load(minor_xa, minor_id); if (minor) drm_dev_get(minor->dev); - xa_unlock(&drm_minors_xa); + xa_unlock(minor_xa); if (!minor) { return ERR_PTR(-ENODEV); @@ -1024,7 +1022,7 @@ static int drm_stub_open(struct inode *inode, struct file *filp) DRM_DEBUG("\n"); - minor = drm_minor_acquire(iminor(inode)); + minor = drm_minor_acquire(&drm_minors_xa, iminor(inode)); if (IS_ERR(minor)) return PTR_ERR(minor); diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index 714e42b051080..f917b259b3342 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -364,7 +364,7 @@ int drm_open(struct inode *inode, struct file *filp) struct drm_minor *minor; int retcode; - minor = drm_minor_acquire(iminor(inode)); + minor = drm_minor_acquire(&drm_minors_xa, iminor(inode)); if (IS_ERR(minor)) return PTR_ERR(minor); diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index 690505a1f7a5d..12acf44c4e240 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -81,10 +81,6 @@ void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv); void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, uint32_t handle); -/* drm_drv.c */ -struct drm_minor *drm_minor_acquire(unsigned int minor_id); -void drm_minor_release(struct drm_minor *minor); - /* drm_managed.c */ void drm_managed_release(struct drm_device *dev); void drmm_add_final_kfree(struct drm_device *dev, void *container); diff --git a/include/drm/drm_accel.h b/include/drm/drm_accel.h index f4d3784b1dce0..8867ce0be94cd 100644 --- a/include/drm/drm_accel.h +++ b/include/drm/drm_accel.h @@ -51,11 +51,10 @@ #if IS_ENABLED(CONFIG_DRM_ACCEL) +extern struct xarray accel_minors_xa; + void accel_core_exit(void); int accel_core_init(void); -void accel_minor_remove(int index); -int accel_minor_alloc(void); -void accel_minor_replace(struct drm_minor *minor, int index); void accel_set_device_instance_params(struct device *kdev, int index); int accel_open(struct inode *inode, struct file *filp); void accel_debugfs_init(struct drm_device *dev); @@ -73,19 +72,6 @@ static inline int __init accel_core_init(void) return 0; } -static inline void accel_minor_remove(int index) -{ -} - -static inline int accel_minor_alloc(void) -{ - return -EOPNOTSUPP; -} - -static inline void accel_minor_replace(struct drm_minor *minor, int index) -{ -} - static inline void accel_set_device_instance_params(struct device *kdev, int index) { } diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index ab230d3af138d..8c0030c773081 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -45,6 +45,8 @@ struct drm_printer; struct device; struct file; +extern struct xarray drm_minors_xa; + /* * FIXME: Not sure we want to have drm_minor here in the end, but to avoid * header include loops we need it here for now. @@ -434,6 +436,9 @@ static inline bool drm_is_accel_client(const struct drm_file *file_priv) void drm_file_update_pid(struct drm_file *); +struct drm_minor *drm_minor_acquire(struct xarray *minors_xa, unsigned int minor_id); +void drm_minor_release(struct drm_minor *minor); + int drm_open(struct inode *inode, struct file *filp); int drm_open_helper(struct file *filp, struct drm_minor *minor); ssize_t drm_read(struct file *filp, char __user *buffer, From patchwork Tue Oct 1 02:48:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1991303 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XHj7D4nghz1xtg for ; Tue, 1 Oct 2024 12:48:40 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1svSwC-0004qi-Hm; Tue, 01 Oct 2024 02:48:32 +0000 Received: from mail-pl1-f173.google.com ([209.85.214.173]) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1svSwA-0004oJ-Ck for kernel-team@lists.ubuntu.com; Tue, 01 Oct 2024 02:48:30 +0000 Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-20b84bfbdfcso11051925ad.0 for ; Mon, 30 Sep 2024 19:48:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727750908; x=1728355708; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CsjBQrLM2bu1QWLzrzKW41XSnjnxDcRUEHz2rcwFPzg=; b=HtQcr/dgNs4GdUvySAloBdJ+BlPnfJv3dRHKkUe/OwJDH+vVnhUqcLRsHdy2uUiAsv SRyVp7r2BC8c0ZdNAJSq1l5BU10GFZlKbYOFXcZrSdLX42l8VSZog7WPpw+RxsKAK9q7 R21qP+ku85RmqKkaNWqgNXCstqCKm72107fU3yR+s7BLXc8Y+w65Llj5/GwcmfM4aOXG OsRH7RNkFpC/W1Gj06oRbQGweEMe/NIB4aM7WAjymhODeDe3BThENt0Xb6gV+FuOK0Ls CrpER8FT3/WJSGbL2FwK8ybfmrC1f7H2eE1/T4CN+C+HIprylSk0aSVWcpSQHwCAIMsV Mtmg== X-Gm-Message-State: AOJu0YzZ8Q9geX857kfOpPh4mGbmxF6kmPTVt+tuGbTpvrDvcBma8egC reozSHn8PTb1c3L/RUBBPQYxs25mTZeFoBoAs3Z0xuXY0lDNJ3Z6ZKIg0A== X-Google-Smtp-Source: AGHT+IFqSYySJLezABc2W0CUMDddfHB9GB2h+EnbW8PeOmoQa4w7SCYUMXDL+cDdfsYPbk1g8PWUyA== X-Received: by 2002:a17:902:f688:b0:206:892c:b758 with SMTP id d9443c01a7336-20ba9ed2162mr26833835ad.13.1727750907778; Mon, 30 Sep 2024 19:48:27 -0700 (PDT) Received: from yewun.. (125-229-129-140.hinet-ip.hinet.net. [125.229.129.140]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-7e6db2c668asm7277802a12.45.2024.09.30.19.48.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Sep 2024 19:48:27 -0700 (PDT) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 3/3][SRU][Unstable][Oracular] drm: Expand max DRM device number to full MINORBITS Date: Tue, 1 Oct 2024 10:48:16 +0800 Message-ID: <20241001024816.111283-4-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241001024816.111283-1-vicamo.yang@canonical.com> References: <20241001024816.111283-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.214.173; envelope-from=vicamo@gmail.com; helo=mail-pl1-f173.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Michał Winiarski BugLink: https://bugs.launchpad.net/bugs/2078773 Having a limit of 64 DRM devices is not good enough for modern world where we have multi-GPU servers, SR-IOV virtual functions and virtual devices used for testing. Let's utilize full minor range for DRM devices. To avoid regressing the existing userspace, we're still maintaining the numbering scheme where 0-63 is used for primary, 64-127 is reserved (formerly for control) and 128-191 is used for render. For minors >= 192, we're allocating minors dynamically on a first-come, first-served basis. Signed-off-by: Michał Winiarski Link: https://patchwork.freedesktop.org/patch/msgid/20240823163048.2676257-4-michal.winiarski@intel.com Acked-by: James Zhu Acked-by: Christian König Signed-off-by: Christian König (cherry picked from commit 071d583e01c88272f6ff216d4f867f8f35e94d7d) Signed-off-by: You-Sheng Yang --- drivers/gpu/drm/drm_drv.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 7e0fa5a2a3182..c734e6a1c4ce2 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -121,10 +121,19 @@ static void drm_minor_alloc_release(struct drm_device *dev, void *data) xa_erase(drm_minor_get_xa(minor->type), minor->index); } +/* + * DRM used to support 64 devices, for backwards compatibility we need to maintain the + * minor allocation scheme where minors 0-63 are primary nodes, 64-127 are control nodes, + * and 128-191 are render nodes. + * After reaching the limit, we're allocating minors dynamically - first-come, first-serve. + * Accel nodes are using a distinct major, so the minors are allocated in continuous 0-MAX + * range. + */ #define DRM_MINOR_LIMIT(t) ({ \ typeof(t) _t = (t); \ _t == DRM_MINOR_ACCEL ? XA_LIMIT(0, ACCEL_MAX_MINORS) : XA_LIMIT(64 * _t, 64 * _t + 63); \ }) +#define DRM_EXTENDED_MINOR_LIMIT XA_LIMIT(192, (1 << MINORBITS) - 1) static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type) { @@ -140,6 +149,9 @@ static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type) r = xa_alloc(drm_minor_get_xa(type), &minor->index, NULL, DRM_MINOR_LIMIT(type), GFP_KERNEL); + if (r == -EBUSY && (type == DRM_MINOR_PRIMARY || type == DRM_MINOR_RENDER)) + r = xa_alloc(&drm_minors_xa, &minor->index, + NULL, DRM_EXTENDED_MINOR_LIMIT, GFP_KERNEL); if (r < 0) return r;