Loading drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +14 −4 Original line number Diff line number Diff line Loading @@ -66,19 +66,29 @@ nvkm_fifo_chan_put(struct nvkm_fifo *fifo, unsigned long flags, } struct nvkm_fifo_chan * nvkm_fifo_chan_inst(struct nvkm_fifo *fifo, u64 inst, unsigned long *rflags) nvkm_fifo_chan_inst_locked(struct nvkm_fifo *fifo, u64 inst) { struct nvkm_fifo_chan *chan; unsigned long flags; spin_lock_irqsave(&fifo->lock, flags); list_for_each_entry(chan, &fifo->chan, head) { if (chan->inst->addr == inst) { list_del(&chan->head); list_add(&chan->head, &fifo->chan); *rflags = flags; return chan; } } return NULL; } struct nvkm_fifo_chan * nvkm_fifo_chan_inst(struct nvkm_fifo *fifo, u64 inst, unsigned long *rflags) { struct nvkm_fifo_chan *chan; unsigned long flags; spin_lock_irqsave(&fifo->lock, flags); if ((chan = nvkm_fifo_chan_inst_locked(fifo, inst))) { *rflags = flags; return chan; } spin_unlock_irqrestore(&fifo->lock, flags); return NULL; } Loading drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +20 −4 Original line number Diff line number Diff line Loading @@ -435,6 +435,7 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit) struct nvkm_fifo_chan *chan; unsigned long flags; char gpcid[8] = "", en[16] = ""; int engn; er = nvkm_enum_find(fifo->func->fault.reason, reason); eu = nvkm_enum_find(fifo->func->fault.engine, unit); Loading Loading @@ -476,7 +477,8 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit) snprintf(en, sizeof(en), "%s", eu->name); } chan = nvkm_fifo_chan_inst(&fifo->base, (u64)inst << 12, &flags); spin_lock_irqsave(&fifo->base.lock, flags); chan = nvkm_fifo_chan_inst_locked(&fifo->base, (u64)inst << 12); nvkm_error(subdev, "%s fault at %010llx engine %02x [%s] client %02x [%s%s] " Loading @@ -487,9 +489,23 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit) (u64)inst << 12, chan ? chan->object.client->name : "unknown"); if (engine && chan) gk104_fifo_recover(fifo, engine, (void *)chan); nvkm_fifo_chan_put(&fifo->base, flags, &chan); /* Kill the channel that caused the fault. */ if (chan) gk104_fifo_recover_chan(&fifo->base, chan->chid); /* Channel recovery will probably have already done this for the * correct engine(s), but just in case we can't find the channel * information... */ for (engn = 0; engn < fifo->engine_nr && engine; engn++) { if (fifo->engine[engn].engine == engine) { gk104_fifo_recover_engn(fifo, engn); break; } } spin_unlock_irqrestore(&fifo->base.lock, flags); } static const struct nvkm_bitfield gk104_fifo_pbdma_intr_0[] = { Loading drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h +3 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,9 @@ void nvkm_fifo_cevent(struct nvkm_fifo *); void nvkm_fifo_kevent(struct nvkm_fifo *, int chid); void nvkm_fifo_recover_chan(struct nvkm_fifo *, int chid); struct nvkm_fifo_chan * nvkm_fifo_chan_inst_locked(struct nvkm_fifo *, u64 inst); struct nvkm_fifo_chan_oclass; struct nvkm_fifo_func { void *(*dtor)(struct nvkm_fifo *); Loading Loading
drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +14 −4 Original line number Diff line number Diff line Loading @@ -66,19 +66,29 @@ nvkm_fifo_chan_put(struct nvkm_fifo *fifo, unsigned long flags, } struct nvkm_fifo_chan * nvkm_fifo_chan_inst(struct nvkm_fifo *fifo, u64 inst, unsigned long *rflags) nvkm_fifo_chan_inst_locked(struct nvkm_fifo *fifo, u64 inst) { struct nvkm_fifo_chan *chan; unsigned long flags; spin_lock_irqsave(&fifo->lock, flags); list_for_each_entry(chan, &fifo->chan, head) { if (chan->inst->addr == inst) { list_del(&chan->head); list_add(&chan->head, &fifo->chan); *rflags = flags; return chan; } } return NULL; } struct nvkm_fifo_chan * nvkm_fifo_chan_inst(struct nvkm_fifo *fifo, u64 inst, unsigned long *rflags) { struct nvkm_fifo_chan *chan; unsigned long flags; spin_lock_irqsave(&fifo->lock, flags); if ((chan = nvkm_fifo_chan_inst_locked(fifo, inst))) { *rflags = flags; return chan; } spin_unlock_irqrestore(&fifo->lock, flags); return NULL; } Loading
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +20 −4 Original line number Diff line number Diff line Loading @@ -435,6 +435,7 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit) struct nvkm_fifo_chan *chan; unsigned long flags; char gpcid[8] = "", en[16] = ""; int engn; er = nvkm_enum_find(fifo->func->fault.reason, reason); eu = nvkm_enum_find(fifo->func->fault.engine, unit); Loading Loading @@ -476,7 +477,8 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit) snprintf(en, sizeof(en), "%s", eu->name); } chan = nvkm_fifo_chan_inst(&fifo->base, (u64)inst << 12, &flags); spin_lock_irqsave(&fifo->base.lock, flags); chan = nvkm_fifo_chan_inst_locked(&fifo->base, (u64)inst << 12); nvkm_error(subdev, "%s fault at %010llx engine %02x [%s] client %02x [%s%s] " Loading @@ -487,9 +489,23 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit) (u64)inst << 12, chan ? chan->object.client->name : "unknown"); if (engine && chan) gk104_fifo_recover(fifo, engine, (void *)chan); nvkm_fifo_chan_put(&fifo->base, flags, &chan); /* Kill the channel that caused the fault. */ if (chan) gk104_fifo_recover_chan(&fifo->base, chan->chid); /* Channel recovery will probably have already done this for the * correct engine(s), but just in case we can't find the channel * information... */ for (engn = 0; engn < fifo->engine_nr && engine; engn++) { if (fifo->engine[engn].engine == engine) { gk104_fifo_recover_engn(fifo, engn); break; } } spin_unlock_irqrestore(&fifo->base.lock, flags); } static const struct nvkm_bitfield gk104_fifo_pbdma_intr_0[] = { Loading
drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h +3 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,9 @@ void nvkm_fifo_cevent(struct nvkm_fifo *); void nvkm_fifo_kevent(struct nvkm_fifo *, int chid); void nvkm_fifo_recover_chan(struct nvkm_fifo *, int chid); struct nvkm_fifo_chan * nvkm_fifo_chan_inst_locked(struct nvkm_fifo *, u64 inst); struct nvkm_fifo_chan_oclass; struct nvkm_fifo_func { void *(*dtor)(struct nvkm_fifo *); Loading