From nobody Sun May 24 23:29:28 2026 Received: from mail-lf1-f53.google.com (mail-lf1-f53.google.com [209.85.167.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CC8EA3F0767 for ; Wed, 20 May 2026 15:17:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779290273; cv=none; b=BRkNx/BJ0OseFCZZp9UzNGbHv6dUEwk4/pwfPkTUYyv4+LD1Y98vrYHQUFO8wAmWSSgC519q/cofVwej5fOEbq964UeLIZDT3vCRCSSeY0BpFrSgBfPLV6lJkX/OIsgm/h3e3HdoXZVXhU98xwPjLiXPDGIuW6z98Ons+qvdBDE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779290273; c=relaxed/simple; bh=EFeEJkQiEqspN2K1pxO/W1A+nKY7wi9XdYP/GPgLqCs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QalsUdkEzoCUrhqBTYTuCuIvxzbKKy9E7FlTzm7pAwlEt/DrscoC4e8xuiNFTNw7q0PfADjESxT/ydLeh8bHuYxfK3ILK6/rg1tPwWW1aUyqbAdVRO3qW8KFVrpTY/6p5/Kq8strJYTXgSiNxJeWQ0+YJfSKI7JLt+2dPHDzDzI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=UwZfEvNn; arc=none smtp.client-ip=209.85.167.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UwZfEvNn" Received: by mail-lf1-f53.google.com with SMTP id 2adb3069b0e04-5a877510541so5971503e87.2 for ; Wed, 20 May 2026 08:17:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779290270; x=1779895070; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fyVPZSX7MwDddJkv/HM4B88jEPRd96zpfMtgKanmjaM=; b=UwZfEvNnrk71SErlbZYM0Z8OAgOvv9x5KsvbRBz9WIn2H8ODK0/PNId9vX+AuXpV3t +eLfPMMNLvQZRC03RSgVu8O+530mFVJ4ksizXHHz/SUtzLvPKm0M95RtuiD0U0rlvcFM 7eXi+kq/OF8znjlgZvQdmOkfuUSyi2FSOAWamQRGjqtsaV1nt3d51b/yLbZfSaGy+vvm jqtJCSQoJfL8ISaUkeKuWHocJJhQrutJ3OBW71BuWYnHwvV3wHqQud1ac85/AdL4ig73 UgPshFH1vfF0GIqz2Jqx3NHUAoXjtezhkT1dlJ0TwvI0DhVTNUAhk1F9vYY9kowQvpeq 9tmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779290270; x=1779895070; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=fyVPZSX7MwDddJkv/HM4B88jEPRd96zpfMtgKanmjaM=; b=KVs124HV7x4VRUknrUDnOUp4r5nU/yxKzhbkb0atK4QdLneMuM4jPkioXYbWXV6t+m 3bQttABwr8ZEXCdnNVeBVqWlRh1vCOS4tLeSWHXD6T3J71mezu7DpIQys2uq9c6Dopv7 HyybZV/iWpQZ/JCtun0Ib0zsa4F/BLyBOGCi6JImocTX7RrXol0iZxEEJbbYzwErq2YM LqqxSkn9s1TGdVpxIqxdhbFdN/uF4xC5+3v1SmZ3qIXPHb+PF7xEXS9TRM7LTBJExb6B eUw6qfzBZ6gLm2Zc+Gfled7zqBZDl45lUd/qDu2DVhTr+LHfrK+eTUPRBLtukNboUrhJ ud6A== X-Forwarded-Encrypted: i=1; AFNElJ+F3vMqacixo4PLB368bW2/i1U1uFwATRwo1KbFEiRI6YylCPGFOlnRKsljHZ2TkDfQyCHJXY/LeeFL5KU=@vger.kernel.org X-Gm-Message-State: AOJu0YxHoN6Wc4eCa4K5zVfZzBJClcb3EwzttSARI+PGJOxAYzjfFAnK 0fW7sCF12X6IjzMv01Y43aRkmRnLydnQsjV6gyU8IeAOL8nY3Be9UbTd X-Gm-Gg: Acq92OGQwthsFXHeQmEn1mfDnx1WjTE6xXKitAkS2e+alSQ5XK8isPqkZlgfmD4fyxv 4KPSfUgcAA7bSpBnlAF4zQguVq1ipdBGmOchEjOyC338qHhQMrlIgqUG/PGB1LTPFxjq7eX64UZ vn688VR8PCeY2Ei4+9/AX5PWQkd2WMux34bplaGqVU2tSmzMLIhxVxUGqTecFhGJyc47kwBevWH 4ySWFsDz67/5F/a6X62opd69lXq6arZLEakMLOZQNKte6poLlk0TsPfVjIudb/Y14n+79EKOG9p FrCr4WJnwsryL5GYTCM4MTZdJKOKgo+COZWesyUJtRr+eLESvaGlxpEgF27wynP0J4/GqXgl6kD M0P1bk6pzW8A1BDtdwszJP+dfj29cPGkQvI4qvJ9LOdepFE3n+69PCMd9ju+NrbpUSIZHiL7jRx NDbaPOIiu9bGGu7/w3jWbNfP551RoXFG0c X-Received: by 2002:a05:6512:1053:b0:5a3:ffed:8440 with SMTP id 2adb3069b0e04-5aa0e73d549mr8445759e87.12.1779290269709; Wed, 20 May 2026 08:17:49 -0700 (PDT) Received: from localhost ([188.234.148.119]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5a90f10c8b2sm5022470e87.17.2026.05.20.08.17.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 May 2026 08:17:49 -0700 (PDT) From: Mikhail Gavrilov To: amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Cc: Alex Deucher , =?UTF-8?q?Christian=20K=C3=B6nig?= , David Airlie , Simona Vetter , Pierre-Eric Pelloux-Prayer , Sumit Semwal , linux-media@vger.kernel.org, linaro-mm-sig@lists.linaro.org, Mikhail Gavrilov Subject: [PATCH v3 1/2] drm/amdgpu: convert amdgpu_vm_lock_by_pasid() to drm_exec Date: Wed, 20 May 2026 20:17:39 +0500 Message-ID: <20260520151741.50575-2-mikhail.v.gavrilov@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260520151741.50575-1-mikhail.v.gavrilov@gmail.com> References: <20260429143743.50743-1-mikhail.v.gavrilov@gmail.com> <20260520151741.50575-1-mikhail.v.gavrilov@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" amdgpu_vm_lock_by_pasid() looks up a VM by PASID and reserves its root PD with a bare amdgpu_bo_reserve(), returning the still-reserved root to the caller. A caller that then needs to reserve further BOs (for example the devcoredump IB dump) ends up nesting reservation_ww_class_mutex acquires without a ww_acquire_ctx, which lockdep flags as recursive locking. Convert the helper to take a drm_exec context and lock the root PD via amdgpu_vm_lock_pd() instead. Callers now run it inside a drm_exec_until_all_locked() loop and can lock additional BOs in the same ww ticket, so there is no nested ww_mutex acquire. The only existing caller, amdgpu_vm_handle_fault(), is updated accordingly. Its is_compute_context path, which previously dropped the root reservation around svm_range_restore_pages() and re-took it, now finalises the drm_exec context and re-initialises a fresh one; behaviour is otherwise unchanged. No functional change intended for the page-fault path. Signed-off-by: Mikhail Gavrilov --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 72 ++++++++++++++++++-------- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 3 +- 2 files changed, 51 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/a= mdgpu/amdgpu_vm.c index 9ba9de16a27a..3a22670b733f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2950,14 +2950,22 @@ int amdgpu_vm_ioctl(struct drm_device *dev, void *d= ata, struct drm_file *filp) } =20 /** - * amdgpu_vm_lock_by_pasid - return an amdgpu_vm and its root bo from a pa= sid, if possible. + * amdgpu_vm_lock_by_pasid - look up a VM by PASID and lock its root PD * @adev: amdgpu device pointer - * @root: root BO of the VM + * @root: out: reference to the VM's root BO, dropped by the caller * @pasid: PASID of the VM - * The caller needs to unreserve and unref the root bo on success. + * @exec: drm_exec context to lock the root PD in + * + * Must be called from within a drm_exec_until_all_locked() loop; the call= er + * runs drm_exec_retry_on_contention() afterwards and drops the *root + * reference once the drm_exec context is finalised. + * + * Return: the VM on success, or NULL if the PASID has no VM, the VM is be= ing + * torn down, or locking the root PD failed. */ struct amdgpu_vm *amdgpu_vm_lock_by_pasid(struct amdgpu_device *adev, - struct amdgpu_bo **root, u32 pasid) + struct amdgpu_bo **root, u32 pasid, + struct drm_exec *exec) { unsigned long irqflags; struct amdgpu_vm *vm; @@ -2971,9 +2979,11 @@ struct amdgpu_vm *amdgpu_vm_lock_by_pasid(struct amd= gpu_device *adev, if (!*root) return NULL; =20 - r =3D amdgpu_bo_reserve(*root, true); - if (r) - goto error_unref; + r =3D amdgpu_vm_lock_pd(vm, exec, 0); + if (r) { + amdgpu_bo_unref(root); + return NULL; + } =20 /* Double check that the VM still exists */ xa_lock_irqsave(&adev->vm_manager.pasids, irqflags); @@ -2981,16 +2991,12 @@ struct amdgpu_vm *amdgpu_vm_lock_by_pasid(struct am= dgpu_device *adev, if (vm && vm->root.bo !=3D *root) vm =3D NULL; xa_unlock_irqrestore(&adev->vm_manager.pasids, irqflags); - if (!vm) - goto error_unlock; + if (!vm) { + amdgpu_bo_unref(root); + return NULL; + } =20 return vm; -error_unlock: - amdgpu_bo_unreserve(*root); - -error_unref: - amdgpu_bo_unref(root); - return NULL; } =20 /** @@ -3013,20 +3019,32 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *a= dev, u32 pasid, { bool is_compute_context =3D false; struct amdgpu_bo *root; + struct drm_exec exec; uint64_t value, flags; struct amdgpu_vm *vm; int r; =20 - vm =3D amdgpu_vm_lock_by_pasid(adev, &root, pasid); - if (!vm) + drm_exec_init(&exec, 0, 0); + drm_exec_until_all_locked(&exec) { + vm =3D amdgpu_vm_lock_by_pasid(adev, &root, pasid, &exec); + drm_exec_retry_on_contention(&exec); + if (!vm) + break; + } + if (!vm) { + drm_exec_fini(&exec); return false; + } =20 is_compute_context =3D vm->is_compute_context; =20 if (is_compute_context) { - /* Unreserve root since svm_range_restore_pages might try to reserve it.= */ - /* TODO: rework svm_range_restore_pages so that this isn't necessary. */ - amdgpu_bo_unreserve(root); + /* Release the root PD lock since svm_range_restore_pages + * might try to take it. + * TODO: rework svm_range_restore_pages so that this isn't + * necessary. + */ + drm_exec_fini(&exec); =20 if (!svm_range_restore_pages(adev, pasid, vmid, node_id, addr >> PAGE_SHIFT, ts, write_fault)) { @@ -3036,9 +3054,17 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *ad= ev, u32 pasid, amdgpu_bo_unref(&root); =20 /* Re-acquire the VM lock, could be that the VM was freed in between. */ - vm =3D amdgpu_vm_lock_by_pasid(adev, &root, pasid); - if (!vm) + drm_exec_init(&exec, 0, 0); + drm_exec_until_all_locked(&exec) { + vm =3D amdgpu_vm_lock_by_pasid(adev, &root, pasid, &exec); + drm_exec_retry_on_contention(&exec); + if (!vm) + break; + } + if (!vm) { + drm_exec_fini(&exec); return false; + } } =20 addr /=3D AMDGPU_GPU_PAGE_SIZE; @@ -3076,7 +3102,7 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *ade= v, u32 pasid, r =3D amdgpu_vm_update_pdes(adev, vm, true); =20 error_unlock: - amdgpu_bo_unreserve(root); + drm_exec_fini(&exec); if (r < 0) dev_err(adev->dev, "Can't handle page fault (%d)\n", r); =20 diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/a= mdgpu/amdgpu_vm.h index d083d7aab75c..af292c2fc521 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -593,7 +593,8 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev,= u32 pasid, bool write_fault); =20 struct amdgpu_vm *amdgpu_vm_lock_by_pasid(struct amdgpu_device *adev, - struct amdgpu_bo **root, u32 pasid); + struct amdgpu_bo **root, u32 pasid, + struct drm_exec *exec); =20 void amdgpu_vm_set_task_info(struct amdgpu_vm *vm); =20 --=20 2.54.0 From nobody Sun May 24 23:29:28 2026 Received: from mail-lj1-f171.google.com (mail-lj1-f171.google.com [209.85.208.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9EB3A3F164C for ; Wed, 20 May 2026 15:17:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779290276; cv=none; b=FvA1jK8v6zeHzBxso+71HCTmV0s0+eJOOM+MJFK2VHiXTqduIJ1u5+kHPtgIVBNGYRhdr6SJS1Gkx+yM964Epjckt3+INpVVMe/LGCSFrw4gD/w9jtrMlBqMuyVP8Ow8qj5kPglVV8s7iGmD6L0X1RgFl4NCEt+H0jP70KNQBOc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779290276; c=relaxed/simple; bh=yyYIDlBPbEckI967SkQQlcDoVK3OrtWSzDlW5Mp01jA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ED4gtjUfuPfzHYwmELBDZzgY8prSsDr8pW5IYhjakygRlTeywY1q3XvjC8SZ/zMvMeeYrobQTvCqpb1FWiCo/Jt5svJwb3jFBg5kO+KRYkalllPF5Vm8lATktvXGgkfWWJ2g5fNnCNd+tpzQ8ZgGBrwACDUwAfnmb7L3wqrfW2c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=UpPgVhH1; arc=none smtp.client-ip=209.85.208.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UpPgVhH1" Received: by mail-lj1-f171.google.com with SMTP id 38308e7fff4ca-393d6025f99so56636541fa.0 for ; Wed, 20 May 2026 08:17:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779290272; x=1779895072; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=K81Nh8nBOwZaTCEqstpBUGuFaakdxNh2S8dsFKzzkkM=; b=UpPgVhH1JBNzF9GzP9W1t9qj2UfXMr9mzuzHMW6NM3rnm4PwBKKqA4WAhWknSNVaER jdp+baQQnhkKA0OQCAr37qcT0DbB2aOLqYkD9VOqiTlylVLqia9KMCxuQ8g9I+fbmnT/ Ex/IjVj/mp45YYWAVKdNP6LIedottKbe+ChEBIeRN/6sbqeL93KY9ElX1Py4JOHZAXHB LnUbHfzSgWd2KXKAgGs1PuNvt0a+ioBH1wnh88FSEVA79L/9HscjItx5eiEQKnYd8VsM Ez6F2pUj7Z+gXx1Y33OAhtijZ+R/If0FUtbneLdTlBifQELVP8PJ+kGmxLXYmKCqCJTz qdIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779290272; x=1779895072; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=K81Nh8nBOwZaTCEqstpBUGuFaakdxNh2S8dsFKzzkkM=; b=l8qr8opaCo/KnXgx4dt8+uux7rORahSoWbRjNCWN+6kAUr4E20J3Ir5zMZeL27tbCH 8bHoXrSKHKCNIqB8vYaB9uISM3wAbT6rMn1Hy0rTLdIcmass2a20ntJdvHj+9KM/MbBv ulaS6FWVmHv4J5nsJ0rZwGqL19ejVi8zQSQXEIs4FVQ4tzJfGPWjf8MOTCN91/ySm13C cHzR51M8qpVNDifigMb0k+gBEVT4IO2GILTJcdklZd7L4mSYIPSkvAAMiuPmrHZXzodS YvhP/7iarGuMJOxPzq6op6PaiD9HPbWSZG4azIKwMua5V1y5D1VEvH0dG5ePnduwFgdQ 6aYA== X-Forwarded-Encrypted: i=1; AFNElJ94/bz8rdY7VSWimxU9XHu5NedheF3L6FJLtNSI0PYnXQLUJe080aUnijskIZUr5+ryXiceRf+K2XTV1u4=@vger.kernel.org X-Gm-Message-State: AOJu0Yx7JFtzIvWgvdYWBYcJNhAwgIeOxOErFYC6Vb8+RggZmlHm/rIj gYYuUZmv9YeH/F7M6IfuNxQdQrAUjomZtXNK5TxkPX/KMKfoq72D3U/Q X-Gm-Gg: Acq92OESheJOqQpwXuUJn7h+Jd8qhoDcIGKCHFwIxIv/HtnDEG9PJavEizQNxf2rE1S Yem2gFYzmpc8O6Awr6zA4cRVy1tGOyOnY477aLaZSO0uWg+W5x0z4TuG6rNPz7qtS09EfwF0HqK 5VccJengCqyNtK+34okn5EqTjxihuYWGYlpgPzM0mCfWrpzkZ8LxG6c1lXdCqnO6BfpSEAGqAvr POFOds9PLTbzlFpFQl0tLpiZaBIjAaVsLB5iM3SQ1aLrvtsqRPJpvgxqLLjEy3rKjnuRYqSnRei waVmyEocW0b6JoZxGijZowCDaFSp4UWqRorUVmVPtat9dvFtBmNbJoQ0Tu/vs8rg6BqroYTtXtp 9y0iCM+qN3Oqmxahe8LbA1Q595sLHmi67lekgjvHETLsN+qXTPBF/JXy+lk+57J6FbCs4Dl1YrZ yFsnezcxKK1jbiJZB/SaqJQr9nCIPTulb3sPHJi2cAZXU= X-Received: by 2002:ac2:4e01:0:b0:5a4:b02:66b1 with SMTP id 2adb3069b0e04-5aa0de8aa10mr6131035e87.9.1779290271462; Wed, 20 May 2026 08:17:51 -0700 (PDT) Received: from localhost ([188.234.148.119]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5a90f10c8b2sm5022470e87.17.2026.05.20.08.17.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 May 2026 08:17:50 -0700 (PDT) From: Mikhail Gavrilov To: amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Cc: Alex Deucher , =?UTF-8?q?Christian=20K=C3=B6nig?= , David Airlie , Simona Vetter , Pierre-Eric Pelloux-Prayer , Sumit Semwal , linux-media@vger.kernel.org, linaro-mm-sig@lists.linaro.org, Mikhail Gavrilov Subject: [PATCH v3 2/2] drm/amdgpu: fix recursive ww_mutex acquire in amdgpu_devcoredump_format Date: Wed, 20 May 2026 20:17:40 +0500 Message-ID: <20260520151741.50575-3-mikhail.v.gavrilov@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260520151741.50575-1-mikhail.v.gavrilov@gmail.com> References: <20260429143743.50743-1-mikhail.v.gavrilov@gmail.com> <20260520151741.50575-1-mikhail.v.gavrilov@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable When dumping IB contents from a hung job, amdgpu_devcoredump_format() acquired the VM root PD's reservation via amdgpu_vm_lock_by_pasid() and then, for each IB, called amdgpu_bo_reserve() on the BO backing the IB. Both reservations are reservation_ww_class_mutex objects and neither used a ww_acquire_ctx, which trips lockdep: WARNING: possible recursive locking detected -------------------------------------------- kworker/u128:0 is trying to acquire lock: ffff88838b16e1f0 (reservation_ww_class_mutex){+.+.}-{4:4}, at: amdgpu_devcoredump_format+0x1594/0x23f0 [amdgpu] but task is already holding lock: ffff8882f82681f0 (reservation_ww_class_mutex){+.+.}-{4:4}, at: amdgpu_devcoredump_format+0x1594/0x23f0 [amdgpu] Possible unsafe locking scenario: CPU0 ---- lock(reservation_ww_class_mutex); lock(reservation_ww_class_mutex); *** DEADLOCK *** May be due to missing lock nesting notation Workqueue: events_unbound amdgpu_devcoredump_deferred_work [amdgpu] Call Trace: __ww_mutex_lock.constprop.0 ww_mutex_lock amdgpu_bo_reserve amdgpu_devcoredump_format+0x1594 [amdgpu] amdgpu_devcoredump_deferred_work+0xea [amdgpu] The two reservations are on different BOs in the captured trace, so the splat is a lockdep-correctness warning, not an observed deadlock. It becomes a real self-deadlock whenever the IB BO shares its dma_resv with the root PD (the always-valid case, see amdgpu_vm_is_bo_always_valid()): amdgpu_bo_reserve(abo) re-acquires the same ww_mutex without a ticket and blocks forever. With amdgpu.gpu_recovery=3D0 the timeout handler refires every ~2 s and each invocation produces this splat, drowning the kernel ring buffer. Now that amdgpu_vm_lock_by_pasid() takes a drm_exec context, lock the root PD and every IB BO together in a single drm_exec ticket. DRM_EXEC_IGNORE_DUPLICATES handles IB BOs that share a dma_resv (e.g. always-valid BOs, or two IBs backed by the same BO). Every lock is now a top-level acquire under one ww_acquire_ctx, so the recursive ww_mutex condition is gone, and the per-IB amdgpu_bo_reserve()/amdgpu_bo_unref() dance -- including a BO refcount leak on the amdgpu_bo_reserve() failure path -- is removed. Reproducer (~150 LoC libdrm_amdgpu): submit a single GFX IB containing PACKET3_INDIRECT_BUFFER chained at GPU VA 0 and wait for the fence. The TDR fires within ~10 s and the deferred coredump worker produces the splat above on every invocation; with this change applied the splat is gone. Fixes: 7b15fc2d1f1a ("drm/amdgpu: dump job ibs in the devcoredump") Suggested-by: Christian K=C3=B6nig Signed-off-by: Mikhail Gavrilov --- .../gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c | 103 ++++++++++++------ 1 file changed, 71 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c b/drivers/gpu= /drm/amd/amdgpu/amdgpu_dev_coredump.c index d386bc775d03..a9d8e03fad83 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c @@ -24,6 +24,7 @@ =20 #include #include +#include #include "amdgpu_dev_coredump.h" #include "atom.h" =20 @@ -214,13 +215,9 @@ amdgpu_devcoredump_format(char *buffer, size_t count, = struct amdgpu_coredump_inf struct drm_printer p; struct drm_print_iterator iter; struct amdgpu_vm_fault_info *fault_info; - struct amdgpu_bo_va_mapping *mapping; struct amdgpu_ip_block *ip_block; struct amdgpu_res_cursor cursor; - struct amdgpu_bo *abo, *root; - uint64_t va_start, offset; struct amdgpu_ring *ring; - struct amdgpu_vm *vm; u32 *ib_content; uint8_t *kptr; int ver, i, j, r; @@ -343,43 +340,84 @@ amdgpu_devcoredump_format(char *buffer, size_t count,= struct amdgpu_coredump_inf drm_printf(&p, "VRAM is lost due to GPU reset!\n"); =20 if (coredump->num_ibs) { - /* Don't try to lookup the VM or map the BOs when calculating the - * size required to store the devcoredump. + struct amdgpu_bo_va_mapping *mapping; + struct amdgpu_bo *root, *abo; + struct drm_exec exec; + struct amdgpu_vm *vm; + u64 va_start, offset; + bool locked =3D false; + + /* + * Lock the VM root PD and every IB BO together in a single + * drm_exec ticket. Reserving the IB BOs one by one while the + * root PD is held would be a recursive reservation_ww_class_mutex + * acquire without a ww_acquire_ctx, which trips lockdep and + * self-deadlocks for IB BOs that share their dma_resv with the + * root PD (always-valid BOs). + * + * Skip locking entirely on the sizing pass: it does not write + * IB content, so the size estimate doesn't depend on whether + * the BOs are reachable. */ - if (sizing_pass) - vm =3D NULL; - else - vm =3D amdgpu_vm_lock_by_pasid(adev, &root, coredump->pasid); + if (!sizing_pass) { + drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, + 1 + coredump->num_ibs); + drm_exec_until_all_locked(&exec) { + vm =3D amdgpu_vm_lock_by_pasid(adev, &root, + coredump->pasid, &exec); + drm_exec_retry_on_contention(&exec); + if (!vm) + break; + + for (int i =3D 0; i < coredump->num_ibs; i++) { + u64 pfn; + + va_start =3D coredump->ibs[i].gpu_addr & + AMDGPU_GMC_HOLE_MASK; + pfn =3D va_start / AMDGPU_GPU_PAGE_SIZE; + mapping =3D amdgpu_vm_bo_lookup_mapping(vm, pfn); + if (!mapping) + continue; + + abo =3D mapping->bo_va->base.bo; + r =3D drm_exec_lock_obj(&exec, &abo->tbo.base); + drm_exec_retry_on_contention(&exec); + if (r) + break; + } + if (r) + break; + } + if (vm && !r) + locked =3D true; + else + drm_exec_fini(&exec); + } + + for (int i =3D 0; i < coredump->num_ibs; i++) { + bool emit_content =3D sizing_pass; =20 - for (int i =3D 0; i < coredump->num_ibs && (sizing_pass || vm); i++) { ib_content =3D kvmalloc_array(coredump->ibs[i].ib_size_dw, 4, GFP_KERNEL); if (!ib_content) continue; =20 - /* vm=3DNULL can only happen when 'sizing_pass' is true. Skip to the - * drm_printf() calls (ib_content doesn't need to be initialized - * as its content won't be written anywhere). - */ - if (!vm) + if (!locked) goto output_ib_content; =20 va_start =3D coredump->ibs[i].gpu_addr & AMDGPU_GMC_HOLE_MASK; mapping =3D amdgpu_vm_bo_lookup_mapping(vm, va_start / AMDGPU_GPU_PAGE_= SIZE); if (!mapping) - goto free_ib_content; + goto output_ib_content; =20 - offset =3D va_start - (mapping->start * AMDGPU_GPU_PAGE_SIZE); - abo =3D amdgpu_bo_ref(mapping->bo_va->base.bo); - r =3D amdgpu_bo_reserve(abo, false); - if (r) - goto free_ib_content; + abo =3D mapping->bo_va->base.bo; + offset =3D va_start - mapping->start * AMDGPU_GPU_PAGE_SIZE; =20 if (abo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) { off =3D 0; =20 if (abo->tbo.resource->mem_type !=3D TTM_PL_VRAM) - goto unreserve_abo; + goto output_ib_content; =20 amdgpu_res_first(abo->tbo.resource, offset, coredump->ibs[i].ib_size_dw * 4, @@ -391,12 +429,13 @@ amdgpu_devcoredump_format(char *buffer, size_t count,= struct amdgpu_coredump_inf off +=3D cursor.size; amdgpu_res_next(&cursor, cursor.size); } + emit_content =3D true; } else { r =3D ttm_bo_kmap(&abo->tbo, 0, PFN_UP(abo->tbo.base.size), &abo->kmap); if (r) - goto unreserve_abo; + goto output_ib_content; =20 kptr =3D amdgpu_bo_kptr(abo); kptr +=3D offset; @@ -404,21 +443,21 @@ amdgpu_devcoredump_format(char *buffer, size_t count,= struct amdgpu_coredump_inf coredump->ibs[i].ib_size_dw * 4); =20 amdgpu_bo_kunmap(abo); + emit_content =3D true; } =20 output_ib_content: drm_printf(&p, "\nIB #%d 0x%llx %d dw\n", i, coredump->ibs[i].gpu_addr, coredump->ibs[i].ib_size_dw); - for (int j =3D 0; j < coredump->ibs[i].ib_size_dw; j++) - drm_printf(&p, "0x%08x\n", ib_content[j]); -unreserve_abo: - if (vm) - amdgpu_bo_unreserve(abo); -free_ib_content: + if (emit_content) { + for (int j =3D 0; j < coredump->ibs[i].ib_size_dw; j++) + drm_printf(&p, "0x%08x\n", ib_content[j]); + } kvfree(ib_content); } - if (vm) { - amdgpu_bo_unreserve(root); + + if (locked) { + drm_exec_fini(&exec); amdgpu_bo_unref(&root); } } --=20 2.54.0