[Nouveau] [PATCH 3/4] drm/nv50: avoid unloading pgraph context when ctxprog is running

Maarten Maathuis madman2003 at gmail.com
Mon Feb 1 14:28:12 PST 2010


If there are no objections, please share them as soon as possible.

On Mon, Feb 1, 2010 at 7:40 PM, Maarten Maathuis <madman2003 at gmail.com> wrote:
> Someone should probably check this out on earlier cards as well.
>
> On Mon, Feb 1, 2010 at 7:34 PM, Maarten Maathuis <madman2003 at gmail.com> wrote:
>> - We need to disable pgraph fifo access before checking the current channel,
>> otherwise we could still hit a running ctxprog.
>> - The writes to 0x400500 are already handled by pgraph->fifo_access and are
>> therefore redundant, moreover pgraph fifo access should not be reenabled before
>> current context is set as invalid. So remove them altogether.
>>
>> Signed-off-by: Maarten Maathuis <madman2003 at gmail.com>
>> ---
>>  drivers/gpu/drm/nouveau/nouveau_channel.c |    7 +++----
>>  drivers/gpu/drm/nouveau/nv50_graph.c      |   10 +++++++---
>>  2 files changed, 10 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
>> index 343d718..2281f99 100644
>> --- a/drivers/gpu/drm/nouveau/nouveau_channel.c
>> +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
>> @@ -278,12 +278,11 @@ nouveau_channel_free(struct nouveau_channel *chan)
>>        /* Ensure the channel is no longer active on the GPU */
>>        pfifo->reassign(dev, false);
>>
>> -       if (pgraph->channel(dev) == chan) {
>> -               pgraph->fifo_access(dev, false);
>> +       pgraph->fifo_access(dev, false);
>> +       if (pgraph->channel(dev) == chan)
>>                pgraph->unload_context(dev);
>> -               pgraph->fifo_access(dev, true);
>> -       }
>>        pgraph->destroy_context(chan);
>> +       pgraph->fifo_access(dev, true);
>>
>>        if (pfifo->channel_id(dev) == chan->id) {
>>                pfifo->disable(dev);
>> diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
>> index 20319e5..6d50480 100644
>> --- a/drivers/gpu/drm/nouveau/nv50_graph.c
>> +++ b/drivers/gpu/drm/nouveau/nv50_graph.c
>> @@ -165,6 +165,12 @@ nv50_graph_channel(struct drm_device *dev)
>>        uint32_t inst;
>>        int i;
>>
>> +       /* Be sure we're not in the middle of a context switch or bad things
>> +        * will happen, such as unloading the wrong pgraph context.
>> +        */
>> +       if (!nv_wait(0x400300, 0x00000001, 0x00000000))
>> +               NV_ERROR(dev, "Ctxprog is still running\n");
>> +
>>        inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
>>        if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
>>                return NULL;
>> @@ -275,7 +281,7 @@ nv50_graph_load_context(struct nouveau_channel *chan)
>>  int
>>  nv50_graph_unload_context(struct drm_device *dev)
>>  {
>> -       uint32_t inst, fifo = nv_rd32(dev, 0x400500);
>> +       uint32_t inst;
>>
>>        inst  = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
>>        if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
>> @@ -283,12 +289,10 @@ nv50_graph_unload_context(struct drm_device *dev)
>>        inst &= NV50_PGRAPH_CTXCTL_CUR_INSTANCE;
>>
>>        nouveau_wait_for_idle(dev);
>> -       nv_wr32(dev, 0x400500, fifo & ~1);
>>        nv_wr32(dev, 0x400784, inst);
>>        nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x20);
>>        nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 0x01);
>>        nouveau_wait_for_idle(dev);
>> -       nv_wr32(dev, 0x400500, fifo);
>>
>>        nv_wr32(dev, NV50_PGRAPH_CTXCTL_CUR, inst);
>>        return 0;
>> --
>> 1.6.6.1
>>
>>
>


More information about the Nouveau mailing list