]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
nouveau: fix disabling the nonstall irq due to storm code
authorDave Airlie <airlied@redhat.com>
Sun, 7 Sep 2025 02:52:54 +0000 (22:52 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 9 Sep 2025 16:58:22 +0000 (18:58 +0200)
[ Upstream commit 0ef5c4e4dbbfcebaa9b2eca18097b43016727dfe ]

Nouveau has code that when it gets an IRQ with no allowed handler
it disables it to avoid storms.

However with nonstall interrupts, we often disable them from
the drm driver, but still request their emission via the push submission.

Just don't disable nonstall irqs ever in normal operation, the
event handling code will filter them out, and the driver will
just enable/disable them at load time.

This fixes timeouts we've been seeing on/off for a long time,
but they became a lot more noticeable on Blackwell.

This doesn't fix all of them, there is a subsequent fence emission
fix to fix the last few.

Fixes: 3ebd64aa3c4f ("drm/nouveau/intr: support multiple trees, and explicit interfaces")
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
Link: https://lore.kernel.org/r/20250829021633.1674524-1-airlied@gmail.com
[ Fix a typo and a minor checkpatch.pl warning; remove "v2" from commit
  subject. - Danilo ]
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
[ Apply to drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga102.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c

index 22443fe4a39ff6e036279dde140932ab26f20a6c..d0092b293090f80b84509bf127b3a100cbfc6760 100644 (file)
@@ -352,6 +352,8 @@ nvkm_fifo_dtor(struct nvkm_engine *engine)
        mutex_destroy(&fifo->userd.mutex);
 
        nvkm_event_fini(&fifo->nonstall.event);
+       if (fifo->func->nonstall_dtor)
+               fifo->func->nonstall_dtor(fifo);
        mutex_destroy(&fifo->mutex);
 
        if (fifo->func->dtor)
index e74493a4569edb933e7d55c817709cb93e701a56..6848a56f20c076770cc3624499107f637733b68b 100644 (file)
@@ -517,19 +517,11 @@ ga100_fifo_nonstall_intr(struct nvkm_inth *inth)
 static void
 ga100_fifo_nonstall_block(struct nvkm_event *event, int type, int index)
 {
-       struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), nonstall.event);
-       struct nvkm_runl *runl = nvkm_runl_get(fifo, index, 0);
-
-       nvkm_inth_block(&runl->nonstall.inth);
 }
 
 static void
 ga100_fifo_nonstall_allow(struct nvkm_event *event, int type, int index)
 {
-       struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), nonstall.event);
-       struct nvkm_runl *runl = nvkm_runl_get(fifo, index, 0);
-
-       nvkm_inth_allow(&runl->nonstall.inth);
 }
 
 const struct nvkm_event_func
@@ -564,12 +556,26 @@ ga100_fifo_nonstall_ctor(struct nvkm_fifo *fifo)
                if (ret)
                        return ret;
 
+               nvkm_inth_allow(&runl->nonstall.inth);
+
                nr = max(nr, runl->id + 1);
        }
 
        return nr;
 }
 
+void
+ga100_fifo_nonstall_dtor(struct nvkm_fifo *fifo)
+{
+       struct nvkm_runl *runl;
+
+       nvkm_runl_foreach(runl, fifo) {
+               if (runl->nonstall.vector < 0)
+                       continue;
+               nvkm_inth_block(&runl->nonstall.inth);
+       }
+}
+
 int
 ga100_fifo_runl_ctor(struct nvkm_fifo *fifo)
 {
@@ -599,6 +605,7 @@ ga100_fifo = {
        .runl_ctor = ga100_fifo_runl_ctor,
        .mmu_fault = &tu102_fifo_mmu_fault,
        .nonstall_ctor = ga100_fifo_nonstall_ctor,
+       .nonstall_dtor = ga100_fifo_nonstall_dtor,
        .nonstall = &ga100_fifo_nonstall,
        .runl = &ga100_runl,
        .runq = &ga100_runq,
index 755235f55b3aca564d7d182b152251f53d131048..18a0b1f4eab76a435a987942afaff1043f367f2c 100644 (file)
@@ -30,6 +30,7 @@ ga102_fifo = {
        .runl_ctor = ga100_fifo_runl_ctor,
        .mmu_fault = &tu102_fifo_mmu_fault,
        .nonstall_ctor = ga100_fifo_nonstall_ctor,
+       .nonstall_dtor = ga100_fifo_nonstall_dtor,
        .nonstall = &ga100_fifo_nonstall,
        .runl = &ga100_runl,
        .runq = &ga100_runq,
index a0f3277605a5cf4e21d6501e23c07b4704c4be07..c5ecbcae29674a3c832e74fa8ebddbcd8b0501d7 100644 (file)
@@ -40,6 +40,7 @@ struct nvkm_fifo_func {
        void (*start)(struct nvkm_fifo *, unsigned long *);
 
        int (*nonstall_ctor)(struct nvkm_fifo *);
+       void (*nonstall_dtor)(struct nvkm_fifo *);
        const struct nvkm_event_func *nonstall;
 
        const struct nvkm_runl_func *runl;
@@ -198,6 +199,7 @@ extern const struct nvkm_fifo_func_mmu_fault tu102_fifo_mmu_fault;
 
 int ga100_fifo_runl_ctor(struct nvkm_fifo *);
 int ga100_fifo_nonstall_ctor(struct nvkm_fifo *);
+void ga100_fifo_nonstall_dtor(struct nvkm_fifo *);
 extern const struct nvkm_event_func ga100_fifo_nonstall;
 extern const struct nvkm_runl_func ga100_runl;
 extern const struct nvkm_runq_func ga100_runq;
index 3454c7d2950295843ea3e8ef4b53eacba8c11553..f978e49a4d546d66e822addc4d70354076a1edcf 100644 (file)
@@ -660,6 +660,7 @@ r535_fifo_new(const struct nvkm_fifo_func *hw, struct nvkm_device *device,
        rm->chan.func = &r535_chan;
        rm->nonstall = &ga100_fifo_nonstall;
        rm->nonstall_ctor = ga100_fifo_nonstall_ctor;
+       rm->nonstall_dtor = ga100_fifo_nonstall_dtor;
 
        return nvkm_fifo_new_(rm, device, type, inst, pfifo);
 }