From patchwork Tue Dec 11 10:34:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chunming Zhou X-Patchwork-Id: 10723437 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 BA17E1751 for ; Tue, 11 Dec 2018 10:35:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A690E2A0AA for ; Tue, 11 Dec 2018 10:35:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9A4492A0D7; Tue, 11 Dec 2018 10:35:37 +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 A681F2A0DC for ; Tue, 11 Dec 2018 10:35:36 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C8C0B6E090; Tue, 11 Dec 2018 10:35:35 +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-eopbgr680079.outbound.protection.outlook.com [40.107.68.79]) by gabe.freedesktop.org (Postfix) with ESMTPS id F13336E090; Tue, 11 Dec 2018 10:35:33 +0000 (UTC) Received: from MWHPR12CA0050.namprd12.prod.outlook.com (2603:10b6:300:103::12) by BY2PR12MB0055.namprd12.prod.outlook.com (2a01:111:e400:2c80::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1425.18; Tue, 11 Dec 2018 10:35:30 +0000 Received: from BY2NAM03FT045.eop-NAM03.prod.protection.outlook.com (2a01:111:f400:7e4a::208) by MWHPR12CA0050.outlook.office365.com (2603:10b6:300:103::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1404.19 via Frontend Transport; Tue, 11 Dec 2018 10:35:30 +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 BY2NAM03FT045.mail.protection.outlook.com (10.152.85.113) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1425.16 via Frontend Transport; Tue, 11 Dec 2018 10:35:29 +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; Tue, 11 Dec 2018 04:35:27 -0600 From: Chunming Zhou To: , , , Date: Tue, 11 Dec 2018 18:34:43 +0800 Message-ID: <20181211103449.25899-4-david1.zhou@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181211103449.25899-1-david1.zhou@amd.com> References: <20181211103449.25899-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)(136003)(376002)(396003)(346002)(39860400002)(2980300002)(428003)(199004)(189003)(105586002)(77096007)(26005)(6346003)(426003)(336012)(126002)(2616005)(476003)(11346002)(446003)(106466001)(186003)(76176011)(7696005)(23676004)(97736004)(81166006)(53416004)(2870700001)(81156014)(8676002)(316002)(110136005)(54906003)(5660300001)(50466002)(72206003)(478600001)(68736007)(5820100001)(47776003)(36756003)(8936002)(53936002)(4744004)(356004)(104016004)(2906002)(6666004)(2201001)(14444005)(50226002)(66574011)(4326008)(1076002)(305945005)(486006)(86362001)(21314003); DIR:OUT; SFP:1101; SCL:1; SRVR:BY2PR12MB0055; H:SATLEXCHOV01.amd.com; FPR:; SPF:None; LANG:en; PTR:InfoDomainNonexistent; A:1; MX:1; X-Microsoft-Exchange-Diagnostics: 1; BY2NAM03FT045; 1:2T6Y8u3y73m/9IIQT2THVo7aEiy7OxXVEZFBm9VuKGOW+38/weHETg/6/D0bElpK5cM8p1Cu3wVwfrtxjAElzBRj18TmuwzTGKxCn5VDFRsQfog/8qMr5w30W5D3J7rl X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b095f3ea-587e-40c6-1529-08d65f545f2a X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(2390098)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(2017052603328)(7153060); SRVR:BY2PR12MB0055; X-Microsoft-Exchange-Diagnostics: 1; BY2PR12MB0055; 3:JYGOxNBq/lvNZWAQiZR8mmnL/pKBTiF4X7iHmOvjjhkwdrOX+Vow6ywvWuaHUqLup9YJHifMI51MBdGGyrNA4nc+8JHgfn9X0nqYSrlkwMN9AAq8MrXJ/nRh5MKygrwvrujpwY50kXpK1eUhy1ieQM3//WGmoC5qhwwAMUa3o1Ys7jSdujYl2YYFDO9P2viuW0U+b879c37vD5KpQNp/r6mDusWZ62T3l4HGTnmGFGjcz+6pmPb1zNdzcryzGieFh0uMLoZm6MTCHuy0b00RUjgY7Pmy7EI6QDhdudW6QZdodtqqnYsWQpVHe3N0cHtwcQK1sUqF1ue/HDxrgsdgZm8ndIDh1fLdor7lbto7A1w=; 25:H9dLOUTMKz9eQjI1CugdyxUUZI2+dUMRmXa79BQGRNBpUGmYDXs7W2Vd8GtXdgPSVAF32a3X1hI5j+0whhBSq5r7WdmQ1rz+nKIJWxmWL6VjdSKp2IDgxGXzHNQf9EpKV6mvLkwR/EKuQ41zFSaU6Tkvvcyr6LSLDAsOM69X2IQnNTGKwSzDBNQ3WYgs887spL7MdO/DpqGoYz5l0sY+7E3WToGY8NCeyv+CR5WLRsR+9FagcMxgF31aDAL0N+gMhneLtVDjlMPHuXk5Q7hfRoUNgrvR4ldlNf1DU3AIss2GLB0WZjpmNW354FTnFYGoByv76FIsWZRRaaoEr3rRULDd4gqghHzndGHnlNxsgzg= X-MS-TrafficTypeDiagnostic: BY2PR12MB0055: X-Microsoft-Exchange-Diagnostics: 1; BY2PR12MB0055; 31:5GCyj0558sOdKxZkMX/YgMPt1W3xfS8FYQDv5C3bQW0CD4aTedtO5NMXCGzotXERylKuIH7U1oTWz8WR/Xb4ghsKpEdsVYZlVSSkoFhvGNQCrlXJNLf8Vcbu/jwZDxW3lF8wHDNqgD0u7fVknQo3Q7+ucC8Shtxj9lPBETs5MChU3y5hoyrwz6bBadpku+PPQ9pfhLa4Ig0+CMt4SMVAchVi/eYpzZv3FuNRm+VPZ8g=; 20:uTA+GbM2dnUCpTFlio3A+A7st9dwdndyHYzW9SYFozs5JpG2AvaJ7ZnTBrAg1E12LvknUjlFyhgW/jwupFtoqfgzh0tye2IuAnpAg3vBmAaJJJTX6FOEefVRlwNNK9Ii9xaikfEhbvUDIhpHDzqK9qoPzpla6HjCM06Bg2idJ/4GJO5zh70vcQ9xR41qnkH9PYYzKroqfk93UUf+0J5H9xmLa233JQjO+1dkyVwynIo6HEKLU62v+jxK+WDcTfC6lkugcNQvHgBmpfbBV5eee0lYv2SBdCwIizzp6vyBWGroPK7kLdl4KyB/QkLV/sjT3v340L7qS4a0VojdLQvaawG7seL0hWMZzGizkE0arf+0SdB2ierduwfXWLlWS5qHJwx+jPXKKE0IlliJ6qY5BibSktTfJ8iv4M1sdsPW5Netv5ikvWmt8tTcQe2CSHbiy57RYMeWcmPC8TRUNMzWvWJOEgKbgkBTgndUpEvIuD7yVaDOBT7i9SxbmGlzcZcb X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(3230017)(999002)(6040522)(2401047)(8121501046)(5005006)(3231472)(944501520)(52105112)(93006095)(93003095)(3002001)(10201501046)(6055026)(148016)(149066)(150057)(6041310)(20161123558120)(20161123562045)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(201708071742011)(7699051)(76991095); SRVR:BY2PR12MB0055; BCL:0; PCL:0; RULEID:; SRVR:BY2PR12MB0055; X-Microsoft-Exchange-Diagnostics: 1; BY2PR12MB0055; 4:5icJ8aEq9X0BW4lXVEzcnOP9nFg+gyBwgGwZ4c069cJM8exwrnkdlgXBuCsp49zyfhl6QTs1nybAvYQCniMTUCZQxA3rf9EUh/qwFNlsPXdrKYVzqtkv/nRL8otuXluWFnm8gpzJapfhcTCC2N81DxhRqZHJC4h4YV2fjOg3kh2XClWpEeIReEgIpPVnefg1ksD73NUZB3zRELVMNUuFv5+z+4oPVTolmziC6Jtd673h1UYXyqva/LcbCmjwMRy8B1S7AAvf4VSS7K2M/TVF4w== X-Forefront-PRVS: 08831F51DC X-Microsoft-Exchange-Diagnostics: =?utf-8?q?1=3BBY2PR12MB0055=3B23=3AvvDt4T2?= =?utf-8?q?O8KCUaHv4SboYxNKymXwP0NjBrWXZPUX0PJzCWgZ2yZ2ZS75sEFfzrR4LzbK+BNTv?= =?utf-8?q?QOQ6A4lNzCGVU7vncMgoosOSNXwevlQ3ZPWBoRgYDsnUx8kxnEJ6E7yHk5uKuSUzY?= =?utf-8?q?wAy+/ks2gpkAfUvgOC9cN46nKM5OzLLDT0HQIGpWLNRiMlW162VePwgKb9iccKvIQ?= =?utf-8?q?8kIQ+FCnIgJ/S73t6JnlT2GcJPyZbaZNnDaxtYIWELCJGwmfjRGMHrKKSRJANcnli?= =?utf-8?q?iNinr2ZDdukJyuM4ZI2XVqlMlPQHS1D1HwYBNs3Rw9DersXIjyvAL1vlXqHbFbrmO?= =?utf-8?q?0xJYQQs1keQmFw4w894oW4V9pcPFgdTs7exDzObrpx4rxfOEkNg6Szo29CXa3BE/2?= =?utf-8?q?qPZMoV6vD2cBOYqUnXElmjpAT82E0sS+qYkLDwgFsRD7yb0I4SaTHPuyz7cjOOfpN?= =?utf-8?q?rM4Q7ce6eEh2p/xUgVPV6XgaVYfWNkDrIbWYa5wIxVx8DuGfa/CV4DYE08GIPEEKe?= =?utf-8?q?dgW1DUUCNw+uBSh/muOkiDq3uikL56yzfhydAxOn9hHyPeHzwBO9i+9s8OeSGZQH0?= =?utf-8?q?4DzgoGfF/gsRMDxJuNBgAnpNJQUmrXXI9mKjDsYQ61nb38DzU7zOrJ5mT++qdttvR?= =?utf-8?q?o3Oqm4X4MpSyeTd5ege7XdZ09f3l6YhuGTD7+arxVT9fsQ3X07yMM692QcBOJjqVh?= =?utf-8?q?ZMOb8N7EvC3R2C/27OM4zV+LCWCWv6U3P5UJPCaLndM5HqOe/7oY+p2Ua1AZPB9or?= =?utf-8?q?QayyhmlwTULgY3MhVG961VevC8p805xoBnPDEy24nFbrCYI/xaNN/E+qyW3mqNF0F?= =?utf-8?q?6w3eh4KvCGsovNUPUkbC5h309DZWgdPbtQ44mIqeDxOqvozei//vXW0x+kzvIBYVf?= =?utf-8?q?0BQtK3fqguUg8vzrr+91ziUKElgu+IJcQscqTCsw3/5/UacOYT1IhBMz8J0YwbXnX?= =?utf-8?q?s6U9IRVWPzSW6XPRpDXs7mUDBNz2/oqxk8OP6DyMfutppSNFmDj1Rfy3kCsiLaB6D?= =?utf-8?q?rMtJBsXU7eSuHPJuk107xJcMMZCTa4D+12VkMr+hAxcRiKG1nbp75HISwiSAxCXS9?= =?utf-8?q?LI9QheCpsIlZsaHlZ0ZqDUJSteH/38iGuufzCymaEQ5DLpgxtInp4Li0J0BbHlhPp?= =?utf-8?q?on5u58WogwTzF4yT7vgb73I+Mwolkp+hjJInFikOMgmQI7p72xDe3HtV2/bC+ceve?= =?utf-8?q?QlSttPwwGX9mABTgYk12597O2BI5mUo1akbW9WjIFFH+8nPLzfo6l/8B7ZuHEIKRh?= =?utf-8?q?Pz8k50h8xAuaBqaY=3D?= X-Microsoft-Antispam-Message-Info: I4BLd9ZK+Ne9KGI8WU4dllRU9h9OHVsH1ym1o0OOPjFRNTwAYoP7ZdJvjam223q3Al6EmoOpTAhyDIkxzYdVFm+lGFJAKMR/apLLjGKvdI7U1fhxy+JKhMap80BV4DlVexJSaP/+avYcHePNC+PoQAFu++hdiHwu1zKxkL32LsBPRKGLJqcJLGfKA/oUeboisZlLHRqGZvNk8RlwEnIZYxrSyqlOeo4yiskBx1aCBhgWDzR0zP2vBSQHByklB41XuL+stXGKdvcfmanL7mzQ5lAbnIjX/npT4bFx33/8Lm/XZ2J1UGSc6zYJOSTJadOp X-Microsoft-Exchange-Diagnostics: 1; BY2PR12MB0055; 6:Ft8AoZtaePqKC8xnKgd8NDHKLrU0yZap7aiUzXR91B0F8w5nvu8wv4jyc1cZQXpXtBvqDzL7h3dMNyqggW6oO58n69EkYOTIWgbjvaVWNf7Qsf+fZjLJXPkb6epczn5mroHVtBOveLa5wc/0vFeSlb1a1CtjLVSZikn2Fsuk1sfdbGmt+r8IfRs1M1SbyvToyiyxqNAAxNpyqVWcyyfCereuSjlAZm+n482qKh6mCtn0cF4LqKollxCntY/gu5thKLZ/ZCBvKY9jJz4k0i1WybJUCGiRKJU+7q9IWYp9uX0FtWZN7cbDMdQkVbsn2LX9VIX8iv0vh3yk9hcmu7EM0Ce3WMAIAYRkqqAqnv/yjmQ0lpRUESxey7KaZMarZPDKEfWYkXAMkhSkA5tBNLfsFM7inwxReLY3uq7eQu0THxlcAZUuiFvd4gwqBu2yjs+YFj9UZRVsxe2T/gsBHxwTNTpEqcmA6NxE6q49TANRDQ8=; 5:u+rB3ARRvBWMCN7G5cvBhmWaq04SoozyrX0jkWePCJVA9lWNB1SQGXbia/y6BJWZiD5q+G/jaV1v69r3kdvhi+GgI1VpulLFT9mEKgawTl/vgGt8Q1iqBJJu9fz7m14PYUESzQ7MfW0VMlXNmh5PUgRqlxfCeUG4ykWIQy4XzCY=; 7:5CKv16VithLWVJWM0yw3jrwKthu4PP5Lp6j/5TbjTF8pq2609eExVCGAknw8BvQrLGQweQeeCScxV0bqvtrpLxhDPsFkeDhA6f6PcrcNnAKwUxGmkcZHiU4l3YJ5x2f4uJgNh6ewpCqfuyDHJrSDqA== SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BY2PR12MB0055; 20:8Bla1uhQr5S0FupIvHF2q4FAB9weynISJ769YJ2wfx0xt8Q6EQPt8iWFMODoLwnVZsP7wuU+cfHSHIfDbkpGqtexboE+54sVYka+oXJEx8cqtwEYTFP6Rrs6Opg3CW65nPgonGODwbSuFmL4vQbK2RDsXP+hZ6XJSG9C16kcLzl2i8h2rxUjPmvimXoQoAabjDoL5nBC/qi/0ZZcvDpXRS1vyN3OfpccZrd1/Vg1nLRjt0G0lTJWWhWztjqfuFFV X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Dec 2018 10:35:29.6113 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b095f3ea-587e-40c6-1529-08d65f545f2a 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: BY2PR12MB0055 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 2b8a744fbbb6..532d7d3c98cd 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); } @@ -147,10 +154,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.