mirror of
https://github.com/torvalds/linux.git
synced 2024-12-11 13:41:55 +00:00
drm/nouveau/fifo/gk104-: directly use new recovery code for mmu faults
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
eaa5ed65ee
commit
3534821df5
@ -65,19 +65,29 @@ nvkm_fifo_chan_put(struct nvkm_fifo *fifo, unsigned long flags,
|
||||
}
|
||||
}
|
||||
|
||||
struct nvkm_fifo_chan *
|
||||
nvkm_fifo_chan_inst_locked(struct nvkm_fifo *fifo, u64 inst)
|
||||
{
|
||||
struct nvkm_fifo_chan *chan;
|
||||
list_for_each_entry(chan, &fifo->chan, head) {
|
||||
if (chan->inst->addr == inst) {
|
||||
list_del(&chan->head);
|
||||
list_add(&chan->head, &fifo->chan);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
if ((chan = nvkm_fifo_chan_inst_locked(fifo, inst))) {
|
||||
*rflags = flags;
|
||||
return chan;
|
||||
}
|
||||
spin_unlock_irqrestore(&fifo->lock, flags);
|
||||
return NULL;
|
||||
|
@ -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);
|
||||
@ -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] "
|
||||
@ -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[] = {
|
||||
|
@ -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…
Reference in New Issue
Block a user