From patchwork Wed Nov 2 20:34:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oded Gabbay X-Patchwork-Id: 14478 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp130158wru; Wed, 2 Nov 2022 13:40:04 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6WQYvMgb0GbUZTKu8dz7XA2VAju1hA0Kr2lMQ55PoRNQPH4VpWCdFJohQFKQWB+pw4Ol9w X-Received: by 2002:aa7:c718:0:b0:462:ff35:95dc with SMTP id i24-20020aa7c718000000b00462ff3595dcmr25317159edq.32.1667421604133; Wed, 02 Nov 2022 13:40:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1667421604; cv=none; d=google.com; s=arc-20160816; b=dksE3A7ZUsSRBJvM4czyPtLRQHPyNG4YBa4gw8bN7yn7678GV4SuYo9Dw5NueaIMd8 jIhFC+AS0veMvzB/mPGPChi4IYeO+HtvMuoF8KRAdbQemeUxX3ock5AethuaUFG2jpcP shoawVXtB9vj0oL+evLVM77YHUNiDl1Hh5rW3ObZSCerbgzsvK40c43ZD9izRwAsxc9G soevXscZV9sZbFCLL4cdqsBUsufeea1ek9pXD096q4kHT5o1P8RW3hqtgtkUBSpM9M2Z 0xW8CkbxWogUvdXoKlBRBoaVF0oOxo2UBTbiAZ3cjdziimYA2V3BdcFz+gaYmNuKjwWm aGDg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=GVJlYlSkAseNvLzjIQaomJlHHi+SClvNR9wZWGE/lQA=; b=kJDi5adWQoyv8VtxqwS78o5qCK+ea6tX+ZRYcNx3DcB9EcG6eAulu5ucOKfdYQjosc 5uMsRngjNtdxZ46W5h3A2KNf+I3hedXGESTQ+XyaFySzBFYWJauKt7PB2RC1wlmQDzEM +ElKw6CGx4SRQH1HlknnWT0S9jNpTmDxLxC/F+QkM/Ye04ATftNfNQX2rRZxPEwFBd8N QvCpPGMUZCrEA1rYFU/OATIPns1w59JTEtxRmMdjVKBx11k+AGjs0vosSqSmcloKYK9I +MusZUUxxOIaKtrR3u7otsWLlqTtEVFGanti+jfaNLxVWhvecCGMEQ+ZjTlr/rgNXRVZ 0eCQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=vCJ8tsAO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id d9-20020a50ea89000000b00461c531d8casi14941227edo.305.2022.11.02.13.39.28; Wed, 02 Nov 2022 13:40:04 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=vCJ8tsAO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231253AbiKBUea (ORCPT + 99 others); Wed, 2 Nov 2022 16:34:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59884 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231224AbiKBUeY (ORCPT ); Wed, 2 Nov 2022 16:34:24 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A17CC6400 for ; Wed, 2 Nov 2022 13:34:22 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 56C1FB823C4 for ; Wed, 2 Nov 2022 20:34:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B4E80C433B5; Wed, 2 Nov 2022 20:34:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1667421260; bh=iJP0+58bg6H21ZtOSo1JNsjuytNpyr5vbaN+xzNBUTg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vCJ8tsAOc9AwtQU93KtI6qVLtY0NAR7NDFFnFqFRzqJ5xGQJw1/wuUpvL/kJNh5gV lJLEPv91FtZbeDA9clLnWwWSiqKJSeC2jCWYcJBmjgyO7GOIqsjDKvCyXWq7h98SH4 8qwutIHyRRtnJl0MS+ZF12lS3pVTlN5pZkPGk6iWdVzIia8Jy6U9qlP6kMHT2YdLlL ySnldnYE7n3mwcC7GPLOm/4EeHa7nja6+9xCJeD8Zdd6eX4fpnmcFJ7uJcfB2gPj+n DBAGFXJ4T5DcTaJjcsE3IIj+OSpWQPuRQu7ydTZ5q1fyuoaHadtgJKJ8EcNxQva/04 mgETA+skfPIDw== From: Oded Gabbay To: David Airlie , Daniel Vetter , Arnd Bergmann , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Jason Gunthorpe , John Hubbard , Alex Deucher Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Yuji Ishikawa , Jiho Chu , Daniel Stone , Tvrtko Ursulin , Jeffrey Hugo , Christoph Hellwig , Kevin Hilman , Jagan Teki , Jacek Lawrynowicz , Maciej Kwapulinski Subject: [RFC PATCH v2 1/3] drivers/accel: define kconfig and register a new major Date: Wed, 2 Nov 2022 22:34:03 +0200 Message-Id: <20221102203405.1797491-2-ogabbay@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221102203405.1797491-1-ogabbay@kernel.org> References: <20221102203405.1797491-1-ogabbay@kernel.org> MIME-Version: 1.0 X-Spam-Status: No, score=-8.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1748418275776090076?= X-GMAIL-MSGID: =?utf-8?q?1748418275776090076?= Add a new Kconfig for the accel subsystem. The Kconfig currently contains only the basic CONFIG_ACCEL option that will be used to decide whether to compile the accel registration code. That code will be called directly from the DRM core code. The accelerator devices will be exposed to the user space with a new, dedicated major number - 261. The accel init function registers the new major number as a char device and create corresponding sysfs and debugfs root entries, similar to what is done in DRM init function. I added a new header called drm_accel.h to include/drm/, that will hold the prototypes of the accel_drv.c functions. In case CONFIG_ACCEL is set to 'N', that header will contain empty inline implementations of those functions, to allow DRM core code to compile successfully without dependency on CONFIG_ACCEL. I Updated the MAINTAINERS file accordingly with the newly added folder and I have taken the liberty to appropriate the dri-devel mailing list and the dri-devel IRC channel for the accel subsystem. Signed-off-by: Oded Gabbay --- Changes in v2: - Created accel_drv.c that will hold the accel framework core functions, instead of embedding the code inside drm core functions. - Created drm/drm_accel.h - Removed all #ifdef CONFIG_ACCEL from drm_drv.c Documentation/admin-guide/devices.txt | 5 ++ MAINTAINERS | 8 ++ drivers/Kconfig | 2 + drivers/Makefile | 3 + drivers/accel/Kconfig | 24 ++++++ drivers/accel/Makefile | 10 +++ drivers/accel/accel_drv.c | 112 ++++++++++++++++++++++++++ include/drm/drm_accel.h | 31 +++++++ 8 files changed, 195 insertions(+) create mode 100644 drivers/accel/Kconfig create mode 100644 drivers/accel/Makefile create mode 100644 drivers/accel/accel_drv.c create mode 100644 include/drm/drm_accel.h -- 2.25.1 diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt index 9764d6edb189..06c525e01ea5 100644 --- a/Documentation/admin-guide/devices.txt +++ b/Documentation/admin-guide/devices.txt @@ -3080,6 +3080,11 @@ ... 255 = /dev/osd255 256th OSD Device + 261 char Compute Acceleration Devices + 0 = /dev/accel/accel0 First acceleration device + 1 = /dev/accel/accel1 Second acceleration device + ... + 384-511 char RESERVED FOR DYNAMIC ASSIGNMENT Character devices that request a dynamic allocation of major number will take numbers starting from 511 and downward, diff --git a/MAINTAINERS b/MAINTAINERS index ab07cf28844e..9b34f756e343 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6825,6 +6825,14 @@ F: include/drm/drm* F: include/linux/vga* F: include/uapi/drm/drm* +DRM COMPUTE ACCELERATORS DRIVERS AND FRAMEWORK +M: Oded Gabbay +L: dri-devel@lists.freedesktop.org +S: Maintained +C: irc://irc.oftc.net/dri-devel +T: git https://git.kernel.org/pub/scm/linux/kernel/git/ogabbay/accel.git +F: drivers/accel/ + DRM DRIVERS FOR ALLWINNER A10 M: Maxime Ripard M: Chen-Yu Tsai diff --git a/drivers/Kconfig b/drivers/Kconfig index 19ee995bd0ae..968bd0a6fd78 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -99,6 +99,8 @@ source "drivers/media/Kconfig" source "drivers/video/Kconfig" +source "drivers/accel/Kconfig" + source "sound/Kconfig" source "drivers/hid/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index bdf1c66141c9..658199dcee96 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -62,6 +62,9 @@ obj-y += iommu/ # gpu/ comes after char for AGP vs DRM startup and after iommu obj-y += gpu/ +# accel is part of drm so it must come after gpu +obj-$(CONFIG_ACCEL) += accel/ + obj-$(CONFIG_CONNECTOR) += connector/ # i810fb and intelfb depend on char/agp/ diff --git a/drivers/accel/Kconfig b/drivers/accel/Kconfig new file mode 100644 index 000000000000..282ea24f90c5 --- /dev/null +++ b/drivers/accel/Kconfig @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Compute Acceleration device configuration +# +# This framework provides support for compute acceleration devices, such +# as, but not limited to, Machine-Learning and Deep-Learning acceleration +# devices +# +menuconfig ACCEL + tristate "Compute Acceleration Framework" + depends on DRM + help + Framework for device drivers of compute acceleration devices, such + as, but not limited to, Machine-Learning and Deep-Learning + acceleration devices. + If you say Y here, you need to select the module that's right for + your acceleration device from the list below. + This framework is integrated with the DRM subsystem as compute + accelerators and GPUs share a lot in common and can use almost the + same infrastructure code. + Having said that, acceleration devices will have a different + major number than GPUs, and will be exposed to user-space using + different device files, called accel/accel* (in /dev, sysfs + and debugfs) diff --git a/drivers/accel/Makefile b/drivers/accel/Makefile new file mode 100644 index 000000000000..b5b7d812a8ef --- /dev/null +++ b/drivers/accel/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Makefile for the accel framework. This framework provides support for +# compute acceleration devices, such as, but not limited to, Machine-Learning +# and Deep-Learning acceleration devices + +accel-y := \ + accel_drv.o + +obj-$(CONFIG_ACCEL) += accel.o diff --git a/drivers/accel/accel_drv.c b/drivers/accel/accel_drv.c new file mode 100644 index 000000000000..6132765ea054 --- /dev/null +++ b/drivers/accel/accel_drv.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Copyright 2022 HabanaLabs, Ltd. + * All Rights Reserved. + * + */ + +#include +#include +#include + +#include +#include +#include + +static struct dentry *accel_debugfs_root; +struct class *accel_class; + +static char *accel_devnode(struct device *dev, umode_t *mode) +{ + return kasprintf(GFP_KERNEL, "accel/%s", dev_name(dev)); +} + +static CLASS_ATTR_STRING(accel_version, 0444, "accel 1.0.0 20221018"); + +/** + * accel_sysfs_init - initialize sysfs helpers + * + * This is used to create the ACCEL class, which is the implicit parent of any + * other top-level ACCEL sysfs objects. + * + * You must call accel_sysfs_destroy() to release the allocated resources. + * + * Return: 0 on success, negative error code on failure. + */ +static int accel_sysfs_init(void) +{ + int err; + + accel_class = class_create(THIS_MODULE, "accel"); + if (IS_ERR(accel_class)) + return PTR_ERR(accel_class); + + err = class_create_file(accel_class, &class_attr_accel_version.attr); + if (err) { + class_destroy(accel_class); + accel_class = NULL; + return err; + } + + accel_class->devnode = accel_devnode; + + return 0; +} + +/** + * accel_sysfs_destroy - destroys ACCEL class + * + * Destroy the ACCEL device class. + */ +static void accel_sysfs_destroy(void) +{ + if (IS_ERR_OR_NULL(accel_class)) + return; + class_remove_file(accel_class, &class_attr_accel_version.attr); + class_destroy(accel_class); + accel_class = NULL; +} + +static int accel_stub_open(struct inode *inode, struct file *filp) +{ + DRM_DEBUG("Operation not supported"); + + return -EOPNOTSUPP; +} + +static const struct file_operations accel_stub_fops = { + .owner = THIS_MODULE, + .open = accel_stub_open, + .llseek = noop_llseek, +}; + +void accel_core_exit(void) +{ + unregister_chrdev(ACCEL_MAJOR, "accel"); + debugfs_remove(accel_debugfs_root); + accel_sysfs_destroy(); +} + +int __init accel_core_init(void) +{ + int ret; + + ret = accel_sysfs_init(); + if (ret < 0) { + DRM_ERROR("Cannot create ACCEL class: %d\n", ret); + goto error; + } + + accel_debugfs_root = debugfs_create_dir("accel", NULL); + + ret = register_chrdev(ACCEL_MAJOR, "accel", &accel_stub_fops); + if (ret < 0) + goto error; + +error: + /* Any cleanup will be done in drm_core_exit() that will call + * to accel_core_exit() + */ + return ret; +} diff --git a/include/drm/drm_accel.h b/include/drm/drm_accel.h new file mode 100644 index 000000000000..cf43a7b30f34 --- /dev/null +++ b/include/drm/drm_accel.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright 2022 HabanaLabs, Ltd. + * All Rights Reserved. + * + */ + +#ifndef DRM_ACCEL_H_ +#define DRM_ACCEL_H_ + +#define ACCEL_MAJOR 261 + +#if IS_ENABLED(CONFIG_ACCEL) + +void accel_core_exit(void); +int accel_core_init(void); + +#else + +static inline void accel_core_exit(void) +{ +} + +static inline int __init accel_core_init(void) +{ + return 0; +} + +#endif /* IS_ENABLED(CONFIG_ACCEL) */ + +#endif /* DRM_ACCEL_H_ */ From patchwork Wed Nov 2 20:34:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oded Gabbay X-Patchwork-Id: 14479 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp130537wru; Wed, 2 Nov 2022 13:41:09 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5BOpVjX6SQdtfn4w02Cme/gjJgw/SUdY/xB6urkMGf//DSc5W0JPY65fC+uas4TUAeF6r/ X-Received: by 2002:aa7:c14b:0:b0:461:c47d:48cf with SMTP id r11-20020aa7c14b000000b00461c47d48cfmr25858902edp.83.1667421669227; Wed, 02 Nov 2022 13:41:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1667421669; cv=none; d=google.com; s=arc-20160816; b=xsdKWGkuHE+4HoYSsk3BjU2XpL3M2XAPOLpoIFCQWTLgzSdFUB5qanUWa1klfPqcJo HT1fpRl5osNKmH9vsIjqXeuow2soxEQrDCQIdRpP0O/Os87DI/qF7qNsjujwBvmhWAOd gob4kKD6IvEwCu/R0SJrxjoxJTEYloY8fJOyd+TfNPQWOjLegjYtbPspVhB0J+erIFpN cJc0/Lnn56DFF2YYKihPwGiVc0bPH4MwLDa8Y64dZ42qtykccC80aKBfKHDDMt9yGPqa JUV73ACH45nmHLcqE5JUNM7eI40hUjMutfi7XCZ39P2az3QA690/ilnKBAciPbTS6Hzx NVJA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=3cyTu7LP/c6J33STMZLzvScjUVkJ6ZP/D3KDjrlsE1I=; b=0ZWQaf67EcYQArl2bqMvNZCtHFgHqz+EOViDERJLpwNfO940JEVTct5wk7KEHDbeiJ hMy3J+H+8DWB2YcDCPZPw3L/2LJEitLoanXX7KT9cBjBy8IDUGZlJA+Tb2wXW8JBO5fa ynIxSjdK8EQAa0JKkmKDxyUL/i04oYGUFD6dXeJ4OZknuH1ZtkIbBTnd9aaDgCYeh9nZ qVkkyG5tBhuQYB+ooIfES9G8fwLOmcgUeW/OhBuu3HF5W19Wz+HNof+cWxyMCHulq9r3 tM7dhTMz0OrdQxeD0p1T63sZEOFmEQOYOtUxJ8ElbbRak8VGdJRUoOOBPnVlF7VjmMcD 5i1w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=F+s73xiv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id dz19-20020a0564021d5300b0045c13366de4si18413356edb.572.2022.11.02.13.40.35; Wed, 02 Nov 2022 13:41:09 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=F+s73xiv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231246AbiKBUee (ORCPT + 99 others); Wed, 2 Nov 2022 16:34:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231272AbiKBUe2 (ORCPT ); Wed, 2 Nov 2022 16:34:28 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D20C06403 for ; Wed, 2 Nov 2022 13:34:26 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6052261BF7 for ; Wed, 2 Nov 2022 20:34:26 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 87A1FC433C1; Wed, 2 Nov 2022 20:34:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1667421265; bh=ATXrtyCVY8SWg2oejMlYWzbqx44OoY28tztz/qRQuUE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=F+s73xivFwNUPpe2t3rohK3K116c2C27UiaLaAYwu/cHlVPkQc23snOR3VRtpOIOi +yb+0rQl3N9c0PT/kCJqZH/qXHTsfvI0rXkL4ByBkvA2I3YVeS4sZLyhQl6prmuP2Y EcxviBKK4lWD7aZ2z/ZPAOlEetIJFB+Ft8My172SgnkaxnvSXL5LLOT1Pvl0HjtRO5 mXFscuNkQMyDCn5IWvAbupf0+DxylxwfzBc2aCYjZeVLBL/mXVLFyQuE3CWv9tqopq 2Hz7mFhJ+1dcxFU7NYSu9IBQH6oOq2AeDL/qBvMBlmWx5Syw1NSoX3mw5GraZzKWKU b5IEWfzDAgDgg== From: Oded Gabbay To: David Airlie , Daniel Vetter , Arnd Bergmann , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Jason Gunthorpe , John Hubbard , Alex Deucher Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Yuji Ishikawa , Jiho Chu , Daniel Stone , Tvrtko Ursulin , Jeffrey Hugo , Christoph Hellwig , Kevin Hilman , Jagan Teki , Jacek Lawrynowicz , Maciej Kwapulinski Subject: [RFC PATCH v2 2/3] accel: add dedicated minor for accelerator devices Date: Wed, 2 Nov 2022 22:34:04 +0200 Message-Id: <20221102203405.1797491-3-ogabbay@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221102203405.1797491-1-ogabbay@kernel.org> References: <20221102203405.1797491-1-ogabbay@kernel.org> MIME-Version: 1.0 X-Spam-Status: No, score=-8.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1748418343947052579?= X-GMAIL-MSGID: =?utf-8?q?1748418343947052579?= The accelerator devices are exposed to user-space using a dedicated major. In addition, they are represented in /dev with new, dedicated device char names: /dev/accel/accel*. This is done to make sure any user-space software that tries to open a graphic card won't open the accelerator device by mistake. The above implies that the minor numbering should be separated from the rest of the DRM devices. However, to avoid code duplication, we want the drm_minor structure to be able to represent the accelerator device. To achieve this, we add a new drm_minor* to drm_device that represents the accelerator device. This pointer is initialized for drivers that declare they handle compute accelerator, using a new driver feature flag called DRIVER_COMPUTE_ACCEL. It is important to note that this driver feature is mutually exclusive with DRIVER_RENDER. Devices that want to expose both graphics and compute device char files should be handled by two drivers that are connected using the auxiliary bus framework. In addition, we define a different xarray to handle the accelerators minors. This is done to make the minor's index be identical to the device index in /dev/. Any access to the xarray is done solely by functions in accel_drv.c, as the xarray is define as static. The DRM core functions call those functions in case they detect the minor's type is DRM_MINOR_ACCEL. We define a separate accel_open function (from drm_open) that the accel drivers should set as their open callback function. Both these functions eventually call the same drm_open_helper(), which had to be changed to be non-static so it can be called from accel_drv.c. accel_open() partially duplicates drm_open as I removed some code from it that handles legacy devices. Signed-off-by: Oded Gabbay --- Changes in v2: - Moved all accel minor handling code to accel_drv.c - Replaced deprecated idr with xarray drivers/accel/accel_drv.c | 205 +++++++++++++++++++++++++++++++++---- drivers/gpu/drm/drm_file.c | 2 +- include/drm/drm_accel.h | 29 +++++- include/drm/drm_device.h | 3 + include/drm/drm_drv.h | 8 ++ include/drm/drm_file.h | 21 +++- 6 files changed, 247 insertions(+), 21 deletions(-) -- 2.25.1 diff --git a/drivers/accel/accel_drv.c b/drivers/accel/accel_drv.c index 6132765ea054..964a93799936 100644 --- a/drivers/accel/accel_drv.c +++ b/drivers/accel/accel_drv.c @@ -9,13 +9,22 @@ #include #include #include +#include #include +#include +#include #include #include +static DEFINE_XARRAY_ALLOC(accel_minors_xa); + static struct dentry *accel_debugfs_root; -struct class *accel_class; +static struct class *accel_class; + +static struct device_type accel_sysfs_device_minor = { + .name = "accel_minor" +}; static char *accel_devnode(struct device *dev, umode_t *mode) { @@ -24,16 +33,6 @@ static char *accel_devnode(struct device *dev, umode_t *mode) static CLASS_ATTR_STRING(accel_version, 0444, "accel 1.0.0 20221018"); -/** - * accel_sysfs_init - initialize sysfs helpers - * - * This is used to create the ACCEL class, which is the implicit parent of any - * other top-level ACCEL sysfs objects. - * - * You must call accel_sysfs_destroy() to release the allocated resources. - * - * Return: 0 on success, negative error code on failure. - */ static int accel_sysfs_init(void) { int err; @@ -54,11 +53,6 @@ static int accel_sysfs_init(void) return 0; } -/** - * accel_sysfs_destroy - destroys ACCEL class - * - * Destroy the ACCEL device class. - */ static void accel_sysfs_destroy(void) { if (IS_ERR_OR_NULL(accel_class)) @@ -68,11 +62,185 @@ static void accel_sysfs_destroy(void) accel_class = NULL; } +/** + * accel_set_device_instance_params() - Set some device parameters for accel device + * @kdev: Pointer to the device instance. + * @index: The minor's index + * + * This function creates the dev_t of the device using the accel major and + * the device's minor number. In addition, it sets the class and type of the + * device instance to the accel sysfs class and device type, respectively. + */ +void accel_set_device_instance_params(struct device *kdev, int index) +{ + kdev->devt = MKDEV(ACCEL_MAJOR, index); + kdev->class = accel_class; + kdev->type = &accel_sysfs_device_minor; +} + +/** + * accel_minor_alloc() - Allocates a new accel minor + * + * This function access the accel minors xarray and allocates from it + * a new id to represent a new accel minor + * + * Return: A new id on success or error code in case xa_alloc failed + */ +int accel_minor_alloc(void) +{ + int rc, index; + + rc = xa_alloc(&accel_minors_xa, &index, NULL, + XA_LIMIT(0, ACCEL_MAX_MINORS - 1), GFP_KERNEL); + if (rc < 0) + return rc; + + return index; +} + +/** + * accel_minor_remove() - Remove an accel minor + * @index: The minor id to remove. + * + * This function access the accel minors xarray and removes from + * it the member with the id that is passed to this function. + */ +void accel_minor_remove(int index) +{ + xa_erase(&accel_minors_xa, index); +} + +/** + * accel_minor_replace() - Replace minor pointer in accel minors xarray. + * @minor: Pointer to the new minor. + * @index: The minor id to replace. + * + * This function access the accel minors xarray 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 + */ +int accel_minor_replace(struct drm_minor *minor, int index) +{ + if (minor) { + void *entry; + + entry = xa_cmpxchg(&accel_minors_xa, index, NULL, minor, GFP_KERNEL); + if (xa_is_err(entry)) + return xa_err(entry); + } else { + xa_store(&accel_minors_xa, index, NULL, GFP_KERNEL); + } + + return 0; +} + +/* + * 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; + + xa_lock(&accel_minors_xa); + minor = xa_load(&accel_minors_xa, minor_id); + if (minor) + drm_dev_get(minor->dev); + xa_unlock(&accel_minors_xa); + + 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 + * @filp: file pointer. + * + * This function must be used by drivers as their &file_operations.open method. + * It looks up the correct ACCEL device and instantiates all the per-file + * resources for it. It also calls the &drm_driver.open driver callback. + * + * Return: 0 on success or negative errno value on failure. + */ +int accel_open(struct inode *inode, struct file *filp) +{ + struct drm_device *dev; + struct drm_minor *minor; + int retcode; + + minor = accel_minor_acquire(iminor(inode)); + if (IS_ERR(minor)) + return PTR_ERR(minor); + + dev = minor->dev; + + atomic_fetch_inc(&dev->open_count); + + /* share address_space across all char-devs of a single device */ + filp->f_mapping = dev->anon_inode->i_mapping; + + retcode = drm_open_helper(filp, minor); + if (retcode) + goto err_undo; + + return 0; + +err_undo: + atomic_dec(&dev->open_count); + accel_minor_release(minor); + return retcode; +} +EXPORT_SYMBOL_GPL(accel_open); + static int accel_stub_open(struct inode *inode, struct file *filp) { - DRM_DEBUG("Operation not supported"); + const struct file_operations *new_fops; + struct drm_minor *minor; + int err; + + DRM_DEBUG("\n"); + + minor = accel_minor_acquire(iminor(inode)); + if (IS_ERR(minor)) + return PTR_ERR(minor); + + new_fops = fops_get(minor->dev->driver->fops); + if (!new_fops) { + err = -ENODEV; + goto out; + } + + replace_fops(filp, new_fops); + if (filp->f_op->open) + err = filp->f_op->open(inode, filp); + else + err = 0; + +out: + accel_minor_release(minor); - return -EOPNOTSUPP; + return err; } static const struct file_operations accel_stub_fops = { @@ -86,6 +254,7 @@ void accel_core_exit(void) unregister_chrdev(ACCEL_MAJOR, "accel"); debugfs_remove(accel_debugfs_root); accel_sysfs_destroy(); + WARN_ON(!xa_empty(&accel_minors_xa)); } int __init accel_core_init(void) diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index a8b4d918e9a3..64b4a3a87fbb 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -326,7 +326,7 @@ static int drm_cpu_valid(void) * Creates and initializes a drm_file structure for the file private data in \p * filp and add it into the double linked list in \p dev. */ -static int drm_open_helper(struct file *filp, struct drm_minor *minor) +int drm_open_helper(struct file *filp, struct drm_minor *minor) { struct drm_device *dev = minor->dev; struct drm_file *priv; diff --git a/include/drm/drm_accel.h b/include/drm/drm_accel.h index cf43a7b30f34..0c0ae387d075 100644 --- a/include/drm/drm_accel.h +++ b/include/drm/drm_accel.h @@ -8,12 +8,20 @@ #ifndef DRM_ACCEL_H_ #define DRM_ACCEL_H_ -#define ACCEL_MAJOR 261 +#include + +#define ACCEL_MAJOR 261 +#define ACCEL_MAX_MINORS 256 #if IS_ENABLED(CONFIG_ACCEL) void accel_core_exit(void); int accel_core_init(void); +void accel_minor_remove(int index); +int accel_minor_alloc(void); +int 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); #else @@ -23,9 +31,28 @@ static inline void accel_core_exit(void) static inline int __init accel_core_init(void) { + /* Return 0 to allow drm_core_init to complete successfully */ return 0; } +static inline void accel_minor_remove(int index) +{ +} + +static inline int accel_minor_alloc(void) +{ + return -EOPNOTSUPP; +} + +static inline int accel_minor_replace(struct drm_minor *minor, int index) +{ + return -EOPNOTSUPP; +} + +static inline void accel_set_device_instance_params(struct device *kdev, int index) +{ +} + #endif /* IS_ENABLED(CONFIG_ACCEL) */ #endif /* DRM_ACCEL_H_ */ diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index 9923c7a6885e..933ce2048e20 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -93,6 +93,9 @@ struct drm_device { /** @render: Render node */ struct drm_minor *render; + /** @accel: Compute Acceleration node */ + struct drm_minor *accel; + /** * @registered: * diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index f6159acb8856..706e68ca5116 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -94,6 +94,14 @@ enum drm_driver_feature { * synchronization of command submission. */ DRIVER_SYNCOBJ_TIMELINE = BIT(6), + /** + * @DRIVER_COMPUTE_ACCEL: + * + * Driver supports compute acceleration devices. This flag is mutually exclusive with + * @DRIVER_RENDER and @DRIVER_MODESET. Devices that support both graphics and compute + * acceleration should be handled by two drivers that are connected using auxiliry bus. + */ + DRIVER_COMPUTE_ACCEL = BIT(7), /* IMPORTANT: Below are all the legacy flags, add new ones above. */ diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index d780fd151789..0d1f853092ab 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -51,11 +51,15 @@ struct file; /* Note that the order of this enum is ABI (it determines * /dev/dri/renderD* numbers). + * + * Setting DRM_MINOR_ACCEL to 32 gives enough space for more drm minors to + * be implemented before we hit any future */ enum drm_minor_type { DRM_MINOR_PRIMARY, DRM_MINOR_CONTROL, DRM_MINOR_RENDER, + DRM_MINOR_ACCEL = 32, }; /** @@ -70,7 +74,7 @@ enum drm_minor_type { struct drm_minor { /* private: */ int index; /* Minor device number */ - int type; /* Control or render */ + int type; /* Control or render or accel */ struct device *kdev; /* Linux device */ struct drm_device *dev; @@ -397,7 +401,22 @@ static inline bool drm_is_render_client(const struct drm_file *file_priv) return file_priv->minor->type == DRM_MINOR_RENDER; } +/** + * drm_is_accel_client - is this an open file of the compute acceleration node + * @file_priv: DRM file + * + * Returns true if this is an open file of the compute acceleration node, i.e. + * &drm_file.minor of @file_priv is a accel minor. + * + * See also the :ref:`section on accel nodes `. + */ +static inline bool drm_is_accel_client(const struct drm_file *file_priv) +{ + return file_priv->minor->type == DRM_MINOR_ACCEL; +} + 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, size_t count, loff_t *offset); int drm_release(struct inode *inode, struct file *filp); From patchwork Wed Nov 2 20:34:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oded Gabbay X-Patchwork-Id: 14480 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp133417wru; Wed, 2 Nov 2022 13:47:35 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5AT/wEduxPFuCr/NMp2SYzO+bYWWVoXaU//z0pI/uvj3oz9gTEJVFJGmTnbRIMFOSykD8K X-Received: by 2002:a63:2221:0:b0:43b:f4a3:80cc with SMTP id i33-20020a632221000000b0043bf4a380ccmr22901714pgi.367.1667422055448; Wed, 02 Nov 2022 13:47:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1667422055; cv=none; d=google.com; s=arc-20160816; b=vYmwS2EdiqgLzkFz4SzMJPXYs5hcsvQDsuxRnK0+WWhvGL4ZrKU8/P8uLOk2R63T6H /SAkArahrUP5Eb4QDQGFWCD0zuezxVZ7jL/KN0SyPpR/bMz48G/8b/t0GCpBHsQMdCWj Nm6eUumKJ4PkkoRYtGzIAsBaatDiSytZea2TjQGNdDKi7gs1aTL05+VRhYxvOEdUbutT cnfp2SkEBt23kITgcV4OVzt6AZD7OMzSFmNVIQl6mDaz+1sliSVWIs1crD9pGCBpzoBO dxGo7p1++G4PyxzLJDpQeT0XbzlVo1hKzV4KI8VjR/7Lqw4AX9JrggTR+VLK5bx0Bgpt JLIw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=m7nWqPdDno7Has14fJS0fnYQ3MAUDuQ1XuzWCHW1Ek0=; b=IOeVJlcl7vyrXhaPeZqJPW00DS0LYMk9ZMKPsXr5AnMswWZT+DJjdBmLWaTX7/CurX RWkudtu3jv9lrshoD/69FmmhEmPdAuMJjN0+yf1cLVSZGVu1NuFkkx6Dve05y3bT7fMw HpXFeBGjQTX/zK+druVmNFrVBRijP/bTtWqnhGj+slUDoBfDYDUHzKsXmsjSPCtpnSJ2 ptJ5NwUXkI2UuPI7VaRq4U3fKyqACT4j3N93M64YxbuMZV1l9UK74zQM1NrnVGMvM+iX hFn64a8OGkfTBZb3Mu0+jVdKQRA/+1rudCQNoPxLkbbG5BV3segU6LczJWyTn/1fJXBH zkLg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=bOAQBo+N; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ip11-20020a17090b314b00b001f31f339134si3752443pjb.152.2022.11.02.13.47.22; Wed, 02 Nov 2022 13:47:35 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=bOAQBo+N; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231258AbiKBUev (ORCPT + 99 others); Wed, 2 Nov 2022 16:34:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60286 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231234AbiKBUeq (ORCPT ); Wed, 2 Nov 2022 16:34:46 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4ECEA624B for ; Wed, 2 Nov 2022 13:34:34 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id C7DE4B823C4 for ; Wed, 2 Nov 2022 20:34:32 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4F44FC433D7; Wed, 2 Nov 2022 20:34:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1667421271; bh=B8ZEkF3UEHgt25u9TF8HM/CN0QZSm2SPbFW9ClyIvc4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bOAQBo+NX3kP7xE+u3pc8SQtvmSr4c8vXE/SpGNs6bbf3XAX2UMmmgoWR+9FIQXN7 q+uE6lz0/5Zftv9MTAzkneJyP9qA62OAR6/YYNuL5Ko6KlL3eAmrq9JmmEvgZMYgui 5tIfMUvOaZ00QbnGPqADLmw79EhJxnEhCTzekX1OiszIN14gm6N6DLZwnsF+ee0ZLw BnscPWImWRxpclb6FPQZ+Gxus+oYr/laUfRtH5g/YwA9rNPZ5FIhBGEyydDzmVciFm 6oWTEMxHIWq0LYznCK3UG86+X9MijwwLPdwS7O9cdJ0Y4+sQBgsOTIb7opemPho+Ns vZAX2cQ8p5q5g== From: Oded Gabbay To: David Airlie , Daniel Vetter , Arnd Bergmann , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Jason Gunthorpe , John Hubbard , Alex Deucher Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Yuji Ishikawa , Jiho Chu , Daniel Stone , Tvrtko Ursulin , Jeffrey Hugo , Christoph Hellwig , Kevin Hilman , Jagan Teki , Jacek Lawrynowicz , Maciej Kwapulinski Subject: [RFC PATCH v2 3/3] drm: initialize accel framework Date: Wed, 2 Nov 2022 22:34:05 +0200 Message-Id: <20221102203405.1797491-4-ogabbay@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221102203405.1797491-1-ogabbay@kernel.org> References: <20221102203405.1797491-1-ogabbay@kernel.org> MIME-Version: 1.0 X-Spam-Status: No, score=-8.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1748418749514535681?= X-GMAIL-MSGID: =?utf-8?q?1748418749514535681?= Now that we have the accel framework code ready, let's call the accel functions from all the appropriate places. These places are the drm module init/exit functions, and all the drm_minor handling functions. Signed-off-by: Oded Gabbay --- drivers/gpu/drm/drm_drv.c | 98 ++++++++++++++++++++++++++++--------- drivers/gpu/drm/drm_sysfs.c | 24 ++++++--- 2 files changed, 90 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 8214a0b1ab7f..c8ea57a974b7 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -90,6 +91,8 @@ static struct drm_minor **drm_minor_get_slot(struct drm_device *dev, return &dev->primary; case DRM_MINOR_RENDER: return &dev->render; + case DRM_MINOR_ACCEL: + return &dev->accel; default: BUG(); } @@ -104,9 +107,13 @@ static void drm_minor_alloc_release(struct drm_device *dev, void *data) put_device(minor->kdev); - spin_lock_irqsave(&drm_minor_lock, flags); - idr_remove(&drm_minors_idr, minor->index); - spin_unlock_irqrestore(&drm_minor_lock, flags); + 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); + } } static int drm_minor_alloc(struct drm_device *dev, unsigned int type) @@ -123,13 +130,17 @@ static int drm_minor_alloc(struct drm_device *dev, unsigned int type) minor->dev = dev; idr_preload(GFP_KERNEL); - 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); + if (type == DRM_MINOR_ACCEL) { + r = accel_minor_alloc(); + } 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); + } idr_preload_end(); if (r < 0) @@ -163,7 +174,11 @@ static int drm_minor_register(struct drm_device *dev, unsigned int type) ret = drm_debugfs_init(minor, minor->index, drm_debugfs_root); if (ret) { - DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n"); + if (minor->type == DRM_MINOR_ACCEL) + DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/accel.\n"); + else + DRM_ERROR("DRM: Failed to initialize /sys/kernel/debug/dri.\n"); + goto err_debugfs; } @@ -172,9 +187,15 @@ static int drm_minor_register(struct drm_device *dev, unsigned int type) goto err_debugfs; /* replace NULL with @minor so lookups will succeed from now on */ - spin_lock_irqsave(&drm_minor_lock, flags); - idr_replace(&drm_minors_idr, minor, minor->index); - spin_unlock_irqrestore(&drm_minor_lock, flags); + if (minor->type == DRM_MINOR_ACCEL) { + ret = accel_minor_replace(minor, minor->index); + if (ret < 0) + goto err_debugfs; + } else { + spin_lock_irqsave(&drm_minor_lock, flags); + idr_replace(&drm_minors_idr, minor, minor->index); + spin_unlock_irqrestore(&drm_minor_lock, flags); + } DRM_DEBUG("new minor registered %d\n", minor->index); return 0; @@ -194,9 +215,13 @@ static void drm_minor_unregister(struct drm_device *dev, unsigned int type) return; /* replace @minor with NULL so lookups will fail from now on */ - spin_lock_irqsave(&drm_minor_lock, flags); - idr_replace(&drm_minors_idr, NULL, minor->index); - spin_unlock_irqrestore(&drm_minor_lock, flags); + 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); + } device_del(minor->kdev); dev_set_drvdata(minor->kdev, NULL); /* safety belt */ @@ -603,6 +628,14 @@ static int drm_dev_init(struct drm_device *dev, /* no per-device feature limits by default */ dev->driver_features = ~0u; + if (drm_core_check_feature(dev, DRIVER_COMPUTE_ACCEL) && + (drm_core_check_feature(dev, DRIVER_RENDER) || + drm_core_check_feature(dev, DRIVER_MODESET))) { + + DRM_ERROR("DRM driver can't be both a compute acceleration and graphics driver\n"); + return -EINVAL; + } + drm_legacy_init_members(dev); INIT_LIST_HEAD(&dev->filelist); INIT_LIST_HEAD(&dev->filelist_internal); @@ -628,15 +661,21 @@ static int drm_dev_init(struct drm_device *dev, dev->anon_inode = inode; - if (drm_core_check_feature(dev, DRIVER_RENDER)) { - ret = drm_minor_alloc(dev, DRM_MINOR_RENDER); + if (drm_core_check_feature(dev, DRIVER_COMPUTE_ACCEL)) { + ret = drm_minor_alloc(dev, DRM_MINOR_ACCEL); if (ret) goto err; - } + } else { + if (drm_core_check_feature(dev, DRIVER_RENDER)) { + ret = drm_minor_alloc(dev, DRM_MINOR_RENDER); + if (ret) + goto err; + } - ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY); - if (ret) - goto err; + ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY); + if (ret) + goto err; + } ret = drm_legacy_create_map_hash(dev); if (ret) @@ -883,6 +922,10 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) if (ret) goto err_minors; + ret = drm_minor_register(dev, DRM_MINOR_ACCEL); + if (ret) + goto err_minors; + ret = create_compat_control_link(dev); if (ret) goto err_minors; @@ -902,12 +945,13 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) driver->name, driver->major, driver->minor, driver->patchlevel, driver->date, dev->dev ? dev_name(dev->dev) : "virtual device", - dev->primary->index); + dev->primary ? dev->primary->index : dev->accel->index); goto out_unlock; err_minors: remove_compat_control_link(dev); + drm_minor_unregister(dev, DRM_MINOR_ACCEL); drm_minor_unregister(dev, DRM_MINOR_PRIMARY); drm_minor_unregister(dev, DRM_MINOR_RENDER); out_unlock: @@ -950,6 +994,7 @@ void drm_dev_unregister(struct drm_device *dev) drm_legacy_rmmaps(dev); remove_compat_control_link(dev); + drm_minor_unregister(dev, DRM_MINOR_ACCEL); drm_minor_unregister(dev, DRM_MINOR_PRIMARY); drm_minor_unregister(dev, DRM_MINOR_RENDER); } @@ -1034,6 +1079,7 @@ static const struct file_operations drm_stub_fops = { static void drm_core_exit(void) { drm_privacy_screen_lookup_exit(); + accel_core_exit(); unregister_chrdev(DRM_MAJOR, "drm"); debugfs_remove(drm_debugfs_root); drm_sysfs_destroy(); @@ -1061,6 +1107,10 @@ static int __init drm_core_init(void) if (ret < 0) goto error; + ret = accel_core_init(); + if (ret < 0) + goto error; + drm_privacy_screen_lookup_init(); drm_core_init_complete = true; diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 430e00b16eec..b8da978d85bb 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -471,19 +472,26 @@ struct device *drm_sysfs_minor_alloc(struct drm_minor *minor) struct device *kdev; int r; - if (minor->type == DRM_MINOR_RENDER) - minor_str = "renderD%d"; - else - minor_str = "card%d"; - kdev = kzalloc(sizeof(*kdev), GFP_KERNEL); if (!kdev) return ERR_PTR(-ENOMEM); device_initialize(kdev); - kdev->devt = MKDEV(DRM_MAJOR, minor->index); - kdev->class = drm_class; - kdev->type = &drm_sysfs_device_minor; + + if (minor->type == DRM_MINOR_ACCEL) { + minor_str = "accel%d"; + accel_set_device_instance_params(kdev, minor->index); + } else { + if (minor->type == DRM_MINOR_RENDER) + minor_str = "renderD%d"; + else + minor_str = "card%d"; + + kdev->devt = MKDEV(DRM_MAJOR, minor->index); + kdev->class = drm_class; + kdev->type = &drm_sysfs_device_minor; + } + kdev->parent = minor->dev->dev; kdev->release = drm_sysfs_release; dev_set_drvdata(kdev, minor);