Message ID | 514EE9EE.9030208@canonical.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi, On Sun, Mar 24, 2013 at 12:56:30PM +0100, Maarten Lankhorst wrote: > Op 23-03-13 12:47, Peter Hurley schreef: > > On Tue, 2013-03-19 at 11:13 -0400, Peter Hurley wrote: > >> On vanilla 3.9.0-rc3, I get this 100% repeatable oops after login when > >> the user X session is coming up: > > Perhaps I wasn't clear that this happens on every boot and is a > > regression from 3.8 > > > > I'd be happy to help resolve this but time is of the essence; it would > > be a shame to have to revert all of this for 3.9 > > Well it broke on my system too, so it was easy to fix. > > I didn't even need gdm to trigger it! > > >8---- > This fixes regression caused by 1d7c71a3e2f7 (drm/nouveau/disp: port vblank handling to event interface), This patch fixes the boot crashes also on my G5 iMac (http://marc.info/?l=linux-kernel&m=136285469916031&w=2). Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi> A.
On Sun, 2013-03-24 at 12:56 +0100, Maarten Lankhorst wrote: > Op 23-03-13 12:47, Peter Hurley schreef: > > On Tue, 2013-03-19 at 11:13 -0400, Peter Hurley wrote: > >> On vanilla 3.9.0-rc3, I get this 100% repeatable oops after login when > >> the user X session is coming up: > > Perhaps I wasn't clear that this happens on every boot and is a > > regression from 3.8 > > > > I'd be happy to help resolve this but time is of the essence; it would > > be a shame to have to revert all of this for 3.9 > > Well it broke on my system too, so it was easy to fix. > > I didn't even need gdm to trigger it! > > >8---- > This fixes regression caused by 1d7c71a3e2f7 (drm/nouveau/disp: port vblank handling to event interface), Thanks Maarten! But am I the only one running multi-head nouveau on linux-next and early RCs? That's a scary thought. Is there a test bench for validating nouveau? Regards, Peter Hurley
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index d109936..c95decf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -72,11 +72,25 @@ module_param_named(modeset, nouveau_modeset, int, 0400); static struct drm_driver driver; static int +nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head) +{ + struct nouveau_drm *drm = + container_of(event, struct nouveau_drm, vblank[head]); + drm_handle_vblank(drm->dev, head); + return NVKM_EVENT_KEEP; +} + +static int nouveau_drm_vblank_enable(struct drm_device *dev, int head) { struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_disp *pdisp = nouveau_disp(drm->device); - nouveau_event_get(pdisp->vblank, head, &drm->vblank); + + if (WARN_ON_ONCE(head > ARRAY_SIZE(drm->vblank))) + return -EIO; + WARN_ON_ONCE(drm->vblank[head].func); + drm->vblank[head].func = nouveau_drm_vblank_handler; + nouveau_event_get(pdisp->vblank, head, &drm->vblank[head]); return 0; } @@ -85,16 +99,11 @@ nouveau_drm_vblank_disable(struct drm_device *dev, int head) { struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_disp *pdisp = nouveau_disp(drm->device); - nouveau_event_put(pdisp->vblank, head, &drm->vblank); -} - -static int -nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head) -{ - struct nouveau_drm *drm = - container_of(event, struct nouveau_drm, vblank); - drm_handle_vblank(drm->dev, head); - return NVKM_EVENT_KEEP; + if (drm->vblank[head].func) + nouveau_event_put(pdisp->vblank, head, &drm->vblank[head]); + else + WARN_ON_ONCE(1); + drm->vblank[head].func = NULL; } static u64 @@ -292,7 +301,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) dev->dev_private = drm; drm->dev = dev; - drm->vblank.func = nouveau_drm_vblank_handler; INIT_LIST_HEAD(&drm->clients); spin_lock_init(&drm->tile.lock); diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h index b25df37..9c85601 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -113,7 +113,7 @@ struct nouveau_drm { struct nvbios vbios; struct nouveau_display *display; struct backlight_device *backlight; - struct nouveau_eventh vblank; + struct nouveau_eventh vblank[16]; /* power management */ struct nouveau_pm *pm;