From patchwork Fri Dec 7 15:54:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chunming Zhou X-Patchwork-Id: 10718409 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 51EF714E2 for ; Fri, 7 Dec 2018 15:55:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3FA5D2DADC for ; Fri, 7 Dec 2018 15:55:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 336BC2E4DD; Fri, 7 Dec 2018 15:55:10 +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=unavailable 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 783CB2E5F6 for ; Fri, 7 Dec 2018 15:55:09 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8A8436E7D3; Fri, 7 Dec 2018 15:55:07 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from NAM04-BN3-obe.outbound.protection.outlook.com (mail-eopbgr680043.outbound.protection.outlook.com [40.107.68.43]) by gabe.freedesktop.org (Postfix) with ESMTPS id CA5FB6E7CF; Fri, 7 Dec 2018 15:55:05 +0000 (UTC) Received: from CY4PR1201CA0017.namprd12.prod.outlook.com (2603:10b6:910:16::27) by CY1PR12MB0838.namprd12.prod.outlook.com (2a01:111:e400:59d2::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1404.19; Fri, 7 Dec 2018 15:55:03 +0000 Received: from BY2NAM03FT022.eop-NAM03.prod.protection.outlook.com (2a01:111:f400:7e4a::201) by CY4PR1201CA0017.outlook.office365.com (2603:10b6:910:16::27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1404.19 via Frontend Transport; Fri, 7 Dec 2018 15:55:03 +0000 Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) Received: from SATLEXCHOV02.amd.com (165.204.84.17) by BY2NAM03FT022.mail.protection.outlook.com (10.152.84.225) 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 15:55:02 +0000 Received: from zhoucm1.amd.com (10.34.1.3) by SATLEXCHOV02.amd.com (10.181.40.72) with Microsoft SMTP Server id 14.3.389.1; Fri, 7 Dec 2018 09:55:01 -0600 From: Chunming Zhou To: , , , Date: Fri, 7 Dec 2018 23:54:16 +0800 Message-ID: <20181207155422.15967-4-david1.zhou@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207155422.15967-1-david1.zhou@amd.com> References: <20181207155422.15967-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)(39860400002)(136003)(396003)(376002)(346002)(2980300002)(428003)(189003)(199004)(77096007)(5820100001)(86362001)(8676002)(68736007)(53416004)(106466001)(50226002)(104016004)(478600001)(72206003)(105586002)(2616005)(6346003)(66574011)(186003)(7696005)(336012)(446003)(26005)(476003)(486006)(50466002)(426003)(11346002)(76176011)(126002)(5660300001)(4744004)(36756003)(47776003)(81166006)(23676004)(8936002)(1076002)(6666004)(305945005)(97736004)(81156014)(4326008)(316002)(110136005)(54906003)(14444005)(356004)(2201001)(2870700001)(2906002)(53936002)(21314003); DIR:OUT; SFP:1101; SCL:1; SRVR:CY1PR12MB0838; H:SATLEXCHOV02.amd.com; FPR:; SPF:None; LANG:en; PTR:InfoDomainNonexistent; MX:1; A:1; X-Microsoft-Exchange-Diagnostics: 1; BY2NAM03FT022; 1:5dkIlWOvJQ6TlKHDRADWnNYsNDqUZ54V4StU88zGUaEzQmOrDAKKCdgF2nxvtocRUntXO4G1sURdPAga0AcaUOeG3JIkVcdrotmLzf9tozUDsgaNTCNVI7Z1ppAlYX8Z X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 2ea0528a-9d31-429e-3bf1-08d65c5c59c8 X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(2390098)(7020095)(4652040)(8989299)(5600074)(711020)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060); SRVR:CY1PR12MB0838; X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0838; 3:lC9ppueFG0GzVXz3pIGC/DjHfMBPIWL6RqznFGwZbGvvR7VlTsE9n4lWYMQyIfmn5+d9SJjE8z3prlFS/LYVg0HFr/lMKHC6+7c+CsfpBc63rfCSHmStukhiW8gUPJx+4EEjRh+OCp5u32bMhUKAtaJom0bsC3uQd82ITDqJrCJJthLNtYwAYwO8fbSg0GlTBHVyTovYpOWZu6VuiRLXKmqorRvcS802MDXkPAEJbav8oUwN/VIodHbN7pr8oaF3K/Bf71IF74mFogy8VMCK1uxQGXKB1jgt2qrlF3QSuUSLaIls/jNn8go2SP+RFm4N0MWrmEMqfpliAx+CsTanX116VKKXzSPxNE+/RVYde/4=; 25:DzK+EDbptyNyTN/nvNMYbA32cZxMqt1Y518ND1PVIaASS9BqoDDL0wEzbo8S1MYeeVvhsunp+HZ/zdiJ0LTspTsa2x8qlfZyJTIErmAylzsSLEmpRUbM0vjCmvcMHeykcdxw1zyLZjxRSmxIP2IkjXQrBIYXDMP+/jsxCtwoAkMl29a2/xEgl9+qWKDmpNvl2NTd4ZoIOzoo+YnRO/ih/7pcbiKcjceT+BX/+8d8QWdS6oezhHQTABoh2HoDkyLd441rgZLlxUx7ghgQEDeOpnwkUwqF4D/lkqL+TStj0/HD/VjMjezZdDMGsqQYQm8mskxF9JWJSjmKZSv/qIawMg== X-MS-TrafficTypeDiagnostic: CY1PR12MB0838: X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0838; 31:o2sAb3/tJ6sxTqge0fwADVh57hei8zMgCEVx1G3pOLsPXdXhwXX5nub/rdgHOlPE0NM9DmvPNyAaZ+SULJ0J2U8eQcwgwBlUq9sxqLLqydx1CWAw+7SELMX6rouM7VQYjToe2MA+sW8uMYZSecf7PreHpQrMNSWFyIDdz45lO/7+70GzDK1WPS8HTEfuGOhwJe21Tih6qM4YUtHJ14WILAMyrKlSh/Ob3rMlto0MK+c=; 20:zEiJ6MBqDqpdoeaZfDT0KRfctnIrxR46W/PVZBKlydupl4a2CbkHphdRKy7U4Qay1tt1uph+8wkU6eh86H8QxeqVjtBRWdKagNUnVjiBFU2mLE9dfHAAH7rWhf66KLqo1mdkDx1rxMesWK5RCye37XG/D9SdUJZ5FCj7y7er8KQEKMpF3a3/cDF5MdusPa+3VX2dcN7457+gjQsjfJgDQMiDwe1UADREg1LgWYKnl2vEJsClWk1uqPPTqNu5wOAcpwsgjjz9tE8WJFTGjxUcqXKq2HFW2brexF9WwE3UU/b2F7MYkPC4R+6VTiaqlb6qegJbulyUfUlPhFS8+wx/X7DCumPjFFLIaBcJlAlN7pqEZRG8pBenx+zmgUUN+p2N2kaCGWsp+qSo7ErdLy4sHXcd1BFrC1NN+JrZtFhjarimVcVBpCmZodQL2ZF3SswNNqWxLJ1RjFu4PUwQj7T0P9vEIlhb5hW8B6ShqCIQtPu9uWIxs+Hb75gzfFaqVod6 X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(93006095)(93003095)(3002001)(3231455)(999002)(944501520)(52105112)(10201501046)(6055026)(148016)(149066)(150057)(6041310)(20161123562045)(20161123564045)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(201708071742011)(7699051)(76991095); SRVR:CY1PR12MB0838; BCL:0; PCL:0; RULEID:; SRVR:CY1PR12MB0838; X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0838; 4:Yy9Qy7tAyrYoD0cYcegjtfegdGRqeG6nPV+GRG6mNw6U9DqHoGgwPyPYZWiRLfPoDQk2gDjltfbXeXyfptTr9YzeZbYtdhuFCNv258MO/A6SudFzQ/CK3DTv6szwbA4kr+E5UrYEyeFBQQ3P3ZqL6FTCIdQRM5mFxgifxhdNdxy7DwtvtKykRWDYz54eZ8wvPECXJUMSlN/unXE+u1O8J+7m47WGhQa/WDdkoDn9A6BYvsyfy9Kd0QrOtr2QUoCWqrUsEIY/3ZsfjQhcRnIunQ== X-Forefront-PRVS: 0879599414 X-Microsoft-Exchange-Diagnostics: =?utf-8?q?1=3BCY1PR12MB0838=3B23=3ANJBJp24?= =?utf-8?q?GEKy+h956lgnKmobaU10DHXbp/xqioM5IZfQ2LZoCA9kS7H/fkH3UBK2bL+FEnNEM?= =?utf-8?q?CVKqIcyeDi8jKd/xs+wwhabOtFnrawzKyP9tgWyLo/CNpMRdVKMGYMpe+NrcAJrCx?= =?utf-8?q?tBOtjpdRtfLYw6K9v/fjxgwulWwCTdgST7G2cZRlBJW1gmMocTnUIx/F421yi0jF3?= =?utf-8?q?sLbSVMb2lnrD2gakLb3rXqcRC6hkH6XXf/34EaIzZli1Y+8ZxSMyEyzLz+q5LCF2C?= =?utf-8?q?qWIu+471Aj57odWEOiNibBu6EeFwk7up+SzGCt5EuixKqv9bTGpc8wezLfFraggX5?= =?utf-8?q?USpw7dFQT5fJqS/6Q3LQKV39iJGffv0auNE9ynLDjhkLFcjDtF+RmFzjrAZC25UgP?= =?utf-8?q?s5esxgi5Oo4BtaE4iZdn8HlhRsexEx7+7aSPdCRXVAhSUkF/gJQ0BHL7orUtHVBtg?= =?utf-8?q?8+/1MTHO4S/Cq8J5SAD2DhnCyp+pnwfNrJgcCZaCzbU49QeqQOsdvG3MZi1mJT8v4?= =?utf-8?q?q9WBFkG26jo3tOztQI0dielI8sY+R2nQ7vA8Mc8VNb6wSCrx+Q1lgfITUK1Ufe/sA?= =?utf-8?q?dMJzhyoVqRMf8l2qAjeasCKDqbp65YldrN6lTVj/5E1DXNcrnWMf/nqc5o9Vucb9Y?= =?utf-8?q?3scGKsvMHPTs/JZ0Jqif4U9kENE7qR8do6b+4a231s3sJ3/zqNQ/uc3MwOnTRWU6B?= =?utf-8?q?CXtzrRUa6hgvVALy5mqlPV0Y3kIbiggy9DXVGKbRUztpnk8cIRecFwFwfCaDlJFCD?= =?utf-8?q?+uQzRPD+DeWfd1PIzhq/RyFLgdmHNsBZkVqjnU14uyEWmKnf0uUpcKC2hgxazSTT0?= =?utf-8?q?MpFWiUiioJGzlH8n/fEGvrZfadvc/cln3n1/AgD0rV1xjrwZ8sDLtrHhHiHjvkHq5?= =?utf-8?q?o1olD3LFIx78+EGpXObgucKQryz3r10pumJDXV9Xx4Q+/EFFw5WejJlpSXRvbQJ5D?= =?utf-8?q?2THpuI9oMXugYXl7MH2NpCGQSpK7tZIOtbeF/hMglfURb9ee2alexZCfrmK1hjaZS?= =?utf-8?q?tuuJOsFfSfNHEfjgiFjMvcPhDr9JJXztRV9a0TQT2JvwR+mDRggcovpsz/yLxvv5T?= =?utf-8?q?akkP3lh36J7j+DDtb7ywEgBQPYDPUO1oP2f0bVW53+WwPwReJSCz2RnScJpk06wxk?= =?utf-8?q?1SnOUI6dj/7Q3IgOW1As/0Y7jid21w9TFdqH6OMDnx6IIyGaRE3EnlmS/JX4rsspN?= =?utf-8?q?bjA6Rf9xEnfrN7l0+tbZn5X/0ajxBGyGiIRSGqR24+3r3HNBqvXskETnwwMiMsocj?= =?utf-8?q?AWPjf1KSTpUuJFK8=3D?= X-Microsoft-Antispam-Message-Info: 7wC+jhWvGm1gu58PTyOL8ukQkmTp7TCeqYYxSUxquik2hm/DJfxlCnEBmnyXjDnKEhQwCYtpShH6E6BEUWKRVawinz3w/RG/w71SHmO3DTNjYOZI0hvZLaRkye9mQX2sXFQVZxyyeBZTD1EvhulbClgQaBcOznp2UDz9k1nGnYVKcuszTQmb7loK9Rou2aMy9VLiGtF4H1YyT1Lf4RtCnmdKk20OoBkJRTUIrnm+Y5IfoV3919H21AiqwdwqnDknGIq/w4EMz5YlWlHutNP2c4UZuIl0yi1URyiSgy98BNsfq+55AzNPoj3qtE5FXcpdisflt4XCfJR5PrXsYs2rZ2Tuxxqv07SagszILxxjlKQ= X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0838; 6:SsZYlKXqtnksJIJWquWMXg7pJtvai3TNs3vkCSIQQlJgw4iPsW5YIgCzgHc+njCAmYAXKKGsh6sHrQB/YOunxqU80w24QRnnHYYOd1ufYSGtpd3fgw+gmn44XKH4lV/9/SQLEAFdXbkp4/GlhqFECVdvlTwJYmDLulzAwJcf4fKR1fNiGRze0tuP5u5pGZ5j9U9pN/AcsV9See1mAxKSXMQ/ZImhWcGkCUX0zop2xUfTs6xQFXXtPXzBzXuu0g2jDEJDf+EJrB+H6HsgYSWhPC2oKBqvT6q0A4Ss3JhpgSZVzJ+7hfG99NxEoy1h+cIhfP6iihT8iK/F/SVGQvQyo8VDFCzca9cTHvyv6IgFQeo2CvN1OtUd3E7VBJyMjuKLrq6le4BBaiV5x5THXMAjeEbj5q7lJHwnu6wtUHURVlfm7LReLHwTRM3mPYnoT0DIExzRDqHtk7sw+3yBzn3j4g==; 5:ejbsrVNRtz021StAcz+QUqzIVJasgN9I5hMWvvVR3pXWxw3dnda7luJnUAS4XR6yIt8JP8GachGSw3ThjSfIKiXsG7Z5vxr4rPONNa2YcDa1fBqvFnangv3NJOhwTG5wAGe/qUbvMoF21ieKaTDQ/f/2sbdhOcSHsg8xpw3+0jI=; 7:hkRhfRP/QCncFfXwNZpYqD4Sv6Lg7yVnpART2DigGqbJbNHEgC7JB/eUwr/E2CGUym93bHYeKJzPjJjm6FHvabYXFS4ipNfjdaboE7QBar8r+AUTFw8AJalupeaJWKy9hhMr1Y5J0DUIApj74mVxCA== SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0838; 20:X1MmPS0CdC74DdcGzIll/VgeQ81qUn+NHgjpEjSR5utkBA561SiCIOnqTCvK22P3h4LSKr1XHmHVyrGvUCY9H7E08+eGtnmvTF8++nUHpu4uhighXdEs/VMjQoXH2FEY3JZSCxgju14dbH+Be+uCBZZdXFIXYaD2iza6BD8tbdQd+c7hI3zxhQwvfCse04Sr3XYFvZ+2DvVlWSKc8bc6QWnpFIM4ERaz5r0VWwRRCDMQcIXcNgERoLqW5JwDorGV X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Dec 2018 15:55:02.9889 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2ea0528a-9d31-429e-3bf1-08d65c5c59c8 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=[SATLEXCHOV02.amd.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR12MB0838 Subject: [Intel-gfx] [PATCH 04/10] drm/syncobj: add support for timeline point wait v8 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Chunming Zhou , Daniel Rakos , Bas Nieuwenhuizen , Dave Airlie , =?utf-8?q?Christian_K=C3=B6nig?= Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" 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.