Added the "Tested-by", added Marcin's real name. And added a spin unlock in the nv50 fifo failure path.
Will push in a day if there are no further comments. Maarten. On Mon, Feb 8, 2010 at 6:38 PM, Maarten Maathuis <[email protected]> wrote: > - Marcin Slusarz pointed out that this triggers a BUG_ON, because kzalloc > could > sleep. > - The irq handler should restore the value NV03_PFIFO_CACHES, but still it's > better if this stuff doesn't happen in the middle of fifo create context. I > see > no reason in spin locking pgraph create context, it isn't activated at that > stage. > - Move and rename the lock after some discussion with Marcin, even better > naming suggestions are appreciated. > > Tested-by: Marcin Slusarz <[email protected]> > Signed-off-by: Maarten Maathuis <[email protected]> > --- > drivers/gpu/drm/nouveau/nouveau_channel.c | 9 ++------- > drivers/gpu/drm/nouveau/nouveau_drv.h | 4 +++- > drivers/gpu/drm/nouveau/nouveau_irq.c | 4 ++-- > drivers/gpu/drm/nouveau/nouveau_state.c | 2 +- > drivers/gpu/drm/nouveau/nv04_fifo.c | 5 +++++ > drivers/gpu/drm/nouveau/nv40_fifo.c | 5 +++++ > drivers/gpu/drm/nouveau/nv50_fifo.c | 5 +++++ > 7 files changed, 23 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c > b/drivers/gpu/drm/nouveau/nouveau_channel.c > index d25ed61..f7ca950 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_channel.c > +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c > @@ -113,7 +113,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct > nouveau_channel **chan_ret, > struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; > struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; > struct nouveau_channel *chan; > - unsigned long flags; > int channel, user; > int ret; > > @@ -204,8 +203,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct > nouveau_channel **chan_ret, > return ret; > } > > - spin_lock_irqsave(&dev_priv->engine.lock, flags); > - > /* disable the fifo caches */ > pfifo->reassign(dev, false); > > @@ -225,8 +222,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct > nouveau_channel **chan_ret, > > pfifo->reassign(dev, true); > > - spin_unlock_irqrestore(&dev_priv->engine.lock, flags); > - > ret = nouveau_dma_init(chan); > if (!ret) > ret = nouveau_fence_init(chan); > @@ -290,7 +285,7 @@ nouveau_channel_free(struct nouveau_channel *chan) > if (pgraph->channel(dev) == chan) > nouveau_wait_for_idle(dev); > > - spin_lock_irqsave(&dev_priv->engine.lock, flags); > + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); > > pgraph->fifo_access(dev, false); > if (pgraph->channel(dev) == chan) > @@ -307,7 +302,7 @@ nouveau_channel_free(struct nouveau_channel *chan) > > pfifo->reassign(dev, true); > > - spin_unlock_irqrestore(&dev_priv->engine.lock, flags); > + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); > > /* Release the channel's resources */ > nouveau_gpuobj_ref_del(dev, &chan->pushbuf); > diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h > b/drivers/gpu/drm/nouveau/nouveau_drv.h > index 64987a9..ea55a41 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_drv.h > +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h > @@ -358,7 +358,6 @@ struct nouveau_engine { > struct nouveau_fb_engine fb; > struct nouveau_pgraph_engine graph; > struct nouveau_fifo_engine fifo; > - spinlock_t lock; > }; > > struct nouveau_pll_vals { > @@ -534,6 +533,9 @@ struct drm_nouveau_private { > struct nouveau_engine engine; > struct nouveau_channel *channel; > > + /* For PFIFO and PGRAPH. */ > + spinlock_t context_switch_lock; > + > /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ > struct nouveau_gpuobj *ramht; > uint32_t ramin_rsvd_vram; > diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c > b/drivers/gpu/drm/nouveau/nouveau_irq.c > index cffc9bc..95220dd 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_irq.c > +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c > @@ -697,7 +697,7 @@ nouveau_irq_handler(DRM_IRQ_ARGS) > if (!status) > return IRQ_NONE; > > - spin_lock_irqsave(&dev_priv->engine.lock, flags); > + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); > > if (dev_priv->fbdev_info) { > fbdev_flags = dev_priv->fbdev_info->flags; > @@ -736,7 +736,7 @@ nouveau_irq_handler(DRM_IRQ_ARGS) > if (dev_priv->fbdev_info) > dev_priv->fbdev_info->flags = fbdev_flags; > > - spin_unlock_irqrestore(&dev_priv->engine.lock, flags); > + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); > > return IRQ_HANDLED; > } > diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c > b/drivers/gpu/drm/nouveau/nouveau_state.c > index 3586667..0a2a437 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_state.c > +++ b/drivers/gpu/drm/nouveau/nouveau_state.c > @@ -383,7 +383,7 @@ nouveau_card_init(struct drm_device *dev) > goto out; > engine = &dev_priv->engine; > dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; > - spin_lock_init(&dev_priv->engine.lock); > + spin_lock_init(&dev_priv->context_switch_lock); > > /* Parse BIOS tables / Run init tables if card not POSTed */ > if (drm_core_check_feature(dev, DRIVER_MODESET)) { > diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c > b/drivers/gpu/drm/nouveau/nv04_fifo.c > index f31347b..66fe559 100644 > --- a/drivers/gpu/drm/nouveau/nv04_fifo.c > +++ b/drivers/gpu/drm/nouveau/nv04_fifo.c > @@ -117,6 +117,7 @@ nv04_fifo_create_context(struct nouveau_channel *chan) > { > struct drm_device *dev = chan->dev; > struct drm_nouveau_private *dev_priv = dev->dev_private; > + unsigned long flags; > int ret; > > ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(chan->id), ~0, > @@ -127,6 +128,8 @@ nv04_fifo_create_context(struct nouveau_channel *chan) > if (ret) > return ret; > > + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); > + > /* Setup initial state */ > dev_priv->engine.instmem.prepare_access(dev, true); > RAMFC_WR(DMA_PUT, chan->pushbuf_base); > @@ -144,6 +147,8 @@ nv04_fifo_create_context(struct nouveau_channel *chan) > /* enable the fifo dma operation */ > nv_wr32(dev, NV04_PFIFO_MODE, > nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); > + > + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); > return 0; > } > > diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c > b/drivers/gpu/drm/nouveau/nv40_fifo.c > index b4f19cc..6b2ef4a 100644 > --- a/drivers/gpu/drm/nouveau/nv40_fifo.c > +++ b/drivers/gpu/drm/nouveau/nv40_fifo.c > @@ -37,6 +37,7 @@ nv40_fifo_create_context(struct nouveau_channel *chan) > struct drm_device *dev = chan->dev; > struct drm_nouveau_private *dev_priv = dev->dev_private; > uint32_t fc = NV40_RAMFC(chan->id); > + unsigned long flags; > int ret; > > ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(chan->id), ~0, > @@ -45,6 +46,8 @@ nv40_fifo_create_context(struct nouveau_channel *chan) > if (ret) > return ret; > > + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); > + > dev_priv->engine.instmem.prepare_access(dev, true); > nv_wi32(dev, fc + 0, chan->pushbuf_base); > nv_wi32(dev, fc + 4, chan->pushbuf_base); > @@ -63,6 +66,8 @@ nv40_fifo_create_context(struct nouveau_channel *chan) > /* enable the fifo dma operation */ > nv_wr32(dev, NV04_PFIFO_MODE, > nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); > + > + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); > return 0; > } > > diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c > b/drivers/gpu/drm/nouveau/nv50_fifo.c > index 204a79f..369ecb4 100644 > --- a/drivers/gpu/drm/nouveau/nv50_fifo.c > +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c > @@ -243,6 +243,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan) > struct drm_device *dev = chan->dev; > struct drm_nouveau_private *dev_priv = dev->dev_private; > struct nouveau_gpuobj *ramfc = NULL; > + unsigned long flags; > int ret; > > NV_DEBUG(dev, "ch%d\n", chan->id); > @@ -278,6 +279,8 @@ nv50_fifo_create_context(struct nouveau_channel *chan) > return ret; > } > > + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); > + > dev_priv->engine.instmem.prepare_access(dev, true); > > nv_wo32(dev, ramfc, 0x08/4, chan->pushbuf_base); > @@ -306,10 +309,12 @@ nv50_fifo_create_context(struct nouveau_channel *chan) > ret = nv50_fifo_channel_enable(dev, chan->id, false); > if (ret) { > NV_ERROR(dev, "error enabling ch%d: %d\n", chan->id, ret); > + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); > nouveau_gpuobj_ref_del(dev, &chan->ramfc); > return ret; > } > > + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); > return 0; > } > > -- > 1.6.6.1 > > _______________________________________________ Nouveau mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/nouveau
