From patchwork Sat May 28 15:25:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oded Gabbay X-Patchwork-Id: 9139457 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 222B96075C for ; Sat, 28 May 2016 15:26:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 064A42793B for ; Sat, 28 May 2016 15:26:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EF19F280B2; Sat, 28 May 2016 15:26:16 +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=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 797D82793B for ; Sat, 28 May 2016 15:26:16 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8A5F26E110; Sat, 28 May 2016 15:26:11 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x243.google.com (mail-wm0-x243.google.com [IPv6:2a00:1450:400c:c09::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id DFFCC6E110 for ; Sat, 28 May 2016 15:26:09 +0000 (UTC) Received: by mail-wm0-x243.google.com with SMTP id n129so8288979wmn.1 for ; Sat, 28 May 2016 08:26:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=SOd5J+WG8FXXTf9A2/EsnzzPaiQIp+oBeUcbLA0JR5Q=; b=Usd4Drq3NbQW+VJa+9uiuDq/84rmFBEkLDIiV2FgkpFFlZFX4cFM069mjSV7AVbKxu 6VBNTPcf+LN0kh0df1qOpW6Mc+MGZFsaf0ilUObVix4WDckSUsfN6Gynq8x68KQpPo4e EizyKCOgsN7uu3GbtPvr6iML51Vhv29OTXNNVo4h4dUvZA3ajBSWQoxxXl9v0Y0jwnWO uUBkonvBdBNSr+vfacMh96xvG5YUT7I0gzi2hBSUDb1N6h7pI3usw1kzqKppb7lj341T 1Djc6FB5TxDPgCfAdG1cd2QTXgSZ6kZ/9HSmRzEqJq5CUdlY/NunSt6FTtaRpZzlljWO Jn+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=SOd5J+WG8FXXTf9A2/EsnzzPaiQIp+oBeUcbLA0JR5Q=; b=A4mNKGZP9gBacN/avyp7Dz76KChRcbN/zG4nFrp8M1SfRGRhaGD2aWxJYQdA4i5XyK /QpHvpIug8EvEOTW7odxWHYEnMA8ecJZpMh9hXasG0W2wQhYkWFLAc9N0YLS6MGOmPMf gNUZvDXW3tMKZ52o/c1NaX4HS4an3kNSO7zb7eE0Tf+kXXuNY985/zR9HxDGyCNfKE2R +rkM5rD7AnFNHN0LbO2wgtEZheOi7VTS7lE/yYgIjDuCxkApIZLuWTdoe/V1sVWGeDud Z2UWMAD2EVunz4DSsylBMEKA4t24WYP9mIE9enkUr+8CnwP+sN1C/jetVo4BwxGXh3s+ YfiQ== X-Gm-Message-State: ALyK8tJIJtmOfkakeNaiC40Qae2PcBPNePRF53c+6P/kRUiodURZwEvsfD4ehSH5aClZOw== X-Received: by 10.194.221.37 with SMTP id qb5mr19053414wjc.171.1464449167931; Sat, 28 May 2016 08:26:07 -0700 (PDT) Received: from odedg-home.localdomain ([2.55.141.226]) by smtp.gmail.com with ESMTPSA id t3sm13996374wmf.20.2016.05.28.08.26.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 28 May 2016 08:26:07 -0700 (PDT) From: Oded Gabbay To: dri-devel@lists.freedesktop.org Subject: [PATCH v2 1/2] drm/amdkfd: unbind only existing processes Date: Sat, 28 May 2016 18:25:44 +0300 Message-Id: <1464449145-13227-1-git-send-email-oded.gabbay@gmail.com> X-Mailer: git-send-email 2.5.5 Cc: Stable X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP When unbinding a process from a device (initiated by amd_iommu_v2), the driver needs to make sure that process still exists in the process table. There is a possibility that amdkfd's own notifier handler - kfd_process_notifier_release() - was called before the unbind function and it already removed the process from the process table. v2: Because there can be only one process with the specified pasid, and because *p can't be NULL inside the hash_for_each_rcu macro, it is more reasonable to just put the whole code inside the if statement that compares the pasid value. That way, when we exit hash_for_each_rcu, we simply exit the function as well. Signed-off-by: Oded Gabbay CC: Stable --- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 60 +++++++++++++++++++------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index ac00579..a64bc61 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -404,42 +404,52 @@ void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid) idx = srcu_read_lock(&kfd_processes_srcu); + /* + * Look for the process that matches the pasid. If there is no such + * process, we either released it in amdkfd's own notifier, or there + * is a bug. Unfortunately, there is no way to tell... + */ hash_for_each_rcu(kfd_processes_table, i, p, kfd_processes) - if (p->pasid == pasid) - break; + if (p->pasid == pasid) { - srcu_read_unlock(&kfd_processes_srcu, idx); + srcu_read_unlock(&kfd_processes_srcu, idx); - BUG_ON(p->pasid != pasid); + pr_debug("Unbinding process %d from IOMMU\n", pasid); - mutex_lock(&p->mutex); + mutex_lock(&p->mutex); - if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid)) - kfd_dbgmgr_destroy(dev->dbgmgr); + if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid)) + kfd_dbgmgr_destroy(dev->dbgmgr); - pqm_uninit(&p->pqm); + pqm_uninit(&p->pqm); - pdd = kfd_get_process_device_data(dev, p); + pdd = kfd_get_process_device_data(dev, p); - if (!pdd) { - mutex_unlock(&p->mutex); - return; - } + if (!pdd) { + mutex_unlock(&p->mutex); + return; + } - if (pdd->reset_wavefronts) { - dbgdev_wave_reset_wavefronts(pdd->dev, p); - pdd->reset_wavefronts = false; - } + if (pdd->reset_wavefronts) { + dbgdev_wave_reset_wavefronts(pdd->dev, p); + pdd->reset_wavefronts = false; + } - /* - * Just mark pdd as unbound, because we still need it to call - * amd_iommu_unbind_pasid() in when the process exits. - * We don't call amd_iommu_unbind_pasid() here - * because the IOMMU called us. - */ - pdd->bound = false; + /* + * Just mark pdd as unbound, because we still need it + * to call amd_iommu_unbind_pasid() in when the + * process exits. + * We don't call amd_iommu_unbind_pasid() here + * because the IOMMU called us. + */ + pdd->bound = false; - mutex_unlock(&p->mutex); + mutex_unlock(&p->mutex); + + return; + } + + srcu_read_unlock(&kfd_processes_srcu, idx); } struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p)