From patchwork Tue Oct 23 09:37:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chunming Zhou X-Patchwork-Id: 10652893 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 34CEB14BD for ; Tue, 23 Oct 2018 09:38:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1543428DA5 for ; Tue, 23 Oct 2018 09:38:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 09BE829049; Tue, 23 Oct 2018 09:38:00 +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 7192828DA5 for ; Tue, 23 Oct 2018 09:37:59 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D542E6E18F; Tue, 23 Oct 2018 09:37:56 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from NAM01-SN1-obe.outbound.protection.outlook.com (mail-sn1nam01on0054.outbound.protection.outlook.com [104.47.32.54]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5B8156E0B4; Tue, 23 Oct 2018 09:37:55 +0000 (UTC) Received: from DM5PR12CA0003.namprd12.prod.outlook.com (2603:10b6:4:1::13) by BLUPR12MB0609.namprd12.prod.outlook.com (2a01:111:e400:594f::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1250.30; Tue, 23 Oct 2018 09:37:53 +0000 Received: from DM3NAM03FT012.eop-NAM03.prod.protection.outlook.com (2a01:111:f400:7e49::204) by DM5PR12CA0003.outlook.office365.com (2603:10b6:4:1::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1273.18 via Frontend Transport; Tue, 23 Oct 2018 09:37:52 +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 DM3NAM03FT012.mail.protection.outlook.com (10.152.82.116) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1273.13 via Frontend Transport; Tue, 23 Oct 2018 09:37:51 +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; Tue, 23 Oct 2018 04:37:50 -0500 From: Chunming Zhou To: Subject: [PATCH] drm: fix deadlock of syncobj v6 Date: Tue, 23 Oct 2018 17:37:45 +0800 Message-ID: <20181023093745.19060-1-david1.zhou@amd.com> X-Mailer: git-send-email 2.17.1 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)(2980300002)(428003)(199004)(189003)(8936002)(6666004)(8676002)(7696005)(14444005)(81166006)(498600001)(81156014)(6916009)(2351001)(54906003)(426003)(5820100001)(77096007)(356004)(86362001)(476003)(186003)(1857600001)(66574009)(2616005)(486006)(126002)(4326008)(50466002)(336012)(2870700001)(1076002)(105586002)(97736004)(104016004)(106466001)(36756003)(72206003)(68736007)(26005)(305945005)(53936002)(53416004)(47776003)(23676004)(5660300001)(2906002)(50226002); DIR:OUT; SFP:1101; SCL:1; SRVR:BLUPR12MB0609; H:SATLEXCHOV02.amd.com; FPR:; SPF:None; LANG:en; PTR:InfoDomainNonexistent; A:1; MX:1; X-Microsoft-Exchange-Diagnostics: 1; DM3NAM03FT012; 1:CNzmj1pXJbnk2Smy7LbGRHE0RFNFU0Mgz/u0MfEUAs73Bnw44kuDdDfbKumQKueCYHusea0NisgjQW4Sjz1xv9jZ0NfgqYpefmpHjg1DUShk2TvU+fFnAvIVD+xlBdqT X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 4e886128-c7a5-4f92-47fe-08d638cb3405 X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(5600074)(711020)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060); SRVR:BLUPR12MB0609; X-Microsoft-Exchange-Diagnostics: 1; BLUPR12MB0609; 3:gPBvrnlg3ddL+1/TEUp60VGe8QAz7DVYD53YjqXrOK2psuzWPoWfZLkeGPbnXFVN19eWe62fkonBLugMgjc6LAhLe8Wdz0LqQ/FBcm5B8cNvDVTuc7SQgU5VOeP18IE74OjtiffDtDoQe/bjCURoCctgq26yDdXwrbFdtsM/Svf+k3n/PThpHAmA7isWJfwBDVFgR0FYn9kHGNMwDbMvXFV6RtSkESuu2anvx5nFHr0wBCMl5A+XjlMSEK5+REaCeolnw3stxfVY6P6OPA6a2ttwSw7b/P3Ath1F7gCzduDai0a/Lw1BboRE8FaoTZJzCqot0KQudrED7B5/4LMRoYt4MoelCXe3FLlr6F5vjac=; 25:ys0TUTYhGuOPX7DJBLFBwSevvNsJYz3mtSD33aSZpMiYEKX2+xAYo2tkrFvoaCBj5Jd6nPastAV/yicesWpDh7YepQT+0V3teVI8KchFsa9CN02Thv/CeQ/OEk8gD3/h9ck+ka/+3m/C47uEIjHzIBHNHH8mzyrwFbn0HPwIz2V0NliLAMlWBLwwjybqrIvqFCKFdHd4waR9nW4OGVuvPxWMRHaCs3IkkQmUEqJ0XU/aTm1UPII8tFC38umYLvjEWQyU+4Zj0hwmZGVSrw9v5kAUz7Cn7pSvCwmUk5OaX4+mTAGchr6TCA3SlIuAMwlS/3/izL2tAf+VLDeAXDWHuw== X-MS-TrafficTypeDiagnostic: BLUPR12MB0609: X-Microsoft-Exchange-Diagnostics: 1; BLUPR12MB0609; 31:xc7RnYwzeLs1GdYqB9GAW6q3yXlSizKeTh4hZnb88qmlnmMJQjmDLe+CPMUlpG3JdO5M2nmtWnOPPUun8bUYIv/W0QtjCeP70pdNnU0e0fhd69wFzHkvgY7/Qr8UmCesn6LcJYDXA7f3mwXop1r2yYnDgmIjzh+CwlcBKR/VCl7diCIxC+saJpKFo7bv1rD+gTnwdHGERBJqvgJ4Zz+2tfZI91A3UpFMFhvqjjitYXo=; 20:gW4WJbigyxRqXiOC+B8fmebU5qSnC6+UXDayTtzeinUsHxcYzGOZ36+u4wNWC9/HoQ3Aq9GPSSzUrayUgk+ejAPZdAZx5Ds43pDPcZ9u1YIdGseQ1p/xly6KNR79CohFsl3HHokTgfCFgIH25IqQvKk2NGrletl/d/ri7eSPEJDPWQKN6LrW/5AWBaVfqkG+6c66lIlmUmkg0XzXFFH5wUV6+m1G9S7rFOerDwuG+L1r5yEFKbr5cP56dOoVEO6zZ3zTNiKZONndtaAa2vHlVnJUa6eH1pegE7vp7k+Ggn/D5uv3IGH9eaesYAnfIvgfw4QGBgVrvsd+EqlWykX/EvBmpbvBSB0V1iF4SxWqXXwMmXdOEBXmRwpsLmuCgOtn9aNALvOhN4i0JzVU/BZSVfo/LQSyOFsCDnYS/XsuXHhWtGbcpK5DrTeYMR/2pAGldUju8DbFuuTT4eV0MfPQwhDWOFHX42UAuv4ipsI9woC8BZoS9i9nUhe1k8JCMs3O X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110)(217544274631240)(788757137089); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(3002001)(10201501046)(93006095)(93003095)(3231355)(944501410)(52105095)(6055026)(148016)(149066)(150057)(6041310)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(201703131423095)(201703061421075)(201703161042150)(6042181)(201708071742011)(7699051)(76991095); SRVR:BLUPR12MB0609; BCL:0; PCL:0; RULEID:; SRVR:BLUPR12MB0609; X-Microsoft-Exchange-Diagnostics: 1; BLUPR12MB0609; 4:caeMjamwhURPJC0jvMTI9bvjEr/ujDazycw6l58Lxkzr6HMl0XQ6rxpFgp/uNKWpKTl/OZ1vCVn+fwidbp6p9IXDy0P1+G81l1L9zWGVxSWzMfDxjOEFqeZ3kJPqSqGovBN3d6nSWSsXHFCqveVOX/skyJ3fOs4qs/VAV9gc7COO2CkmrUs1WGlT/JXJjv0y6pPo41aVoX5CRp0EPU65E8QmTPZ7e/lZC6XHNrk5lKFgSD59ByWWVAj0576tECia8+ik6xLUxvVbDwt7qVaXNGW+w44W68mZ60WLS9+JAZ0s2wZI0U9bhSZLirKp4lhQMDYgEDPFQRRHeTjdGNVDuPCt+mZSOqNDyQFjo6s3CxomjZCDoDpSwqhziq/mughl X-Forefront-PRVS: 0834BAF534 X-Microsoft-Exchange-Diagnostics: =?utf-8?q?1=3BBLUPR12MB0609=3B23=3ACkeOnQ+?= =?utf-8?q?ecH8pCBz+ZrdTfuBC+0zPamD0qkjGcTwTEi1RuFq0Ff2IIBrUBBLWn0nJv2sCryaf?= =?utf-8?q?vEN/+CUJX4qgc2bvFQaTVQ7QsThmcvGBP05F2wG+amqiwqCz/VjGzluiMAipTTQzN?= =?utf-8?q?CCbgblYVJH2z9k2WNRfQ+w3imxNsI4sVM+VdzxdzFiotAP+nPqpq34mXR/X6uhgCP?= =?utf-8?q?2tM8/JPaZKbQcHN9y671UsVIdjakvFwqIdNgrTMDVa24NLj6u6fIwHa9aP0uv/yId?= =?utf-8?q?fGcBVmUI7l4PAcowNfDrv8liezf8tF+QNqOa/pNc4JGRjapGsN9elRffzcptGFkCY?= =?utf-8?q?vXRzUoSEgAFjsWyqSideVZ39hD/B7ZRq8nCR9Vjmxt7GFs8OdO1SR0Al9pa3SKQ0U?= =?utf-8?q?PHwKw4vfcO7CMmW2+FqsjzlDnRDDRXE4I/OX3pNWf9vq0SR3irITAoUeOpUBovDLO?= =?utf-8?q?93yITyn0tF5LNJcdv39kKQeSaPUjEQ2V2esgFA0c2oIkJtSjg2EZZFc/8llDO4pPw?= =?utf-8?q?tRyFJlJ48YUepNwyMYLrvbbDpmhwDjW4IW/aboz3F2y+bILYwyvIxG9kCmVYFRT+w?= =?utf-8?q?QZ7qnuG+pkwW2SfR/6TMWdVzHlumDmXJyHxngIbiTcPmIs6EZcmXcrxfcY8w2vPM/?= =?utf-8?q?RLxIpxS0Qc7GZ4kFrHRNlaDYeZTZc7udO0QYGh0iQH7+7whK0BV8CpT67+meA5YTh?= =?utf-8?q?+G+077DnBtp//Qpsi9lI3mTKlGq4FimkFvN7Nfy61s6itK3OwKO2ji+9B7R8T7YIi?= =?utf-8?q?C7pJHDmu35rMVFZzUT0fA7U2sgUCHAV0yfWV36q/dVQb8qKAEi5S53Xv/b0yfyPJE?= =?utf-8?q?3eOfoZzikcl+mlkybCnweXei3nm24EvsMwwpRYGA1pMlXGBJ9U12TI7zg1VOZCxY1?= =?utf-8?q?AkUNv6JUulPmWqMGqZsl0OZe9d2qr982hz6yAiR1m/XcNjN+bCsz7ZbKsWsxA3KKI?= =?utf-8?q?SwtCOgxYNRpkzdA0+ZFtq1xEAzV+BelUmz9h0UCAUoH3S9d8/9A1wJwayo59AuncR?= =?utf-8?q?xh1YiCMja6qkhmqQlcHE4pvwaYJqp7lZdTPFTRCQjObjiHxvGRJryNbxNy/hFXQ?= =?utf-8?q?=3D=3D?= X-Microsoft-Antispam-Message-Info: yJRZy1mc9CBlaKTZ8M9BTf920Q3SpJOkDKgDlr6yYCJYJmxyOB5UXj2qg6SYrpAAZanweyWkVAuiPbGY1oxzfmxoKUVBTYpvokIoCXOG/x+PbbPItqV+Hmmz10AsKEC5/zhgYGpZCLOxD270afxMgRaKe2S2LE10FODtNP+NMRJI4GDNQXq8MYoueyYbWEndMFBg0qK3gfVVRjm7SlNlYW+PrHUDCJwVBEFBInBURL8gCp5KHUoKCc7/9K5Oe2JYyaFrIEgbn4Kp4Cd+8yxRiBQEvrou2IUvrT/eOt/8DSx2xX7peypqYtR7Rlbb+jlYD4k4M0Rs0ECwRU4Q1RZi6c4mu8QHZ89cp0zIdeNfRQs= X-Microsoft-Exchange-Diagnostics: 1; BLUPR12MB0609; 6:kFCggbL8EU13oPcOtJhMwQABgkrJN7t0hJ4DsDOoGQOpi2m0lZn3xNSWjQVVrEWVYyItrYIhDzHtQ+T8sQiQ3cfddlRJ0/9ZAFUefHcNr2wS/umozizh9MYp30QUScpHSqbbjcpO1dVzI1l+8Zbi+VFwHU0DQQw7XYl32IZg47sZQ+sxermasVHVCdKwTKVmhO2yJODSw59KTe1fFfUGJX+Ru/5eFZafkitXgyFGZARPHiSWZtzXJ2n/RtaTrebN2txaaRdSfqTF2Ir9vAV6vP/XUcs/Ot7kr7XrZCk3fMYS2c9drOMxsgYxmPNJup+r1/TMNhHGXyW535sFZqiU667UBDTRoqGvi0ldrT6otZYcyGxDUsiPqMpc6nY/YZtwryQFI6/p4qq/IipPN61r7ogbLOEv6HN8ZD11KqT1PFv9MNuFnmNIX3ze8ZuMPkg1IDUa6RSB1P9vr0FqsOhkLw==; 5:/n5vuUycCC1AJ8fb0UJiBKZQ5iNN5qW9AyI2znWjdvxj9dxn91Q7+xIg3dahvQLLEzamokDiBNzTz5d3JlO2He0TBGaXjVd24e3j2LeOYMKfoR7yxfbUEnoDXVu3EeeFBsdIyOFsM3KGzfDrCUOhJSEr7ZkW991I0EjRBzyrBZk=; 7:IaBOwClnDDpeLZj+6UfxNmaTg/4OEYxpeMWgNlEjsr3lz1XX2nh/ym1jHi5VSvKwmfSDo1iS4UXEC76xK0PpD94Jqrhks25vkHD93zpsOSnbnCE027AqG/a3PrKvrC82rzkiO7YbYzSlLZypA9B+jfV5qKWNc+mmW4SOYbYt5oG9ktfSt4pyTBf8qfm8eCSO1ijuhNI8Q4TJV3YU+t9avfrVP4MSavA9de1NcQPYClI9NG67DjMn6qEh4Ap3r4/1 SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BLUPR12MB0609; 20:0JQ+csOuwSiomdOWP9UyFCMbbybkIO97c5+wgw938H/g5AVLuBdJ2cTQevkIRaimmbvl7MHJtNEeJ7Za74TIIy06ajDvL8Z6weai8O3ojMNoCEERhRkScHg/ujum3az5p84RAawWniEdKU+X8SzflEWoatioIn1bLD+WRwG43OSZTfVQQLmKVATewlmSiAabIOSRp8b6/6lh7bZiMRp9QDiAgugJjA3qPCVpp/6WgoISTshG+ctcmiEnim+6jZML X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Oct 2018 09:37:51.8656 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 4e886128-c7a5-4f92-47fe-08d638cb3405 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: BLUPR12MB0609 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: intel-gfx@lists.freedesktop.org, =?utf-8?q?Christian_K=C3=B6nig?= Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP v2: add a mutex between sync_cb execution and free. v3: clearly separating the roles for pt_lock and cb_mutex (Chris) v4: the cb_mutex should be taken outside of the pt_lock around this if() block. (Chris) v5: fix a corner case v6: tidy drm_syncobj_fence_get_or_add_callback up. (Chris) Tested by syncobj_basic and syncobj_wait of igt. Signed-off-by: Chunming Zhou Cc: Daniel Vetter Cc: Chris Wilson Cc: Christian König Cc: intel-gfx@lists.freedesktop.org Reviewed-by: Chris Wilson --- drivers/gpu/drm/drm_syncobj.c | 156 ++++++++++++++++------------------ include/drm/drm_syncobj.h | 8 +- 2 files changed, 81 insertions(+), 83 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 57bf6006394d..b7eaa603f368 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -106,6 +106,42 @@ struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private, } EXPORT_SYMBOL(drm_syncobj_find); +static struct dma_fence +*drm_syncobj_find_signal_pt_for_point(struct drm_syncobj *syncobj, + uint64_t point) +{ + struct drm_syncobj_signal_pt *signal_pt; + + if ((syncobj->type == DRM_SYNCOBJ_TYPE_TIMELINE) && + (point <= syncobj->timeline)) { + struct drm_syncobj_stub_fence *fence = + kzalloc(sizeof(struct drm_syncobj_stub_fence), + GFP_KERNEL); + + if (!fence) + return NULL; + spin_lock_init(&fence->lock); + dma_fence_init(&fence->base, + &drm_syncobj_stub_fence_ops, + &fence->lock, + syncobj->timeline_context, + point); + + dma_fence_signal(&fence->base); + return &fence->base; + } + + list_for_each_entry(signal_pt, &syncobj->signal_pt_list, list) { + if (point > signal_pt->value) + continue; + if ((syncobj->type == DRM_SYNCOBJ_TYPE_BINARY) && + (point != signal_pt->value)) + continue; + return dma_fence_get(&signal_pt->fence_array->base); + } + return NULL; +} + static void drm_syncobj_add_callback_locked(struct drm_syncobj *syncobj, struct drm_syncobj_cb *cb, drm_syncobj_func_t func) @@ -114,115 +150,71 @@ static void drm_syncobj_add_callback_locked(struct drm_syncobj *syncobj, list_add_tail(&cb->node, &syncobj->cb_list); } -static int drm_syncobj_fence_get_or_add_callback(struct drm_syncobj *syncobj, - struct dma_fence **fence, - struct drm_syncobj_cb *cb, - drm_syncobj_func_t func) +static void drm_syncobj_fence_get_or_add_callback(struct drm_syncobj *syncobj, + struct dma_fence **fence, + struct drm_syncobj_cb *cb, + drm_syncobj_func_t func) { - int ret; + u64 pt_value = 0; - ret = drm_syncobj_search_fence(syncobj, 0, 0, fence); - if (!ret) - return 1; + if (syncobj->type == DRM_SYNCOBJ_TYPE_BINARY) { + /*BINARY syncobj always wait on last pt */ + pt_value = syncobj->signal_point; - spin_lock(&syncobj->lock); - /* We've already tried once to get a fence and failed. Now that we - * 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 (!list_empty(&syncobj->signal_pt_list)) { - spin_unlock(&syncobj->lock); - drm_syncobj_search_fence(syncobj, 0, 0, fence); - if (*fence) - return 1; - spin_lock(&syncobj->lock); - } else { - *fence = NULL; - drm_syncobj_add_callback_locked(syncobj, cb, func); - ret = 0; + if (pt_value == 0) + pt_value += DRM_SYNCOBJ_BINARY_POINT; } - spin_unlock(&syncobj->lock); - return ret; + mutex_lock(&syncobj->cb_mutex); + spin_lock(&syncobj->pt_lock); + *fence = drm_syncobj_find_signal_pt_for_point(syncobj, pt_value); + spin_unlock(&syncobj->pt_lock); + if (!*fence) + drm_syncobj_add_callback_locked(syncobj, cb, func); + mutex_unlock(&syncobj->cb_mutex); } void drm_syncobj_add_callback(struct drm_syncobj *syncobj, struct drm_syncobj_cb *cb, drm_syncobj_func_t func) { - spin_lock(&syncobj->lock); + mutex_lock(&syncobj->cb_mutex); drm_syncobj_add_callback_locked(syncobj, cb, func); - spin_unlock(&syncobj->lock); + mutex_unlock(&syncobj->cb_mutex); } void drm_syncobj_remove_callback(struct drm_syncobj *syncobj, struct drm_syncobj_cb *cb) { - spin_lock(&syncobj->lock); + mutex_lock(&syncobj->cb_mutex); list_del_init(&cb->node); - spin_unlock(&syncobj->lock); + mutex_unlock(&syncobj->cb_mutex); } static void drm_syncobj_init(struct drm_syncobj *syncobj) { - spin_lock(&syncobj->lock); + spin_lock(&syncobj->pt_lock); syncobj->timeline_context = dma_fence_context_alloc(1); syncobj->timeline = 0; syncobj->signal_point = 0; init_waitqueue_head(&syncobj->wq); INIT_LIST_HEAD(&syncobj->signal_pt_list); - spin_unlock(&syncobj->lock); + spin_unlock(&syncobj->pt_lock); } static void drm_syncobj_fini(struct drm_syncobj *syncobj) { struct drm_syncobj_signal_pt *signal_pt = NULL, *tmp; - spin_lock(&syncobj->lock); + spin_lock(&syncobj->pt_lock); list_for_each_entry_safe(signal_pt, tmp, &syncobj->signal_pt_list, list) { list_del(&signal_pt->list); dma_fence_put(&signal_pt->fence_array->base); kfree(signal_pt); } - spin_unlock(&syncobj->lock); -} - -static struct dma_fence -*drm_syncobj_find_signal_pt_for_point(struct drm_syncobj *syncobj, - uint64_t point) -{ - struct drm_syncobj_signal_pt *signal_pt; - - if ((syncobj->type == DRM_SYNCOBJ_TYPE_TIMELINE) && - (point <= syncobj->timeline)) { - struct drm_syncobj_stub_fence *fence = - kzalloc(sizeof(struct drm_syncobj_stub_fence), - GFP_KERNEL); - - if (!fence) - return NULL; - spin_lock_init(&fence->lock); - dma_fence_init(&fence->base, - &drm_syncobj_stub_fence_ops, - &fence->lock, - syncobj->timeline_context, - point); - - dma_fence_signal(&fence->base); - return &fence->base; - } - - list_for_each_entry(signal_pt, &syncobj->signal_pt_list, list) { - if (point > signal_pt->value) - continue; - if ((syncobj->type == DRM_SYNCOBJ_TYPE_BINARY) && - (point != signal_pt->value)) - continue; - return dma_fence_get(&signal_pt->fence_array->base); - } - return NULL; + spin_unlock(&syncobj->pt_lock); } static int drm_syncobj_create_signal_pt(struct drm_syncobj *syncobj, @@ -249,14 +241,14 @@ static int drm_syncobj_create_signal_pt(struct drm_syncobj *syncobj, fences[num_fences++] = dma_fence_get(fence); /* timeline syncobj must take this dependency */ if (syncobj->type == DRM_SYNCOBJ_TYPE_TIMELINE) { - spin_lock(&syncobj->lock); + spin_lock(&syncobj->pt_lock); if (!list_empty(&syncobj->signal_pt_list)) { tail_pt = list_last_entry(&syncobj->signal_pt_list, struct drm_syncobj_signal_pt, list); fences[num_fences++] = dma_fence_get(&tail_pt->fence_array->base); } - spin_unlock(&syncobj->lock); + spin_unlock(&syncobj->pt_lock); } signal_pt->fence_array = dma_fence_array_create(num_fences, fences, syncobj->timeline_context, @@ -266,16 +258,16 @@ static int drm_syncobj_create_signal_pt(struct drm_syncobj *syncobj, goto fail; } - spin_lock(&syncobj->lock); + spin_lock(&syncobj->pt_lock); if (syncobj->signal_point >= point) { DRM_WARN("A later signal is ready!"); - spin_unlock(&syncobj->lock); + spin_unlock(&syncobj->pt_lock); goto exist; } signal_pt->value = point; list_add_tail(&signal_pt->list, &syncobj->signal_pt_list); syncobj->signal_point = point; - spin_unlock(&syncobj->lock); + spin_unlock(&syncobj->pt_lock); wake_up_all(&syncobj->wq); return 0; @@ -294,7 +286,7 @@ static void drm_syncobj_garbage_collection(struct drm_syncobj *syncobj) { struct drm_syncobj_signal_pt *signal_pt, *tmp, *tail_pt; - spin_lock(&syncobj->lock); + spin_lock(&syncobj->pt_lock); tail_pt = list_last_entry(&syncobj->signal_pt_list, struct drm_syncobj_signal_pt, list); @@ -315,7 +307,7 @@ static void drm_syncobj_garbage_collection(struct drm_syncobj *syncobj) } } - spin_unlock(&syncobj->lock); + spin_unlock(&syncobj->pt_lock); } /** * drm_syncobj_replace_fence - replace fence in a sync object. @@ -344,13 +336,14 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, drm_syncobj_create_signal_pt(syncobj, fence, pt_value); if (fence) { struct drm_syncobj_cb *cur, *tmp; + LIST_HEAD(cb_list); - spin_lock(&syncobj->lock); + mutex_lock(&syncobj->cb_mutex); list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) { list_del_init(&cur->node); cur->func(syncobj, cur); } - spin_unlock(&syncobj->lock); + mutex_unlock(&syncobj->cb_mutex); } } EXPORT_SYMBOL(drm_syncobj_replace_fence); @@ -386,11 +379,11 @@ drm_syncobj_point_get(struct drm_syncobj *syncobj, u64 point, u64 flags, if (ret < 0) return ret; } - spin_lock(&syncobj->lock); + spin_lock(&syncobj->pt_lock); *fence = drm_syncobj_find_signal_pt_for_point(syncobj, point); if (!*fence) ret = -EINVAL; - spin_unlock(&syncobj->lock); + spin_unlock(&syncobj->pt_lock); return ret; } @@ -500,7 +493,8 @@ int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, kref_init(&syncobj->refcount); INIT_LIST_HEAD(&syncobj->cb_list); - spin_lock_init(&syncobj->lock); + spin_lock_init(&syncobj->pt_lock); + mutex_init(&syncobj->cb_mutex); if (flags & DRM_SYNCOBJ_CREATE_TYPE_TIMELINE) syncobj->type = DRM_SYNCOBJ_TYPE_TIMELINE; else diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h index 5e8c5c027e09..29244cbcd05e 100644 --- a/include/drm/drm_syncobj.h +++ b/include/drm/drm_syncobj.h @@ -75,9 +75,13 @@ struct drm_syncobj { */ struct list_head cb_list; /** - * @lock: Protects syncobj list and write-locks &fence. + * @pt_lock: Protects pt list. */ - spinlock_t lock; + spinlock_t pt_lock; + /** + * @cb_mutex: Protects syncobj cb list. + */ + struct mutex cb_mutex; /** * @file: A file backing for this syncobj. */