Message ID | 5150175D.3070808@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, Mar 25, 2013 at 10:22:37AM +0100, Maarten Lankhorst wrote: > Fixes 100% cpu usage when the exit interrupt never got acked. > > Signed-off-by: Maarten Lankhorst <m.b.lankhorst@gmail.com> > --- > diff --git a/drivers/gpu/drm/nouveau/core/core/falcon.c b/drivers/gpu/drm/nouveau/core/core/falcon.c > index e05c157..b11c5f3 100644 > --- a/drivers/gpu/drm/nouveau/core/core/falcon.c > +++ b/drivers/gpu/drm/nouveau/core/core/falcon.c > @@ -229,6 +229,24 @@ _nouveau_falcon_fini(struct nouveau_object *object, bool suspend) > return nouveau_engine_fini(&falcon->base, suspend); > } > > +void > +nouveau_falcon_intr(struct nouveau_subdev *subdev) > +{ > + struct nouveau_falcon *falcon = (void*)subdev; > + u32 intr = nv_ro32(falcon, 0x008); > + > + nv_wo32(falcon, 0x004, intr); > + > + if (intr & 0x10) { > + intr &= ~0x10; > + > + nv_info(falcon, "Exit interrupt called\n"); Do you really want to print it at "info" level? How frequent it is? > + } > + > + if (intr) > + nv_error(falcon, "Unhandled interrupt %08x\n", intr); > +} > + > int > nouveau_falcon_create_(struct nouveau_object *parent, > struct nouveau_object *engine,
Op 25-03-13 19:14, Marcin Slusarz schreef: > On Mon, Mar 25, 2013 at 10:22:37AM +0100, Maarten Lankhorst wrote: >> Fixes 100% cpu usage when the exit interrupt never got acked. >> >> Signed-off-by: Maarten Lankhorst <m.b.lankhorst@gmail.com> >> --- >> diff --git a/drivers/gpu/drm/nouveau/core/core/falcon.c b/drivers/gpu/drm/nouveau/core/core/falcon.c >> index e05c157..b11c5f3 100644 >> --- a/drivers/gpu/drm/nouveau/core/core/falcon.c >> +++ b/drivers/gpu/drm/nouveau/core/core/falcon.c >> @@ -229,6 +229,24 @@ _nouveau_falcon_fini(struct nouveau_object *object, bool suspend) >> return nouveau_engine_fini(&falcon->base, suspend); >> } >> >> +void >> +nouveau_falcon_intr(struct nouveau_subdev *subdev) >> +{ >> + struct nouveau_falcon *falcon = (void*)subdev; >> + u32 intr = nv_ro32(falcon, 0x008); >> + >> + nv_wo32(falcon, 0x004, intr); >> + >> + if (intr & 0x10) { >> + intr &= ~0x10; >> + >> + nv_info(falcon, "Exit interrupt called\n"); > Do you really want to print it at "info" level? How frequent it is? It shouldn't be often, I want it to run at the error level since that usually means the firmware exited prematurely/crashed and things go bad, but it happens with the secret scrubber finishing on initialization too. That one is harmless though. >> + } >> + >> + if (intr) >> + nv_error(falcon, "Unhandled interrupt %08x\n", intr); >> +} >> + >> int >> nouveau_falcon_create_(struct nouveau_object *parent, >> struct nouveau_object *engine, > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel >
On Tue, Mar 26, 2013 at 07:29:24AM +0100, Maarten Lankhorst wrote: > Op 25-03-13 19:14, Marcin Slusarz schreef: > > On Mon, Mar 25, 2013 at 10:22:37AM +0100, Maarten Lankhorst wrote: > >> Fixes 100% cpu usage when the exit interrupt never got acked. > >> > >> Signed-off-by: Maarten Lankhorst <m.b.lankhorst@gmail.com> > >> --- > >> diff --git a/drivers/gpu/drm/nouveau/core/core/falcon.c b/drivers/gpu/drm/nouveau/core/core/falcon.c > >> index e05c157..b11c5f3 100644 > >> --- a/drivers/gpu/drm/nouveau/core/core/falcon.c > >> +++ b/drivers/gpu/drm/nouveau/core/core/falcon.c > >> @@ -229,6 +229,24 @@ _nouveau_falcon_fini(struct nouveau_object *object, bool suspend) > >> return nouveau_engine_fini(&falcon->base, suspend); > >> } > >> > >> +void > >> +nouveau_falcon_intr(struct nouveau_subdev *subdev) > >> +{ > >> + struct nouveau_falcon *falcon = (void*)subdev; > >> + u32 intr = nv_ro32(falcon, 0x008); > >> + > >> + nv_wo32(falcon, 0x004, intr); > >> + > >> + if (intr & 0x10) { > >> + intr &= ~0x10; > >> + > >> + nv_info(falcon, "Exit interrupt called\n"); > > Do you really want to print it at "info" level? How frequent it is? > It shouldn't be often, I want it to run at the error level since that usually > means the firmware exited prematurely/crashed and things go bad, but it > happens with the secret scrubber finishing on initialization too. That one > is harmless though. Maybe it should say: nv_error(falcon, "firmware exited prematurely\n"); ? > >> + } > >> + > >> + if (intr) > >> + nv_error(falcon, "Unhandled interrupt %08x\n", intr); > >> +} > >> + > >> int > >> nouveau_falcon_create_(struct nouveau_object *parent, > >> struct nouveau_object *engine, > > _______________________________________________ > > dri-devel mailing list > > dri-devel@lists.freedesktop.org > > http://lists.freedesktop.org/mailman/listinfo/dri-devel > > >
Op 26-03-13 21:29, Marcin Slusarz schreef: > On Tue, Mar 26, 2013 at 07:29:24AM +0100, Maarten Lankhorst wrote: >> Op 25-03-13 19:14, Marcin Slusarz schreef: >>> On Mon, Mar 25, 2013 at 10:22:37AM +0100, Maarten Lankhorst wrote: >>>> Fixes 100% cpu usage when the exit interrupt never got acked. >>>> >>>> Signed-off-by: Maarten Lankhorst <m.b.lankhorst@gmail.com> >>>> --- >>>> diff --git a/drivers/gpu/drm/nouveau/core/core/falcon.c b/drivers/gpu/drm/nouveau/core/core/falcon.c >>>> index e05c157..b11c5f3 100644 >>>> --- a/drivers/gpu/drm/nouveau/core/core/falcon.c >>>> +++ b/drivers/gpu/drm/nouveau/core/core/falcon.c >>>> @@ -229,6 +229,24 @@ _nouveau_falcon_fini(struct nouveau_object *object, bool suspend) >>>> return nouveau_engine_fini(&falcon->base, suspend); >>>> } >>>> >>>> +void >>>> +nouveau_falcon_intr(struct nouveau_subdev *subdev) >>>> +{ >>>> + struct nouveau_falcon *falcon = (void*)subdev; >>>> + u32 intr = nv_ro32(falcon, 0x008); >>>> + >>>> + nv_wo32(falcon, 0x004, intr); >>>> + >>>> + if (intr & 0x10) { >>>> + intr &= ~0x10; >>>> + >>>> + nv_info(falcon, "Exit interrupt called\n"); >>> Do you really want to print it at "info" level? How frequent it is? >> It shouldn't be often, I want it to run at the error level since that usually >> means the firmware exited prematurely/crashed and things go bad, but it >> happens with the secret scrubber finishing on initialization too. That one >> is harmless though. > Maybe it should say: > nv_error(falcon, "firmware exited prematurely\n"); > ? > That is only 1 of the 2 causes, the other is when it's a secret engine (CRYPT/BSP/VP for <nvd0) and the scrubber finished running. In that case it's not an error. ~Maarten
diff --git a/drivers/gpu/drm/nouveau/core/core/falcon.c b/drivers/gpu/drm/nouveau/core/core/falcon.c index e05c157..b11c5f3 100644 --- a/drivers/gpu/drm/nouveau/core/core/falcon.c +++ b/drivers/gpu/drm/nouveau/core/core/falcon.c @@ -229,6 +229,24 @@ _nouveau_falcon_fini(struct nouveau_object *object, bool suspend) return nouveau_engine_fini(&falcon->base, suspend); } +void +nouveau_falcon_intr(struct nouveau_subdev *subdev) +{ + struct nouveau_falcon *falcon = (void*)subdev; + u32 intr = nv_ro32(falcon, 0x008); + + nv_wo32(falcon, 0x004, intr); + + if (intr & 0x10) { + intr &= ~0x10; + + nv_info(falcon, "Exit interrupt called\n"); + } + + if (intr) + nv_error(falcon, "Unhandled interrupt %08x\n", intr); +} + int nouveau_falcon_create_(struct nouveau_object *parent, struct nouveau_object *engine, diff --git a/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c index 0a5aa6b..2201c96 100644 --- a/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/bsp/nvc0.c @@ -91,6 +91,7 @@ nvc0_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return ret; nv_subdev(priv)->unit = 0x00008000; + nv_subdev(priv)->intr = nouveau_falcon_intr; nv_engine(priv)->cclass = &nvc0_bsp_cclass; nv_engine(priv)->sclass = nvc0_bsp_sclass; return 0; diff --git a/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c b/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c index d4f23bb..4e7f79b 100644 --- a/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/bsp/nve0.c @@ -91,6 +91,7 @@ nve0_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return ret; nv_subdev(priv)->unit = 0x00008000; + nv_subdev(priv)->intr = nouveau_falcon_intr; nv_engine(priv)->cclass = &nve0_bsp_cclass; nv_engine(priv)->sclass = nve0_bsp_sclass; return 0; diff --git a/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c index ebf0d86..4557c3b 100644 --- a/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/ppp/nvc0.c @@ -91,6 +91,7 @@ nvc0_ppp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return ret; nv_subdev(priv)->unit = 0x00000002; + nv_subdev(priv)->intr = nouveau_falcon_intr; nv_engine(priv)->cclass = &nvc0_ppp_cclass; nv_engine(priv)->sclass = nvc0_ppp_sclass; return 0; diff --git a/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c index f761949..cc2c8cc 100644 --- a/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/vp/nvc0.c @@ -91,6 +91,7 @@ nvc0_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return ret; nv_subdev(priv)->unit = 0x00020000; + nv_subdev(priv)->intr = nouveau_falcon_intr; nv_engine(priv)->cclass = &nvc0_vp_cclass; nv_engine(priv)->sclass = nvc0_vp_sclass; return 0; diff --git a/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c b/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c index 2384ce5..774ec16 100644 --- a/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/vp/nve0.c @@ -91,6 +91,7 @@ nve0_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return ret; nv_subdev(priv)->unit = 0x00020000; + nv_subdev(priv)->intr = nouveau_falcon_intr; nv_engine(priv)->cclass = &nve0_vp_cclass; nv_engine(priv)->sclass = nve0_vp_sclass; return 0; diff --git a/drivers/gpu/drm/nouveau/core/include/core/falcon.h b/drivers/gpu/drm/nouveau/core/include/core/falcon.h index 1edec38..181aa7d 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/falcon.h +++ b/drivers/gpu/drm/nouveau/core/include/core/falcon.h @@ -72,6 +72,8 @@ int nouveau_falcon_create_(struct nouveau_object *, struct nouveau_object *, struct nouveau_oclass *, u32, bool, const char *, const char *, int, void **); +void nouveau_falcon_intr(struct nouveau_subdev *subdev); + #define _nouveau_falcon_dtor _nouveau_engine_dtor int _nouveau_falcon_init(struct nouveau_object *); int _nouveau_falcon_fini(struct nouveau_object *, bool);
Fixes 100% cpu usage when the exit interrupt never got acked. Signed-off-by: Maarten Lankhorst <m.b.lankhorst@gmail.com> ---