From nobody Sat Oct 3 03:09:04 2026 Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) (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 D9DFF422542 for ; Thu, 6 Aug 2026 08:52:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786006358; cv=none; b=a1NfUyUrem4OPNKXbV9xzkxron/E3IxA3tKuTrTKxh1YFgPxf1y1FtSWjmTABpLk9fIrDk4CzHyolpIkM77ZNQCMvBbll6qZ83+JA3rH39yt5+hWByiJkt9FMKwvTXq458cwWh9fP/TwHW21RvzJYZR0hc/VWM1hWN7EU4YVfzs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786006358; c=relaxed/simple; bh=e7sdquLlvCULAa+1JlzkXezh2ApbuZGZ+Gf0EqM1BOo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MeyiNKlMn1vglChsEUhDWYyf/ckaSndSrhCG12KEvcs0ZEChBEEMlwDXxggCub86Q7jGBB3qvRHnPh4tzud5Ks+ll35M34g4Ril0HSdOpOraNEMovqjEVRaqqYEn/lKNvN5aI8WU5LaskCXPE3+Eu9lf+qwqsX5dql5nh3ueC5M= 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=XBFR6lC0; arc=none smtp.client-ip=209.85.128.44 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="XBFR6lC0" Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-4994d41ceb9so2149895e9.2 for ; Thu, 06 Aug 2026 01:52:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786006352; x=1786611152; 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:content-type; bh=43GMMFZoVTY8+U+Ee+riXD/46xoLgGatma6l0KI0k2A=; b=XBFR6lC0r+qchtQ6xzKSk2cZqNlhqh0TOaP+UsKP7xwMSCD0xh6jQxaGXMCKuvndNR N4QJlhk4p4uOmL6TGbNAaIbAzlk8e8uUgF9kExi52GdlRZp2LsO4haZWNBfCUZjnAgZg l0jGPeu2zf/Ur2qOp6JYGkVBoZ0pGy2vuw27OqDk4fPy+49fXVtG9pHwi69NGUnAnAnS Lj7sDDAjq6v4MyhEklSRfdO3plpILg5L6GxCP7aOIK/Sfj+SKdccUgb4iL853gqqlmvk ujGM3P7c4sK5AyQIRq3A8fLQApx6qe6iYlp9Lk9uwYR3A9fscv3o4xRVxtKCro/193DS /qYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786006352; x=1786611152; 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:content-type; bh=43GMMFZoVTY8+U+Ee+riXD/46xoLgGatma6l0KI0k2A=; b=XJWdOVx81+CsnYJSOHZ7VEp7fEKyKD5MZl5HQnmCfsLb9M9GWZvqOne+KKcaXPCGQT TONsNJ8ZmUuoOJcyu25JiJEnLKmseOxrxYGIYSQ0IMM9tV1oZGEmmyLwt91XcMTv6BqC dAp0j+VwFHXMlMwnjoCewIPCnrykUti7qCEAvB+Y4jU1I97/KHrvYEkclj4KCDN7+7NP E8uMQq1ClLy7uSvRAKFAHwVd3MP6Ov/ye9WzhDxo6TpqfX+6jD5MeX8uEMcZrxbKoDqk rolryvQEqBily5PkRsNhhoGlmYzvjnMEjKHmd9/jdJOrLbY1WKEh3e9xvO00EP8w+QcJ /8SA== X-Forwarded-Encrypted: i=1; AHgh+RrJXBf6J7lEN45aJBr5K0l2dnSy6K+HXsgvxCVhM9o8HRTg0alJM8Xbju0Xz6CXun/ZLrgJl1q6zXWEJkI=@vger.kernel.org X-Gm-Message-State: AOJu0Yw2rKUCFIhVnPXd3s3lRDejF9HoqMCdPC6RXS//3HGE2012SdhP Nh+js41/eXMt+PSlZf2ZDPVe6Jh6RVBhGmATL7S4KwAxevuvIdSGOpsq X-Gm-Gg: AR+sD10joCveFJ51Sfo/VWtV5oFOpCMU0Q3sYkjijtyrGj+FNypNkbyrKrF6N2BTzw6 e1/4gBY6yDmkdmmBpDOBWnCGROyUv4zsZ/Frdr9CEG8qaFb9uoLz3aBXPIm6WfpOL11T3u2R/n5 KSGs28QJZyQa8tnXzPgDj+sAdYFshF/OsPRbiLH/uw+Wqqm3IWbqeWsIeIJce3YuSb+HIZ1Lk9u HFuycoSCHwFJlgBW0sApFSbZ+jv4dSpHOinRM7z/TGLHzKWi2wBAjMDvDBJbAaZU7UjDwIPXyXs jETla7lkekN5vQpGQBnP0ftAMU6Ttn00RWHuSfRHCUdazyL1vGJFmFotJZdEwUo/7U9r/eJdpN+ FqBzmCCnk5AzJLuxxgvr8EzOlf2gIZyZ19n0ZmfnmXrAL2ALfMk21BrhcsFQ6DOJsjnp2sMGMY2 Bk6e+CbQKYq2zHeuBmRmLu4I7CMulR4UBQ8PVNC+mwz2S8B2EgKNHnqF5y+mEgPpqmEjSQy3L7J MzJu4kB70zWHh7/FpEkHdm6UgYNRK5KJFpiLqm0l0/tittf0xkvJZDJFl/0NSnsOA== X-Received: by 2002:a05:600c:b85:b0:495:4505:dad0 with SMTP id 5b1f17b1804b1-4994e7ba5efmr93074145e9.2.1786006351804; Thu, 06 Aug 2026 01:52:31 -0700 (PDT) Received: from Neo.taile6b6ba.ts.net (ip-109-193-028-127.um39.pools.vodafone-ip.de. [109.193.28.127]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4995420cb4esm45985355e9.2.2026.08.06.01.52.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Aug 2026 01:52:31 -0700 (PDT) From: Marek Czernohous To: nouveau@lists.freedesktop.org Cc: Lyude Paul , Danilo Krummrich , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/3] drm/nouveau/fifo/nv04: filter benign CACHE_ERROR from Mesa NV50 bind probe Date: Thu, 6 Aug 2026 10:52:26 +0200 Message-ID: <20260806085228.1848994-2-mczernohous@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260806085228.1848994-1-mczernohous@gmail.com> References: <20260806085228.1848994-1-mczernohous@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" From: Marek Czernohous The Mesa userspace driver issues a method-0x0060 / data-0xbeef02xx binding probe on Tesla GPUs that ends up triggering CACHE_ERROR in the PFIFO interrupt handler. The probe is harmless and recovers cleanly, but it floods dmesg at error level on every X/Wayland session start. Filter that specific pattern down to debug level so dmesg stays clean while real CACHE_ERROR conditions are still logged at error level. Tested on an Apple Mac mini Late 2009 (MCP79, NVAC 0xac080b1): dmesg has no CACHE_ERROR spam during normal operation, the previously visible beef02xx pattern now only appears at debug level. Assisted-by: Claude:claude-opus-5 Signed-off-by: Marek Czernohous --- .../gpu/drm/nouveau/nvkm/engine/fifo/nv04.c | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c b/drivers/gpu/= drm/nouveau/nvkm/engine/fifo/nv04.c index c4b8e567d86f..fa13cd55b593 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c @@ -327,12 +327,25 @@ nv04_fifo_intr_cache_error(struct nvkm_fifo *fifo, u3= 2 chid, u32 get) =20 if (!(pull0 & 0x00000100) || !nv04_fifo_swmthd(device, chid, mthd, data)) { - chan =3D nvkm_chan_get_chid(&fifo->engine, chid, &flags); - nvkm_error(subdev, "CACHE_ERROR - " - "ch %d [%s] subc %d mthd %04x data %08x\n", - chid, chan ? chan->name : "unknown", - (mthd >> 13) & 7, mthd & 0x1ffc, data); - nvkm_chan_put(&chan, flags); + /* + * Filter benign Mesa NV50 bind probe: mthd 0x0060 with + * data 0xbeef02xx is a harmless userspace probe on Tesla + * GPUs and does not indicate an actual error condition. + * Demote to debug to keep dmesg clean while still catching + * real CACHE_ERROR events. + */ + if ((mthd & 0x1ffc) =3D=3D 0x0060 && + (data & 0xffffff00) =3D=3D 0xbeef0200) { + nvkm_debug(subdev, "CACHE_ERROR - ch %d subc %d mthd %04x data %08x (be= nign, skipped)\n", + chid, (mthd >> 13) & 7, mthd & 0x1ffc, data); + } else { + chan =3D nvkm_chan_get_chid(&fifo->engine, chid, &flags); + nvkm_error(subdev, "CACHE_ERROR - " + "ch %d [%s] subc %d mthd %04x data %08x\n", + chid, chan ? chan->name : "unknown", + (mthd >> 13) & 7, mthd & 0x1ffc, data); + nvkm_chan_put(&chan, flags); + } } =20 nvkm_wr32(device, NV04_PFIFO_CACHE1_DMA_PUSH, 0); --=20 2.54.0 From nobody Sat Oct 3 03:09:04 2026 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (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 25F27421220 for ; Thu, 6 Aug 2026 08:52:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786006359; cv=none; b=g0A+1aCEM4o/XdpNbkhFOrWDUgX7d8QJrYnKnPsRdkMlsSWi4fOOuPMlneWlp/eT+MUni7bSptGsnjAUZ7b/3o78VCSN7mLA7Nkz21IDdCbqJ2iwHtwrUfQmosGk3x1N5GqNtFFfT10FHV1CpsS8mq0oahQ1LcuBYdhDtIpp+mk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786006359; c=relaxed/simple; bh=tuZdamJvRz33WaeY9ad3Zb1en0F8NCkpcVpFyRn25+Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u83Ze+AlNeUlHd94bhAzpMNWqXj2YL9AyG5CaUOtfNgPFXN+9RMLG866f8CjVNXrTZ2KrkTRtBzP07yEKwfwArgZsz/fLOJmzDOz1gpHf3eWdoMKfO9T34JJEeryPOVt2SPHwZeUDwjx5P7AyBclNJF+HnPr2AqTAkBocoFV1jc= 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=p23bJUKa; arc=none smtp.client-ip=209.85.128.42 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="p23bJUKa" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-4957739c22fso411105e9.3 for ; Thu, 06 Aug 2026 01:52:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786006353; x=1786611153; 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:content-type; bh=gH1ZijC9dBMRwcIQPOFxOSOLg1MiHZNn8LjvIG16PSY=; b=p23bJUKaDTbr39h/7hcdAeKUlvyfZeuQ4TYRLDRzjEdZYnUoQLYL00DcQL1HFS3PyV SPfvWuXzdCySr8NSXpmPi7Y0S1TmCkn+RsSOIjF3jDeR9a1Ij4xcO0+JLytUfQRBzG1+ khMNdBtLype6WbDD/kg9tW9xnIQnwJvIb2thsOd6boF9ZKsU+Mx8kvqeY6R27n93GnRA WFJGK/qWf0regkwW/DYD5hU9kA2l7quF2AqOI4gn1PvtLC8mSG+/uX0GZ1Xdvyc7a5+5 bKzu+PfHmlUrPc8LIJUVc8cjljeYCp6DHJkO5CuStMhy3JpHOYBi+VM69F4k6yKO8/w1 U75w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786006353; x=1786611153; 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:content-type; bh=gH1ZijC9dBMRwcIQPOFxOSOLg1MiHZNn8LjvIG16PSY=; b=S6HwCEmVp9QT+E3ITLNVEBiqS2kfOU3p612/Q1YV0c3RvHGn5ilcgwoMs7j/9wcI37 mZ+ZadfuYHSCu780GN1BRZVdblJ8YN7yI4KmJIHXntEVNl5TVH3WVzFLQX/3765ev62v 7bi2afpe+2TJ8yoEEya3pvRZ50n6DiNC+gqYDKHjkTGDG/KOet6LfNg8MzjKlVy6H9Hw 1wJTPadAh3U0zwfB4FOJOwQNYdgAeZBDFocswVJIPquFMbhyMgeSBh/RT4aFxRHxnpx7 YLt+OQU1vIVOTzkdFZgqxNv5cZ0dM1pa7PCHwNhOJUUxbLAIOPhsOLiGlpb9ooCGiv4K cKCQ== X-Forwarded-Encrypted: i=1; AHgh+RrtvielzAeKeYaXYXVHC+qn5WeytSKTZ0+gnndwAwpJ1sWq0Z9Hy/1gdB3sepUbKvC+8kVILVP8JEp5d3U=@vger.kernel.org X-Gm-Message-State: AOJu0YwxCJnjRUELpSWbMldn+UjLMJ9uM/tznzBBVEFU6ylkK8DB+Du5 6SJymWRweKxZnMyCCLNLMkMrHT8lEbdCFiLTxuh6k4SpXFahE30LQPOy X-Gm-Gg: AR+sD11B+WC1X8e8NJoQvaaNK01sjU/bMOJtT4NUkMJY9nwYLMSDZc6EABzQzrW82Al Nn7eFQwopMcdPTqDdK9TxkERCS6yQwhJ0oM3wExyEesx4GdORpaGidQ02h5we8kv8TTA6/T8JeN 4M4gUUI0Efvsn5deFBMGlFEuAkfAJBOPjBtCMa01kQ+ZxeIQcZcUuEYnBJS75efurjiatCwnaKg W32t1NmVVMBr/4XqRR3jmmhn2ZOpGUuDFpwPY0NZhf8Y9bpKokU2VmDp2dgcZknKhNZPhJtj6pf eJA9Tmwzqn6wb6jqwGp02oPkLah9i0NGaWe/HI/CH1QNHknUmXXgJjq5CtmPLBwY7Q2wcn+79B2 lGGlTIcxnKNf/TQwBggyC0K8YtnbLhWmf2641X6r0C1tQWcbOV0nNMt1r1D9+xWkJxt0Kr63fz+ Muzydrq1VncnVEVR1TSLAL0WuYKrq3brToeZV5UhyYPrO9rWqVZ94HN9Fqf9HVa4zBhwP2KnxzS KCss0ITu52fAPSGbT9rMfqbg2Mt2Mb21FuiY8V3zHjnQJae1VAvd/o= X-Received: by 2002:a05:600c:1549:b0:498:1371:660c with SMTP id 5b1f17b1804b1-4994e704bd5mr85555625e9.0.1786006352729; Thu, 06 Aug 2026 01:52:32 -0700 (PDT) Received: from Neo.taile6b6ba.ts.net (ip-109-193-028-127.um39.pools.vodafone-ip.de. [109.193.28.127]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4995420cb4esm45985355e9.2.2026.08.06.01.52.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Aug 2026 01:52:32 -0700 (PDT) From: Marek Czernohous To: nouveau@lists.freedesktop.org Cc: Lyude Paul , Danilo Krummrich , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/3] drm/nouveau: subscribe to channel-kill events on NV50 and newer Date: Thu, 6 Aug 2026 10:52:27 +0200 Message-ID: <20260806085228.1848994-3-mczernohous@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260806085228.1848994-1-mczernohous@gmail.com> References: <20260806085228.1848994-1-mczernohous@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" From: Marek Czernohous nouveau_channel_init() only subscribes to the channel-killed event for FERMI_CHANNEL_GPFIFO and newer. On NV50/Tesla the subscription therefore never happens, and nvkm_chan_error()'s NVKM_CHAN_EVENT_ERRORED is delivered into an empty notifier list. Today that is harmless, because nothing kills a channel on Tesla: the only nvkm_chan_error() callers are the Fermi and newer recovery paths. The next patch adds such a caller for Tesla, and without a subscriber the consequences are severe. nouveau_channel_killed() never runs, so nouveau_fence_context_kill() never runs either, and the pending fences of the killed channel are never signalled. Everything waiting on them waits forever: drm_atomic_helper_wait_for_fences() in the display commit tail waits uninterruptibly and without a timeout, and the TTM delayed delete workers wait in TASK_UNINTERRUPTIBLE. The user sees a frozen desktop on a machine that is otherwise alive; it stays that way for minutes until the fences time out, and a reboot clears it immediately. That is also a dma-fence contract violation: a fence must always be signalled, with an error if necessary. Lower the class gate to NV50_CHANNEL_GPFIFO. The nvkm side is already class neutral: the KILLED case hangs the notifier on runl->chid->event, which every fifo owns since the runlist rework, and nvkm_uchan_uevent() does not discriminate by class. Pre-NV50 chips keep the old behaviour, so NV04 to NV40 are unaffected. Assisted-by: Claude:claude-opus-5 Signed-off-by: Marek Czernohous --- drivers/gpu/drm/nouveau/nouveau_chan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouve= au/nouveau_chan.c index 598513f60449..1db9fbd81f5c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -363,7 +363,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 = vram, u32 gart) if (ret) return ret; =20 - if (chan->user.oclass >=3D FERMI_CHANNEL_GPFIFO) { + if (chan->user.oclass >=3D NV50_CHANNEL_GPFIFO) { DEFINE_RAW_FLEX(struct nvif_event_v0, args, data, sizeof(struct nvif_chan_event_v0)); struct nvif_chan_event_v0 *host =3D --=20 2.54.0 From nobody Sat Oct 3 03:09:04 2026 Received: from mail-wr1-f54.google.com (mail-wr1-f54.google.com [209.85.221.54]) (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 2C085421232 for ; Thu, 6 Aug 2026 08:52:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786006363; cv=none; b=OUy/fh2O4oEbVYHVRhuvUlODkiOA5ounbRAM4LLUylESUGd6UzyMUALez1HuMJGPs5nOdLWUsv5xjHjGrTGkRlbKC2BWyNTlCxWG63Z1FK/b9tEQbK7jgR/IvVQRCCFAcFyAFDYowtcxLMiaQ4jQyq2wNScxnurSgINrJFxKVRs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786006363; c=relaxed/simple; bh=/OlT7nCovesoR6EKSMoje4ZVXpYO7L/3vx9f2l08XT0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OTAkhdS5/7ExiEYvjexPfqzJyYk/oNNqBF1FmkbEIxE+QLM4H5uYqrAPtSamWvsrvH+PHIC+Z5U7SoCyRnsbecpZT3zodJjJVS8gW0PLIeip+9KPVe9i2HDB4lJu22a+BYTc/LWQuTjRLZlBUCKwN8XKBf4Z44mebVlXh1pqz3c= 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=qOfRfxRj; arc=none smtp.client-ip=209.85.221.54 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="qOfRfxRj" Received: by mail-wr1-f54.google.com with SMTP id ffacd0b85a97d-47f5d5dbf80so176524f8f.2 for ; Thu, 06 Aug 2026 01:52:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786006354; x=1786611154; 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:content-type; bh=khPuyJHv89zY4dZVkmNZIJYQNoyOM1lI8MsDyIAf3TY=; b=qOfRfxRjqA5jj47/jWx3U32nz61pnwmB9SvF8IA39rKJenEiA0uAnjzEZNNbUYbOkR UQfQ6DK8hT74jjtzUyRlTv8obqrQ4xYt+u09nbkdU4mwuilKWoIeg/s02c7Ll3WkSLti Uh+Eo5zP/Omvafv87W3vvc3D0gP38UnK6cC4FiSRmRFkY2pWbQ0PwExnpvkKjbGBfn/r 8nqdvAihVcXkFLnodGn0B5CYaAPXTndErh+xJuGCDUVh4CuMpWR7hVHlR9mamTW7Fc2C M+mEVZ/tRjOxqbliclGknNIfork5Fez5lF8TssicWhcI8QwMZj4RyQNUQGo1xecJVQPk VYxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786006354; x=1786611154; 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:content-type; bh=khPuyJHv89zY4dZVkmNZIJYQNoyOM1lI8MsDyIAf3TY=; b=hbNA31fGYVlLZkC30fQBwahTnP31c66fHrb6H6ItjdiG4XsrjgayiPrvr0j4fTGIii FlJH8HE/VdgBg+Eic0iNTZ33ErwJUSKPc8SjKDgXmlJIDmAQWZB2rNRxyPu3DjHJYmv6 Qq97JrDhXDO19fz4+lD5cQjj+CBgBqn1lXESzd/Jrn8DYhjKmhv/YuJtkLFfDoUdU0ly ogZcUb00bifpSGm4xVVhVmuBzL7oHeRMmNHUpkuiGNQSYBs3atYYJbTCiwQENB5ELDLM nQf6mAfzJM9FiDI9haYZ0WHY7DpdvgrnbBRN2aICLPmFyMgmTzYs+kVaQWoBCn6X1hIC bqiA== X-Forwarded-Encrypted: i=1; AHgh+RqUA4okvifcDU2iwhSrbo6PRrnBHjzQniB9gog/fQJ16PZ+vXmYibawySmfeIWnx71FeCTjpXXUU1V8+m8=@vger.kernel.org X-Gm-Message-State: AOJu0YwgclN6SkeoPOpJLowE0TWheptbbkFORVpAQlDWIKOQNNLyfAxy X0/IXUpQ5pS2fiY0YZvjy2JtT6yzV2Z+nxk1m0CtBlESTXc5lIJHeiSdAZPOAnSgNs8= X-Gm-Gg: AR+sD11Ml1nuMNsyxSPLhTU0Od80Lf5cz6aQxkwaKtUd6W6JkA5/rdbP4pRETQwC8ko 8LmYbm2F5Z+sbVEGUVtQozWx9Pe46+86I5VhjMtMXGnKgNE+vgBy3l8XDHiIvWjZppjDC2ojw6M nBJ20SqVjYyfI6YC9MTyoths2fZa8ek8daJUz6kMJxxZTbxbj699bWwQn0HBaCI7mQAqHbvrWss NdI14C+rKRfvnsxg+E8hGf+QAtPx5uewJPnlxmSWn+TMggyBxdGwQGEsQPJDjFzmYvGi+cyCkBl Spo3bG6ZEEBF+qqdxUnKSgUWV5hlqK4zCj7VBdFGJRwewYT7/Ef8mSQ6nfBTixVbBkUHerJZnKg 41ZsrS0Osx4zW8rsugIVENviQstqgWYW1PG6AaSR19WX/SGp4/BNhfAkSgSeco0kikQwigTrSOW oPriMNvvKRLZyH4E1gbQ+Drw3D0WJFzfb4lPtvcB3bZgdUftyxypXyZBPA5hbIOonJcXEW5nrsO 8A/rlBxEwFGoYTv4cZnUFdpyFd9ElTa6KXLPoLJX4pA9xhnCYFRgso= X-Received: by 2002:a05:600c:c8c:b0:495:7561:a9cc with SMTP id 5b1f17b1804b1-4994e7d5c76mr84278115e9.4.1786006353850; Thu, 06 Aug 2026 01:52:33 -0700 (PDT) Received: from Neo.taile6b6ba.ts.net (ip-109-193-028-127.um39.pools.vodafone-ip.de. [109.193.28.127]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4995420cb4esm45985355e9.2.2026.08.06.01.52.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Aug 2026 01:52:33 -0700 (PDT) From: Marek Czernohous To: nouveau@lists.freedesktop.org Cc: Lyude Paul , Danilo Krummrich , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/3] drm/nouveau/fifo: add recovery path for Tesla cache_error/dma_pusher Date: Thu, 6 Aug 2026 10:52:28 +0200 Message-ID: <20260806085228.1848994-4-mczernohous@gmail.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260806085228.1848994-1-mczernohous@gmail.com> References: <20260806085228.1848994-1-mczernohous@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" From: Marek Czernohous On Tesla / NV50 family chipsets (nv50, g84, g94, g98, mcp77, mcp79), FIFO fault handling in nv04_fifo_intr_cache_error() and nv04_fifo_intr_dma_pusher() logs the fault and resets hardware registers but leaves the offending channel running. Compared to Fermi and newer, which call nvkm_chan_error() from nvkm_runl_rc(), Tesla has no escalation at all: repeated faults on the same channel keep firing forever and there is no telemetry beyond dmesg. Add a shared recovery helper, nv04_fifo_recover(), that both interrupt handlers call after the existing logging and reset sequence. It implements two tiers: Tier-1: kill the channel with nvkm_chan_error(), but only after it has faulted NVKM_FIFO_KILL_COUNT times inside NVKM_FIFO_KILL_WINDOW_MS. The single PFIFO cache puller names the channel that is *resident* when the fault is noticed, not necessarily the one that caused it (see the comment in nv04_fifo_pause() about incorrect instance offsets), so one fault is not sufficient evidence to kill. Below the threshold the behaviour is unchanged from mainline: the method is skipped or the push segment dropped, and the channel resumes. Tier-2: after a burst of faults within a sliding window, request a device-wide drm_dev_wedged_event() so userspace can rebind the driver. Tier-2 is fed by every fault, including those Tier-1 lets pass. The per-channel streak is keyed on the channel object pointer, which is used purely as an identity token and never dereferenced. It is dropped in nvkm_chan_del() so that a channel id handed out again cannot inherit the streak of its predecessor. nvkm_chan_error() is called with preempt=3Dfalse. nv50 and g84 channels have no .preempt callback, so preempt=3Dtrue would dereference a NULL function pointer under chan->lock in interrupt context. Assisted-by: Claude:claude-opus-5 Signed-off-by: Marek Czernohous --- .../drm/nouveau/include/nvkm/engine/fifo.h | 31 +++ .../include/trace/events/nouveau_fifo.h | 58 ++++++ drivers/gpu/drm/nouveau/nouveau_drm.c | 29 +++ .../gpu/drm/nouveau/nvkm/engine/fifo/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/engine/fifo/base.c | 3 + .../gpu/drm/nouveau/nvkm/engine/fifo/chan.c | 14 ++ .../gpu/drm/nouveau/nvkm/engine/fifo/nv04.c | 4 + .../gpu/drm/nouveau/nvkm/engine/fifo/priv.h | 10 + .../drm/nouveau/nvkm/engine/fifo/recover.c | 176 ++++++++++++++++++ 9 files changed, 326 insertions(+) create mode 100644 drivers/gpu/drm/nouveau/include/trace/events/nouveau_fi= fo.h create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/fifo/recover.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/g= pu/drm/nouveau/include/nvkm/engine/fifo.h index 96c16cfccf16..973c3ee445dc 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h @@ -55,6 +55,36 @@ void nvkm_chan_put(struct nvkm_chan **, unsigned long ir= qflags); =20 struct nvkm_chan *nvkm_uchan_chan(struct nvkm_object *); =20 +#define NVKM_FIFO_WEDGE_RING_MAX 32 + +/* + * A channel is only killed once it has faulted NVKM_FIFO_KILL_COUNT times + * within NVKM_FIFO_KILL_WINDOW_MS. The PFIFO cache puller names the chan= nel + * that is resident when the fault is noticed, which is not necessarily th= e one + * that caused it, so a single fault is not sufficient evidence to kill. + */ +#define NVKM_FIFO_KILL_COUNT 3 +#define NVKM_FIFO_KILL_WINDOW_MS 10000 +#define NVKM_FIFO_KILL_CHID_MAX 128 + +struct nvkm_fifo_wedge { + spinlock_t lock; + u32 count; /* faults inside the win= dow */ + ktime_t ts[NVKM_FIFO_WEDGE_RING_MAX]; /* ring of fault timestam= ps */ + u32 head; /* ring head */ + struct work_struct work; /* schedules drm_dev_wedg= ed_event */ + atomic_t wedged; /* Tier-2 already fired? = */ + + /* Per-channel fault streak for the Tier-1 escalation. owner is an + * identity token for the channel object and is never dereferenced. + */ + struct { + void *owner; + ktime_t first; + u32 count; + } chfault[NVKM_FIFO_KILL_CHID_MAX]; +}; + struct nvkm_fifo { const struct nvkm_fifo_func *func; struct nvkm_engine engine; @@ -86,6 +116,7 @@ struct nvkm_fifo { =20 spinlock_t lock; struct mutex mutex; + struct nvkm_fifo_wedge wedge; }; =20 void nvkm_fifo_fault(struct nvkm_fifo *, struct nvkm_fault_data *); diff --git a/drivers/gpu/drm/nouveau/include/trace/events/nouveau_fifo.h b/= drivers/gpu/drm/nouveau/include/trace/events/nouveau_fifo.h new file mode 100644 index 000000000000..46d043a82850 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/trace/events/nouveau_fifo.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: MIT */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM nouveau + +#if !defined(_TRACE_NOUVEAU_FIFO_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_NOUVEAU_FIFO_H + +#include +#include + +TRACE_EVENT(nouveau_fifo_chan_killed, + TP_PROTO(struct drm_device *dev, u32 chid, u32 fault_type, u64 info), + TP_ARGS(dev, chid, fault_type, info), + TP_STRUCT__entry( + __string(devname, dev_name(dev->dev)) + __field(u32, chid) + __field(u32, fault_type) + __field(u64, info) + ), + TP_fast_assign( + __assign_str(devname); + __entry->chid =3D chid; + __entry->fault_type =3D fault_type; + __entry->info =3D info; + ), + TP_printk("dev=3D%s chid=3D%u fault=3D%s info=3D0x%llx", + __get_str(devname), + __entry->chid, + __entry->fault_type =3D=3D 0 ? "CACHE_ERROR" : "DMA_PUSHER", + __entry->info) +); + +TRACE_EVENT(nouveau_fifo_dev_wedged, + TP_PROTO(struct drm_device *dev, u32 fault_count, u32 window_ms), + TP_ARGS(dev, fault_count, window_ms), + TP_STRUCT__entry( + __string(devname, dev_name(dev->dev)) + __field(u32, fault_count) + __field(u32, window_ms) + ), + TP_fast_assign( + __assign_str(devname); + __entry->fault_count =3D fault_count; + __entry->window_ms =3D window_ms; + ), + TP_printk("dev=3D%s wedged after %u faults in %u ms", + __get_str(devname), + __entry->fault_count, + __entry->window_ms) +); + +#endif /* _TRACE_NOUVEAU_FIFO_H */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/nouveau/include/trace/eve= nts +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE nouveau_fifo +#include diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouvea= u/nouveau_drm.c index e16f59b00f6f..9a9278589a3a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -22,6 +22,8 @@ * Authors: Ben Skeggs */ =20 +#define CREATE_TRACE_POINTS + #include #include #include @@ -74,6 +76,9 @@ #include "nouveau_uvmm.h" #include "nouveau_sched.h" =20 +#include +#include + DECLARE_DYNDBG_CLASSMAP(drm_debug_classes, DD_CLASS_TYPE_DISJOINT_BITS, 0, "DRM_UT_CORE", "DRM_UT_DRIVER", @@ -111,6 +116,18 @@ MODULE_PARM_DESC(runpm, "disable (0), force enable (1)= , optimus only default (-1 static int nouveau_runtime_pm =3D -1; module_param_named(runpm, nouveau_runtime_pm, int, 0400); =20 +MODULE_PARM_DESC(fifo_wedge_count, + "FIFO faults within window before drm_dev_wedged_event " + "(0=3Ddisable Tier-2, max 32, default 10)"); +unsigned int nouveau_fifo_wedge_count =3D 10; +module_param_named(fifo_wedge_count, nouveau_fifo_wedge_count, uint, 0400); + +MODULE_PARM_DESC(fifo_wedge_window_ms, + "Sliding-window width in milliseconds for fifo_wedge_count " + "(default 60000)"); +unsigned int nouveau_fifo_wedge_window_ms =3D 60000; +module_param_named(fifo_wedge_window_ms, nouveau_fifo_wedge_window_ms, uin= t, 0400); + static struct drm_driver driver_stub; static struct drm_driver driver_pci; static struct drm_driver driver_platform; @@ -1495,6 +1512,18 @@ nouveau_drm_init(void) if (!nouveau_modeset) return 0; =20 + if (nouveau_fifo_wedge_count > NVKM_FIFO_WEDGE_RING_MAX) { + pr_warn("nouveau: fifo_wedge_count=3D%u exceeds max %u; clamping\n", + nouveau_fifo_wedge_count, NVKM_FIFO_WEDGE_RING_MAX); + nouveau_fifo_wedge_count =3D NVKM_FIFO_WEDGE_RING_MAX; + } + if (nouveau_fifo_wedge_window_ms < 100 || + nouveau_fifo_wedge_window_ms > 600000) { + pr_warn("nouveau: fifo_wedge_window_ms=3D%u out of range; resetting to 6= 0000\n", + nouveau_fifo_wedge_window_ms); + nouveau_fifo_wedge_window_ms =3D 60000; + } + nouveau_module_debugfs_init(); =20 #ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild b/drivers/gpu/= drm/nouveau/nvkm/engine/fifo/Kbuild index 376e9c3bcb1a..1ff29753731d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild @@ -5,6 +5,7 @@ nvkm-y +=3D nvkm/engine/fifo/chan.o nvkm-y +=3D nvkm/engine/fifo/chid.o nvkm-y +=3D nvkm/engine/fifo/runl.o nvkm-y +=3D nvkm/engine/fifo/runq.o +nvkm-y +=3D nvkm/engine/fifo/recover.o =20 nvkm-y +=3D nvkm/engine/fifo/nv04.o nvkm-y +=3D nvkm/engine/fifo/nv10.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/= drm/nouveau/nvkm/engine/fifo/base.c index 9dd924694306..a61183fa38af 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c @@ -337,6 +337,8 @@ nvkm_fifo_dtor(struct nvkm_engine *engine) struct nvkm_runl *runl, *runt; struct nvkm_runq *runq, *rtmp; =20 + nv04_fifo_wedge_fini(fifo); + if (fifo->userd.bar1) nvkm_vmm_put(nvkm_bar_bar1_vmm(engine->subdev.device), &fifo->userd.bar1= ); nvkm_memory_unref(&fifo->userd.mem); @@ -390,6 +392,7 @@ nvkm_fifo_new_(const struct nvkm_fifo_func *func, struc= t nvkm_device *device, fifo->timeout.chan_msec =3D 10000; spin_lock_init(&fifo->lock); mutex_init(&fifo->mutex); + nv04_fifo_wedge_init(fifo); =20 return nvkm_engine_ctor(&nvkm_fifo, device, type, inst, true, &fifo->engi= ne); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c b/drivers/gpu/= drm/nouveau/nvkm/engine/fifo/chan.c index 418a8918bcb8..79774c6460f4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c @@ -275,6 +275,20 @@ nvkm_chan_del(struct nvkm_chan **pchan) nvkm_gpuobj_del(&chan->ramfc); =20 if (chan->cgrp) { + struct nvkm_fifo *fifo =3D chan->cgrp->runl->fifo; + + /* Drop this channel's fault streak before the id is reused. */ + if (chan->id >=3D 0) { + typeof(&fifo->wedge.chfault[0]) cf =3D + &fifo->wedge.chfault[chan->id % NVKM_FIFO_KILL_CHID_MAX]; + unsigned long flags; + + spin_lock_irqsave(&fifo->wedge.lock, flags); + if (cf->owner =3D=3D chan) + cf->owner =3D NULL; + spin_unlock_irqrestore(&fifo->wedge.lock, flags); + } + nvkm_chid_put(chan->cgrp->runl->chid, chan->id, &chan->cgrp->lock); nvkm_cgrp_unref(&chan->cgrp); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c b/drivers/gpu/= drm/nouveau/nvkm/engine/fifo/nv04.c index fa13cd55b593..cb81941ecccd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c @@ -345,6 +345,8 @@ nv04_fifo_intr_cache_error(struct nvkm_fifo *fifo, u32 = chid, u32 get) chid, chan ? chan->name : "unknown", (mthd >> 13) & 7, mthd & 0x1ffc, data); nvkm_chan_put(&chan, flags); + nv04_fifo_recover(fifo, chid, NV04_FAULT_CACHE_ERROR, + ((u64)mthd << 32) | data); } } =20 @@ -410,6 +412,8 @@ nv04_fifo_intr_dma_pusher(struct nvkm_fifo *fifo, u32 c= hid) } nvkm_chan_put(&chan, flags); =20 + nv04_fifo_recover(fifo, chid, NV04_FAULT_DMA_PUSHER, state); + nvkm_wr32(device, 0x003228, 0x00000000); nvkm_wr32(device, 0x003220, 0x00000001); nvkm_wr32(device, 0x002100, NV_PFIFO_INTR_DMA_PUSHER); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h b/drivers/gpu/= drm/nouveau/nvkm/engine/fifo/priv.h index fff1428ef267..bf551906dcd4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h @@ -83,6 +83,16 @@ void nv04_chan_start(struct nvkm_chan *); void nv04_chan_stop(struct nvkm_chan *); void nv04_eobj_ramht_del(struct nvkm_chan *, int); =20 +/* Recovery helper for Tesla cache_error/dma_pusher (recover.c). */ +#define NV04_FAULT_CACHE_ERROR 0 +#define NV04_FAULT_DMA_PUSHER 1 + +void nv04_fifo_recover(struct nvkm_fifo *fifo, u32 chid, u32 fault_type, u= 64 info); +void nv04_fifo_wedge_init(struct nvkm_fifo *fifo); +void nv04_fifo_wedge_fini(struct nvkm_fifo *fifo); +extern unsigned int nouveau_fifo_wedge_count; +extern unsigned int nouveau_fifo_wedge_window_ms; + int nv10_fifo_chid_nr(struct nvkm_fifo *); =20 int nv50_fifo_chid_nr(struct nvkm_fifo *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/recover.c b/drivers/g= pu/drm/nouveau/nvkm/engine/fifo/recover.c new file mode 100644 index 000000000000..ea962ddf0bcb --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/recover.c @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: MIT +/* + * nv04_fifo_recover - shared recovery helper for Tesla cache_error and + * dma_pusher fault paths. + * + * Tier-1: kill the offending channel via nvkm_chan_error, but only once it + * has faulted repeatedly inside a short window. + * Tier-2: after a configurable burst of faults within a sliding time + * window, request a device-wide drm_dev_wedged_event so userspace + * can rebind the driver. + */ + +#include "priv.h" +#include "chan.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "nouveau_drv.h" +#include + +static struct drm_device * +nv04_fifo_drm_device(struct nvkm_fifo *fifo) +{ + struct nvkm_device *device =3D fifo->engine.subdev.device; + struct nouveau_drm *drm =3D dev_get_drvdata(device->dev); + + return (drm && drm->dev) ? drm->dev : NULL; +} + +void +nv04_fifo_recover(struct nvkm_fifo *fifo, u32 chid, u32 fault_type, u64 in= fo) +{ + struct drm_device *drm_dev =3D nv04_fifo_drm_device(fifo); + struct nvkm_chan *chan; + unsigned long flags; + ktime_t now, cutoff; + u32 i, count; + + chan =3D nvkm_chan_get_chid(&fifo->engine, chid, &flags); + if (chan) { + struct nvkm_fifo_wedge *w =3D &fifo->wedge; + typeof(&w->chfault[0]) cf =3D + &w->chfault[chid % NVKM_FIFO_KILL_CHID_MAX]; + ktime_t tnow =3D ktime_get(); + unsigned long wflags; + bool kill; + u32 seen; + + /* + * wedge.lock nests inside chan->cgrp->lock, which + * nvkm_chan_get_chid() holds until nvkm_chan_put(). The other + * users of wedge.lock take no channel lock, so there is no + * reverse ordering. + */ + if (atomic_read(&chan->errored)) { + /* + * The channel is already dead but can still be + * resident and fault again, because nv50 and g84 have + * no preempt and the handler re-enables the puller + * unconditionally. Do not restart its streak. + */ + nvkm_chan_put(&chan, flags); + goto tier2; + } + + spin_lock_irqsave(&w->lock, wflags); + if (cf->owner !=3D chan || + ktime_after(tnow, ktime_add_ms(cf->first, + NVKM_FIFO_KILL_WINDOW_MS))) { + cf->owner =3D chan; + cf->first =3D tnow; + cf->count =3D 0; + } + seen =3D ++cf->count; + kill =3D seen >=3D NVKM_FIFO_KILL_COUNT; + if (kill) + cf->owner =3D NULL; + spin_unlock_irqrestore(&w->lock, wflags); + + if (kill) { + if (drm_dev) + trace_nouveau_fifo_chan_killed(drm_dev, chid, + fault_type, info); + /* + * preempt must stay false: nv50 and g84 channels have + * no .preempt callback, so nvkm_chan_error() would + * dereference a NULL function pointer under a spinlock + * in interrupt context. + */ + nvkm_chan_error(chan, false); + } else { + nvkm_warn(&fifo->engine.subdev, + "ch %d fault %u/%u within %ums, resuming\n", + chid, seen, NVKM_FIFO_KILL_COUNT, + NVKM_FIFO_KILL_WINDOW_MS); + } + nvkm_chan_put(&chan, flags); + } + +tier2: + if (nouveau_fifo_wedge_count =3D=3D 0) + return; + + now =3D ktime_get(); + cutoff =3D ktime_sub_ms(now, nouveau_fifo_wedge_window_ms); + + spin_lock_irqsave(&fifo->wedge.lock, flags); + + /* Insert current first, then purge expired and count survivors. */ + fifo->wedge.ts[fifo->wedge.head] =3D now; + fifo->wedge.head =3D (fifo->wedge.head + 1) % NVKM_FIFO_WEDGE_RING_MAX; + + count =3D 0; + for (i =3D 0; i < NVKM_FIFO_WEDGE_RING_MAX; i++) { + if (!ktime_to_ns(fifo->wedge.ts[i])) + continue; + if (ktime_before(fifo->wedge.ts[i], cutoff)) + fifo->wedge.ts[i] =3D 0; + else + count++; + } + fifo->wedge.count =3D count; + + if (count >=3D nouveau_fifo_wedge_count) + schedule_work(&fifo->wedge.work); + + spin_unlock_irqrestore(&fifo->wedge.lock, flags); +} + +static void +nv04_fifo_wedge_work(struct work_struct *work) +{ + struct nvkm_fifo_wedge *w =3D container_of(work, struct nvkm_fifo_wedge, = work); + struct nvkm_fifo *fifo =3D container_of(w, struct nvkm_fifo, wedge); + struct drm_device *drm_dev =3D nv04_fifo_drm_device(fifo); + u32 fault_count; + + if (atomic_xchg(&w->wedged, 1) !=3D 0) + return; /* already wedged this cycle */ + + if (!drm_dev) + return; + + fault_count =3D w->count; + + dev_info(drm_dev->dev, + "nouveau: fifo wedged after %u faults in %u ms\n", + fault_count, nouveau_fifo_wedge_window_ms); + + trace_nouveau_fifo_dev_wedged(drm_dev, fault_count, + nouveau_fifo_wedge_window_ms); + + drm_dev_wedged_event(drm_dev, DRM_WEDGE_RECOVERY_REBIND, NULL); +} + +void +nv04_fifo_wedge_init(struct nvkm_fifo *fifo) +{ + memset(fifo->wedge.chfault, 0, sizeof(fifo->wedge.chfault)); + spin_lock_init(&fifo->wedge.lock); + INIT_WORK(&fifo->wedge.work, nv04_fifo_wedge_work); + atomic_set(&fifo->wedge.wedged, 0); +} + +void +nv04_fifo_wedge_fini(struct nvkm_fifo *fifo) +{ + cancel_work_sync(&fifo->wedge.work); +} --=20 2.54.0