Maarten Lankhorst
2013-Jul-23 13:43 UTC
[Nouveau] [PATCH 1/3] drm/nouveau: fix vblank interrupt being called before event is setup
Sort of fixes mmiotrace for me again, I could sear I sent a similar patch before
the rework to event interface, so I guess it got reintroduced.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst at canonical.com>
---
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
index 7e3875d..35e526b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
@@ -1266,13 +1266,15 @@ nv50_disp_intr(struct nouveau_subdev *subdev)
}
if (intr1 & 0x00000004) {
- nouveau_event_trigger(priv->base.vblank, 0);
+ if (priv->base.vblank)
+ nouveau_event_trigger(priv->base.vblank, 0);
nv_wr32(priv, 0x610024, 0x00000004);
intr1 &= ~0x00000004;
}
if (intr1 & 0x00000008) {
- nouveau_event_trigger(priv->base.vblank, 1);
+ if (priv->base.vblank)
+ nouveau_event_trigger(priv->base.vblank, 1);
nv_wr32(priv, 0x610024, 0x00000008);
intr1 &= ~0x00000008;
}
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
index 52dd7a1..4095f65 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
@@ -941,7 +941,7 @@ nvd0_disp_intr(struct nouveau_subdev *subdev)
u32 mask = 0x01000000 << i;
if (mask & intr) {
u32 stat = nv_rd32(priv, 0x6100bc + (i * 0x800));
- if (stat & 0x00000001)
+ if ((stat & 0x00000001) && priv->base.vblank)
nouveau_event_trigger(priv->base.vblank, i);
nv_mask(priv, 0x6100bc + (i * 0x800), 0, 0);
nv_rd32(priv, 0x6100c0 + (i * 0x800));
Maarten Lankhorst
2013-Jul-23 13:45 UTC
[Nouveau] [PATCH 2/3] drm/nouveau: fix null pointer dereference in poll_changed
Fixes vgaswitcheroo on a card without display.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst at canonical.com>
---
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 4c1bc06..8f6d63d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -398,7 +398,8 @@ void
nouveau_fbcon_output_poll_changed(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
- drm_fb_helper_hotplug_event(&drm->fbcon->helper);
+ if (drm->fbcon)
+ drm_fb_helper_hotplug_event(&drm->fbcon->helper);
}
static int
Maarten Lankhorst
2013-Jul-23 13:49 UTC
[Nouveau] [PATCH 3/3] drm/nouveau: fix semaphore dmabuf obj
Fixes some dmabuf object errors on nv50 chipset and below.
Cc: stable at vger.kernel.org [3.7+]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst at canonical.com>
---
Xorg still won't start with vblank enabled on nv50, I have no idea why yet.
diff --git a/drivers/gpu/drm/nouveau/nv17_fence.c
b/drivers/gpu/drm/nouveau/nv17_fence.c
index 37a032b..260f3c5 100644
--- a/drivers/gpu/drm/nouveau/nv17_fence.c
+++ b/drivers/gpu/drm/nouveau/nv17_fence.c
@@ -76,7 +76,7 @@ nv17_fence_context_new(struct nouveau_channel *chan)
struct ttm_mem_reg *mem = &priv->bo->bo.mem;
struct nouveau_object *object;
u32 start = mem->start * PAGE_SIZE;
- u32 limit = mem->start + mem->size - 1;
+ u32 limit = start + mem->size - 1;
int ret = 0;
fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL);
diff --git a/drivers/gpu/drm/nouveau/nv50_fence.c
b/drivers/gpu/drm/nouveau/nv50_fence.c
index ada4d6d..60afa5c 100644
--- a/drivers/gpu/drm/nouveau/nv50_fence.c
+++ b/drivers/gpu/drm/nouveau/nv50_fence.c
@@ -51,26 +51,27 @@ nv50_fence_context_new(struct nouveau_channel *chan)
fctx->base.sync = nv17_fence_sync;
ret = nouveau_object_new(nv_object(chan->cli), chan->handle,
- NvSema, 0x0002,
+ NvSema, 0x003d,
&(struct nv_dma_class) {
.flags = NV_DMA_TARGET_VRAM |
NV_DMA_ACCESS_RDWR,
.start = mem->start * PAGE_SIZE,
- .limit = mem->size - 1,
+ .limit = mem->start * PAGE_SIZE + mem->size - 1,
}, sizeof(struct nv_dma_class),
&object);
/* dma objects for display sync channel semaphore blocks */
for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) {
struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i);
+ mem = &bo->bo.mem;
ret = nouveau_object_new(nv_object(chan->cli), chan->handle,
NvEvoSema0 + i, 0x003d,
&(struct nv_dma_class) {
.flags = NV_DMA_TARGET_VRAM |
NV_DMA_ACCESS_RDWR,
- .start = bo->bo.offset,
- .limit = bo->bo.offset + 0xfff,
+ .start = mem->start * PAGE_SIZE,
+ .limit = mem->start * PAGE_SIZE + mem->size - 1,
}, sizeof(struct nv_dma_class),
&object);
}
Ben Skeggs
2013-Jul-30 02:42 UTC
[Nouveau] [PATCH 1/3] drm/nouveau: fix vblank interrupt being called before event is setup
On Tue, Jul 23, 2013 at 11:43 PM, Maarten Lankhorst <maarten.lankhorst at canonical.com> wrote:> Sort of fixes mmiotrace for me again, I could sear I sent a similar patch before > the rework to event interface, so I guess it got reintroduced.I don't know how/why you think this fixes anything. The interrupt handler can't possibly be called until after priv->base.vblank has been initialised... Seriously, go look, the subdev interrupt handler pointer isn't filled in (and can't be) until after nouveau_disp_create() has been called, and nouveau_disp_create() initialises priv->base.vblank before it returns... Ben.> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst at canonical.com> > --- > diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c > index 7e3875d..35e526b 100644 > --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c > +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c > @@ -1266,13 +1266,15 @@ nv50_disp_intr(struct nouveau_subdev *subdev) > } > > if (intr1 & 0x00000004) { > - nouveau_event_trigger(priv->base.vblank, 0); > + if (priv->base.vblank) > + nouveau_event_trigger(priv->base.vblank, 0); > nv_wr32(priv, 0x610024, 0x00000004); > intr1 &= ~0x00000004; > } > > if (intr1 & 0x00000008) { > - nouveau_event_trigger(priv->base.vblank, 1); > + if (priv->base.vblank) > + nouveau_event_trigger(priv->base.vblank, 1); > nv_wr32(priv, 0x610024, 0x00000008); > intr1 &= ~0x00000008; > } > diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c > index 52dd7a1..4095f65 100644 > --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c > +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c > @@ -941,7 +941,7 @@ nvd0_disp_intr(struct nouveau_subdev *subdev) > u32 mask = 0x01000000 << i; > if (mask & intr) { > u32 stat = nv_rd32(priv, 0x6100bc + (i * 0x800)); > - if (stat & 0x00000001) > + if ((stat & 0x00000001) && priv->base.vblank) > nouveau_event_trigger(priv->base.vblank, i); > nv_mask(priv, 0x6100bc + (i * 0x800), 0, 0); > nv_rd32(priv, 0x6100c0 + (i * 0x800)); > > _______________________________________________ > dri-devel mailing list > dri-devel at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel
Maarten Lankhorst
2013-Jul-30 06:10 UTC
[Nouveau] [PATCH 1/3] drm/nouveau: fix vblank interrupt being called before event is setup
Op 30-07-13 04:42, Ben Skeggs schreef:> On Tue, Jul 23, 2013 at 11:43 PM, Maarten Lankhorst > <maarten.lankhorst at canonical.com> wrote: >> Sort of fixes mmiotrace for me again, I could sear I sent a similar patch before >> the rework to event interface, so I guess it got reintroduced. > I don't know how/why you think this fixes anything. The interrupt > handler can't possibly be called until after priv->base.vblank has > been initialised... > > Seriously, go look, the subdev interrupt handler pointer isn't filled > in (and can't be) until after nouveau_disp_create() has been called, > and nouveau_disp_create() initialises priv->base.vblank before it > returns... >There's also a disp_dtor function right above it and without a smp_wmb the writes could still be reordered in the constructor. O:-) A spinlock would be needed to make sure that no interrupt is in process if you set intr to null before destroying vblank event, though. I can probably try to get the oops again indicating that priv->base.vblank was null in the interrupt handler if you want, iirc it happened reliably during mmiotracing. ~Maarten
Seemingly Similar Threads
- [PATCH 1/3] drm/nouveau: fix vblank interrupt being called before event is setup
- [PATCH] gpio: rename g92 class to g94
- [PATCH 1/3] drm/nouveau: fix vblank interrupt being called before event is setup
- [RFC PATCH] drm/nv50-nvd0: implement precise vblank timing support on nv50/nvc0.
- [PATCH 3/3] nouveau: add vblank methods on newer cards