From patchwork Fri Dec 7 09:55:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chunming Zhou X-Patchwork-Id: 10717763 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2937517DB for ; Fri, 7 Dec 2018 09:56:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 131A72E700 for ; Fri, 7 Dec 2018 09:56:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 04E202E747; Fri, 7 Dec 2018 09:56:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id ECA9F2E700 for ; Fri, 7 Dec 2018 09:56:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1AFE46E702; Fri, 7 Dec 2018 09:56:55 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from NAM05-DM3-obe.outbound.protection.outlook.com (mail-eopbgr730072.outbound.protection.outlook.com [40.107.73.72]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4FECE6E702; Fri, 7 Dec 2018 09:56:53 +0000 (UTC) Received: from MWHPR1201CA0007.namprd12.prod.outlook.com (2603:10b6:301:4a::17) by BN4PR12MB0834.namprd12.prod.outlook.com (2a01:111:e400:59bd::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1404.22; Fri, 7 Dec 2018 09:56:50 +0000 Received: from BY2NAM03FT037.eop-NAM03.prod.protection.outlook.com (2a01:111:f400:7e4a::206) by MWHPR1201CA0007.outlook.office365.com (2603:10b6:301:4a::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1404.19 via Frontend Transport; Fri, 7 Dec 2018 09:56:49 +0000 Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) Received: from SATLEXCHOV01.amd.com (165.204.84.17) by BY2NAM03FT037.mail.protection.outlook.com (10.152.84.188) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1404.17 via Frontend Transport; Fri, 7 Dec 2018 09:56:48 +0000 Received: from zhoucm1.amd.com (10.34.1.3) by SATLEXCHOV01.amd.com (10.181.40.71) with Microsoft SMTP Server id 14.3.389.1; Fri, 7 Dec 2018 03:56:47 -0600 From: Chunming Zhou To: , , Subject: [PATCH 05/11] drm/syncobj: add support for timeline point wait v8 Date: Fri, 7 Dec 2018 17:55:55 +0800 Message-ID: <20181207095601.2058-5-david1.zhou@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207095601.2058-1-david1.zhou@amd.com> References: <20181207095601.2058-1-david1.zhou@amd.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:165.204.84.17; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(376002)(346002)(39860400002)(136003)(396003)(2980300002)(428003)(199004)(189003)(305945005)(76176011)(4326008)(5660300001)(478600001)(72206003)(2906002)(50466002)(53416004)(2870700001)(5820100001)(106466001)(47776003)(1076002)(97736004)(105586002)(316002)(23676004)(7696005)(36756003)(68736007)(53936002)(110136005)(54906003)(8676002)(86362001)(186003)(8936002)(486006)(476003)(66574011)(126002)(2616005)(336012)(446003)(2201001)(11346002)(426003)(4744004)(81156014)(77096007)(50226002)(6666004)(26005)(81166006)(356004)(104016004)(14444005)(21314003); DIR:OUT; SFP:1101; SCL:1; SRVR:BN4PR12MB0834; H:SATLEXCHOV01.amd.com; FPR:; SPF:None; LANG:en; PTR:InfoDomainNonexistent; A:1; MX:1; X-Microsoft-Exchange-Diagnostics: 1; BY2NAM03FT037; 1:tjAG7aqAe2VGR1RyMSKU3x++vHH2QjNKTCNgcYfu7xlu1upTdr/4RGN7ilreWYBhFusqicmXP4LyQuPGCL4xyL+8M1JLj4vArlXo0W9snAhSbuu7ObTcLtekDFwx2Uno X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 66678982-fa8f-47cf-d50e-08d65c2a4e42 X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(2390098)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(2017052603328)(7153060); SRVR:BN4PR12MB0834; X-Microsoft-Exchange-Diagnostics: 1; BN4PR12MB0834; 3:OpuPhD+stSjHPD/khNu1Ks0DsDOibONDzJfaPsVmwP4MeD+YdW172WIsKbmm4nudzvZuxmjjmOkNJoqiXwquPJcXfMX1bRoSE7R972ZdooF40CKRJAjlp9ZrjXghCXlG+3iwkM4C5t1S0bLUbLokzvl/kesKONPEoWpGNn5G0uvg2Kc3eh55g0PtqILsyrD6+Q+e4sUuJL709Jdt9ujLzQUi89zAvoaK40KJ59xAKkLz+pZY/WB5HSjrpdkeWFke472N+t3Ffib907/FP3kmw+PXdu1m2geEHxPF/jet0ThNpllNmMb1H1bYfbSrfxrgJIs6UCL5zOwYOvdku1UN/BYhfl0J4ttPl0vqaotocaQ=; 25:h6m+btcoe7ZnpcTEzuUFaLF+T+S7lDKasHDFbJIK+lAFvkL1eVUoZMqyd9NfOlD+30TX9s2RkjP5AhYUgTVujAx0WbKykalHTR9IASDym9TKOCI+xv1YdZOPzpwGx0svPYA7XeXjXnSRHSY+nhGPxxJ7hTE77dsTywTUZGi/i5Db3A2IULRWxouxDCGn7AUqFvlaBQHh8dGAKQ005FJFvIzvatXXtoBPGySAECixoE1pjnsIuswfa68TuCNga3oZq92wAfSxKga5ciRZfseDKNv2b1xAGduBbAMhkgJLaTmurPwaurjhd4M0gxdXM2VeAhLUNRIy+TWN9IiZxPAMnw== X-MS-TrafficTypeDiagnostic: BN4PR12MB0834: X-Microsoft-Exchange-Diagnostics: 1; BN4PR12MB0834; 31:EVYe43CKvAcsfl0LcMLK+RgmCODvaOzniribtA33KC0VFqIRaAFGoE1vmhU1Pjm6zZFZCtk69EQ4kCHk+N93D0/tXU4fSDIkXU9Z7oL1ZZLSAML806VAQEPZq9/ZlgZFEVpMzBwah3AynvBjXBs7rmE9kt+3NlFQLuXbccx0/1lyjng269+xcvAaPNLuUiwgsd0Em1GB47FZZvgjenvMmJwjTwW6GtHjgo2iV5GReac=; 20:/OFEVQZx+FaN2CPWycIjrmhkbzXXxwS0aywTyZlI8uz8Jqfu25LlcIH/CefjlLl0JslFEDhrV42TGsjOVHlvJdxX/n3FSY1GGIpZpRH42QIn8FzBwqeISF6e7Cy1fz0d4wGm1pIPkgbQEMdRUgHkynZVIFQ2T7i6PpkNf2CBOIXE6WOb0i5//I3q9m4UKMcwPjDTk6cV40racdAXCm57qOgwlEXcIwiXIaVJbXcpz22gPKXQ1X8Q5e+FBbYCp/IEzf++267XaToNeFtbKP6njVE/pZuEPP+5VRQI9072o8dgC+SpM+pcx/wp+8LaSqGSIe3TxlMzcG4AEQN2uYotuK+e4lz3JXGAVVGA8duqlEdMWQNKs/6pwg4ij5QFjkRHpwGPI9CjFr/Jh0swIMIqSExl7HZZLY3ZSZT99SyCzS8+Av31+RDNxnZ1BujHWZNCs/y6/4R14letcxvbHpqc5a7XXG1zL+MeZSwTSkKjGFRwhO9V2N/TZz2vgs67Pmwq X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(10201501046)(3002001)(93006095)(93003095)(3231455)(999002)(944501520)(52105112)(6055026)(148016)(149066)(150057)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123560045)(20161123564045)(201708071742011)(7699051)(76991095); SRVR:BN4PR12MB0834; BCL:0; PCL:0; RULEID:; SRVR:BN4PR12MB0834; X-Microsoft-Exchange-Diagnostics: 1; BN4PR12MB0834; 4:RGGXhl34IzLuC2AfS7zbjeoJM1p/WmXGG55KfE9uV8QzStYgIAph76jK2mbvA4kA6YFpy/QL9pJOhb5wImuJU76rNcIwgWCM0us33fQr4ufI3B1a3PKnogaNxCGqD1h9TuAceOMHv1coh2EvkpI9Pjay5pbYpzMyuDUdpGZmNATdgtqwxA+RDNaonuXRaBvYVIjPma0AN2oPdSUQPR0KLxz/lvwzcbOb3ULn4/5GzpTUZ0AQFGd34GSI8tZABT1fbUodn6MRc+zxeLCkKJY3/Q== X-Forefront-PRVS: 0879599414 X-Microsoft-Exchange-Diagnostics: =?utf-8?q?1=3BBN4PR12MB0834=3B23=3A7ibsbBo?= =?utf-8?q?GSwY+UZOqMKScyxI4vDaujx9sSc+QMxiIFl5ArCsZt0jDPyqSgPmjdYVteMhj3c31?= =?utf-8?q?n6kgDv0RddB14KhJW4VN4T5hOIlwMtajxz4u4FZDDmXDJG84Uynml+OJkrYy0A6yC?= =?utf-8?q?dC97v6JE6WmTDhT//RCxIsZ23WAgP/jTvj/IwvVtsm4PeoltphReJ95ByOlyiUTdA?= =?utf-8?q?GraShkAnP88ygLVJYx/u0p8ZVIlA+4zQ6I9KjIXJAlvsxN2AaaK1VKO8Qx6l0nw2g?= =?utf-8?q?DefviOS2GfxP6fHnB29nWaSS9IzgILCiWc6UqxcWva+iTbOlkDJTNcRrdUHjCjUaV?= =?utf-8?q?Yki2owCJGL4FQAnoqzP0fcgU+2uGQvQ7jM3x2JmYbLX8Ikb3pNX9YrdtA3bPdZTda?= =?utf-8?q?ePWogcYIU1PUhJy6n+pthwbo9yteAk9pCACUd0NyWtw4TV9+9FP0HdipMJ5Dpy4y3?= =?utf-8?q?gNBkxSDoxpANFta9o0I0fMBkKXO9D8a4e18qLS/0PQwBzlyZ2eRGp890GW0Y4tOYl?= =?utf-8?q?gO7jTL9Z0F3kpmFT8lS/IM3wXUF6DmKVQDAtj57+mexvfilOoYY9LF0WMSaZeO//a?= =?utf-8?q?Ps4w+zPbPx9X4/qkC50jjW/kj++ZpYQyUWToRB+30BEtA/LyahLJ7dsxR6zomNrNV?= =?utf-8?q?WMmMyDMWJYepE9PiMzjI63cNMtMABSHPWxeRLicn/6CVWEUx7rdyffVF7SQGpaWLz?= =?utf-8?q?GhbpTUuYM97B9lB+W2d8Lwp9qouiVHqMZ/fQweshH/Wp4tJVb2tFg0DyeKHNrjH0Q?= =?utf-8?q?0/0TjVOWZyWBRJCjldMBsavRJS9Fn9K1rU88neBf2m3h9ibC3BYgSWU1dhkYk7AcN?= =?utf-8?q?u6Hj25diS7/XsE2KsJLQObhw8uwZ80b9KUdjRzY934WRr5/nVfuQe5bilpI81fGFE?= =?utf-8?q?ccdqidwM8eA0vXjNVP6W7FhMHTM2NPDGSYxv7ScqbdpYhSY7Eit0L7+9tuF1umzIC?= =?utf-8?q?qiknfwCrVB3btZ2C3ezFl28yuUJQ6kkNXTZx3LMGrCqJI/AcPBaiNcBUMsg7gRkf8?= =?utf-8?q?5eR672mq39ayK3izpweHeHtKE+RDh9jKsJzGN1SzlEcdIZwqKRtu7lyM3XVzAp7k9?= =?utf-8?q?eqcGCxs2XQrQMEHdLjxrLIGjDy8pFRVFoPtrM11jvSLREjI6+BYwdSX5SveUb/ylc?= =?utf-8?q?3Lir14aWyo7wV7JxWUtWY2/rSJv8quVMjgUsH62nRfQ+HuczdgrZe7obYiaGVrmTQ?= =?utf-8?q?RK7kHiFO3d7qNCUhUWbdxu+kEG3zqkTXkPZ1llg7xSjWpbcNoZlXu5GeO7pw=3D?= =?utf-8?q?=3D?= X-Microsoft-Antispam-Message-Info: q5XVZ0v+BGCPSKKWnioXkeegYNls0JFn64k6s/CpLS4NKjuEBXub1aVsptn6JTy38itBeb2IHiKcQlH0j5xq9wUprrvBC0FXZZ4rq5BLY3jv3Y+3VxHLZM4CvVqC8lLIC0UqN4VRHPnurwuo0gUm4KJwqcy1dCPSAbVyL1na4+PRCLOvZ/3OMlKItKyCmKCTaujx/Ax6l5sFXd5QzE6xXyfEGDOXJq+5DGc5tOdaEzjOg8mWE+ZiZIfpvwqOOxxXZQEkq+OX1k8RQwj3UEhifVCnyM1N0zFd8oTOqc/C3qEFGagIDAe7wUrWubVEgO3qD8nGKmUhDEojsDaIMi/Icw029fECUYbyMRXK8dxR6PI= X-Microsoft-Exchange-Diagnostics: 1; BN4PR12MB0834; 6:sdY/XiwB9UToeRA0bFTRbMOe2+uwuS5sJetC7jOezYrXYeQU41+HpZSzrTCrTtdwSCx/mPCqwMThpvofD00qPeaBmPLoXzUzTTqTTnap09rOQDoJfo5Tj+D/TLWgzjafZxv7vgs2ymClkU2axNwkKc6N8joqnqNp20d8pTbOyXDU8rMmVf6l8lekxy0xiBMqhPoJWBFveZazoBdq60Cgz9XGJtaWbWzNxsljaBURGluSwxsiwKpN7HW0Of5diyzcDEqLwyZaBho5adowoGalmlXXlbQ10rPNJG3X5+rqbTSvyzAXgebWm8bmoskksWt77tCR/eLUahcAk2Bdlr6UyWvrWczlK9W/S5Gg2JyjEHo9jQBzzzsdcSOcSfvzphzSsJ+AAeYYcPQ2OYrF9uJpGAnS26zvP+wAwdXZg4qlkXxVAZCoI2/ytt3XziZRxplVPhs01pmFL4k8MOP1ksLCXg==; 5:G2u7/xyhONc2ZJgjFFMlXeKr9By+I8j0LXFmj9baAINPJNTejDeedGcSwOwwHX3rzVlCO2AvKeFvyw/oG2ernATms9PWImaBVYuTEiSHB3tfd/s8teCkIfRSR9tI/NCIX+hIVMVQ2NELculLaTXFn6cV8rJ+y4V5U/0GjUg8kLM=; 7:PIstGLWreobXk3FvCB0VjPShKRdeg2jSUaycoMR74OVnKHMWQnXOs1yOBrySAo/D/qvNmTdcz+OVv5pQLjLohM9KjeSXDS0T1CdfIipfwHam+30kk7j4VVXnuMWTCFxqiC+4JQxU5bR7r4Smbad8Ug== SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BN4PR12MB0834; 20:YlxbFMnlx9Wb3KPQqtFhuFEb3IE5FGImvdnmh7ciYZcNhXwgWV00mkwsmIE6ohs34kQuzVLEGCxR3JbCQDXTQZfz6TMehgj6cdUKvaLZF3poM4QavGE/dCcybATWldG4T7qTjE+XsspOv4Jebk6sQVnMPpOlJxYDNblFYrwe5KZnWtCZal0GQMi0ut2p01S8N043edAgPgb8Fx/INzXb3ZgXZ+aeL+E27WGTG61WhYyLDQQMGgLj7TYnlgJFkzr3 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Dec 2018 09:56:48.8388 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 66678982-fa8f-47cf-d50e-08d65c2a4e42 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d; Ip=[165.204.84.17]; Helo=[SATLEXCHOV01.amd.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN4PR12MB0834 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Daniel Rakos , Jason Ekstrand , Dave Airlie , =?utf-8?q?Christian_K=C3=B6nig?= Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP points array is one-to-one match with syncobjs array. v2: add seperate ioctl for timeline point wait, otherwise break uapi. v3: userspace can specify two kinds waits:: a. Wait for time point to be completed. b. and wait for time point to become available v4: rebase v5: add comment for xxx_WAIT_AVAILABLE v6: rebase and rework on new container v7: drop _WAIT_COMPLETED, it is the default anyway v8: correctly handle garbage collected fences Signed-off-by: Chunming Zhou Signed-off-by: Christian König Cc: Daniel Rakos Cc: Jason Ekstrand Cc: Bas Nieuwenhuizen Cc: Dave Airlie Cc: Chris Wilson --- drivers/gpu/drm/drm_internal.h | 2 + drivers/gpu/drm/drm_ioctl.c | 2 + drivers/gpu/drm/drm_syncobj.c | 153 ++++++++++++++++++++++++++------- include/uapi/drm/drm.h | 15 ++++ 4 files changed, 143 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index c7a7d7ce5d1c..18b41e10195c 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -178,6 +178,8 @@ int drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); int drm_syncobj_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); +int drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_private); int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private); int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 94bd872d56c4..a9a17ed35cc4 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -675,6 +675,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_WAIT, drm_syncobj_wait_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, drm_syncobj_timeline_wait_ioctl, + DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_RESET, drm_syncobj_reset_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl, diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 51f798e2194f..348079bb0965 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -61,6 +61,7 @@ struct syncobj_wait_entry { struct task_struct *task; struct dma_fence *fence; struct dma_fence_cb fence_cb; + u64 point; }; static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj, @@ -95,6 +96,8 @@ EXPORT_SYMBOL(drm_syncobj_find); static void drm_syncobj_fence_add_wait(struct drm_syncobj *syncobj, struct syncobj_wait_entry *wait) { + struct dma_fence *fence; + if (wait->fence) return; @@ -103,11 +106,15 @@ static void drm_syncobj_fence_add_wait(struct drm_syncobj *syncobj, * have the lock, try one more time just to be sure we don't add a * callback when a fence has already been set. */ - if (syncobj->fence) - wait->fence = dma_fence_get( - rcu_dereference_protected(syncobj->fence, 1)); - else + fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, 1)); + if (!fence || dma_fence_chain_find_seqno(&fence, wait->point)) { + dma_fence_put(fence); list_add_tail(&wait->node, &syncobj->cb_list); + } else if (!fence) { + wait->fence = dma_fence_get_stub(); + } else { + wait->fence = fence; + } spin_unlock(&syncobj->lock); } @@ -148,10 +155,8 @@ void drm_syncobj_add_point(struct drm_syncobj *syncobj, dma_fence_chain_init(chain, prev, fence, point); rcu_assign_pointer(syncobj->fence, &chain->base); - list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) { - list_del_init(&cur->node); + list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) syncobj_wait_syncobj_func(syncobj, cur); - } spin_unlock(&syncobj->lock); /* Walk the chain once to trigger garbage collection */ @@ -182,10 +187,8 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, rcu_assign_pointer(syncobj->fence, fence); if (fence != old_fence) { - list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) { - list_del_init(&cur->node); + list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) syncobj_wait_syncobj_func(syncobj, cur); - } } spin_unlock(&syncobj->lock); @@ -642,13 +645,27 @@ static void syncobj_wait_fence_func(struct dma_fence *fence, static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj, struct syncobj_wait_entry *wait) { + struct dma_fence *fence; + /* This happens inside the syncobj lock */ - wait->fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, - lockdep_is_held(&syncobj->lock))); + fence = rcu_dereference_protected(syncobj->fence, + lockdep_is_held(&syncobj->lock)); + dma_fence_get(fence); + if (!fence || dma_fence_chain_find_seqno(&fence, wait->point)) { + dma_fence_put(fence); + return; + } else if (!fence) { + wait->fence = dma_fence_get_stub(); + } else { + wait->fence = fence; + } + wake_up_process(wait->task); + list_del_init(&wait->node); } static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, + void __user *user_points, uint32_t count, uint32_t flags, signed long timeout, @@ -656,12 +673,27 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, { struct syncobj_wait_entry *entries; struct dma_fence *fence; + uint64_t *points; uint32_t signaled_count, i; - entries = kcalloc(count, sizeof(*entries), GFP_KERNEL); - if (!entries) + points = kmalloc_array(count, sizeof(*points), GFP_KERNEL); + if (points == NULL) return -ENOMEM; + if (!user_points) { + memset(points, 0, count * sizeof(uint64_t)); + + } else if (copy_from_user(points, user_points, + sizeof(uint64_t) * count)) { + timeout = -EFAULT; + goto err_free_points; + } + + entries = kcalloc(count, sizeof(*entries), GFP_KERNEL); + if (!entries) { + timeout = -ENOMEM; + goto err_free_points; + } /* Walk the list of sync objects and initialize entries. We do * this up-front so that we can properly return -EINVAL if there is * a syncobj with a missing fence and then never have the chance of @@ -669,9 +701,13 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, */ signaled_count = 0; for (i = 0; i < count; ++i) { + struct dma_fence *fence; + entries[i].task = current; - entries[i].fence = drm_syncobj_fence_get(syncobjs[i]); - if (!entries[i].fence) { + entries[i].point = points[i]; + fence = drm_syncobj_fence_get(syncobjs[i]); + if (!fence || dma_fence_chain_find_seqno(&fence, points[i])) { + dma_fence_put(fence); if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { continue; } else { @@ -680,7 +716,13 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, } } - if (dma_fence_is_signaled(entries[i].fence)) { + if (fence) + entries[i].fence = fence; + else + entries[i].fence = dma_fence_get_stub(); + + if ((flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE) || + dma_fence_is_signaled(entries[i].fence)) { if (signaled_count == 0 && idx) *idx = i; signaled_count++; @@ -713,7 +755,8 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, if (!fence) continue; - if (dma_fence_is_signaled(fence) || + if ((flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE) || + dma_fence_is_signaled(fence) || (!entries[i].fence_cb.func && dma_fence_add_callback(fence, &entries[i].fence_cb, @@ -758,6 +801,9 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, } kfree(entries); +err_free_points: + kfree(points); + return timeout; } @@ -796,19 +842,33 @@ static signed long drm_timeout_abs_to_jiffies(int64_t timeout_nsec) static int drm_syncobj_array_wait(struct drm_device *dev, struct drm_file *file_private, struct drm_syncobj_wait *wait, - struct drm_syncobj **syncobjs) + struct drm_syncobj_timeline_wait *timeline_wait, + struct drm_syncobj **syncobjs, bool timeline) { - signed long timeout = drm_timeout_abs_to_jiffies(wait->timeout_nsec); + signed long timeout = 0; uint32_t first = ~0; - timeout = drm_syncobj_array_wait_timeout(syncobjs, - wait->count_handles, - wait->flags, - timeout, &first); - if (timeout < 0) - return timeout; - - wait->first_signaled = first; + if (!timeline) { + timeout = drm_timeout_abs_to_jiffies(wait->timeout_nsec); + timeout = drm_syncobj_array_wait_timeout(syncobjs, + NULL, + wait->count_handles, + wait->flags, + timeout, &first); + if (timeout < 0) + return timeout; + wait->first_signaled = first; + } else { + timeout = drm_timeout_abs_to_jiffies(timeline_wait->timeout_nsec); + timeout = drm_syncobj_array_wait_timeout(syncobjs, + u64_to_user_ptr(timeline_wait->points), + timeline_wait->count_handles, + timeline_wait->flags, + timeout, &first); + if (timeout < 0) + return timeout; + timeline_wait->first_signaled = first; + } return 0; } @@ -894,13 +954,48 @@ drm_syncobj_wait_ioctl(struct drm_device *dev, void *data, return ret; ret = drm_syncobj_array_wait(dev, file_private, - args, syncobjs); + args, NULL, syncobjs, false); drm_syncobj_array_free(syncobjs, args->count_handles); return ret; } +int +drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_private) +{ + struct drm_syncobj_timeline_wait *args = data; + struct drm_syncobj **syncobjs; + int ret = 0; + + if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + return -ENODEV; + + if (args->flags & ~(DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL | + DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT | + DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE)) + return -EINVAL; + + if (args->count_handles == 0) + return -EINVAL; + + ret = drm_syncobj_array_find(file_private, + u64_to_user_ptr(args->handles), + args->count_handles, + &syncobjs); + if (ret < 0) + return ret; + + ret = drm_syncobj_array_wait(dev, file_private, + NULL, args, syncobjs, true); + + drm_syncobj_array_free(syncobjs, args->count_handles); + + return ret; +} + + int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 300f336633f2..0092111d002c 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -737,6 +737,7 @@ struct drm_syncobj_handle { #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0) #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1) +#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (1 << 2) struct drm_syncobj_wait { __u64 handles; /* absolute timeout */ @@ -747,6 +748,19 @@ struct drm_syncobj_wait { __u32 pad; }; +struct drm_syncobj_timeline_wait { + __u64 handles; + /* wait on specific timeline point for every handles*/ + __u64 points; + /* absolute timeout */ + __s64 timeout_nsec; + __u32 count_handles; + __u32 flags; + __u32 first_signaled; /* only valid when not waiting all */ + __u32 pad; +}; + + struct drm_syncobj_array { __u64 handles; __u32 count_handles; @@ -909,6 +923,7 @@ extern "C" { #define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease) #define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease) +#define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait) /** * Device specific ioctls should only be in their respective headers * The device specific ioctl range is from 0x40 to 0x9f.