[PATCH] a lockup in the mga driver
Dave Airlie
airlied at gmail.com
Thu Mar 13 17:36:05 PDT 2014
On Fri, Mar 14, 2014 at 8:25 AM, Mikulas Patocka <mpatocka at redhat.com> wrote:
> Hi David
>
> Are you maintaining the Xorg mga driver? (you anounced the last update
> 1.6.3) Or is someone else maintaining it?
Nobody maintains it really, the usermode driver is mostly ignored at this point,
I try to look after the kernel mgag200 for the server cards, I can
commit patches to this
if they fix things, but otherwise its mostly dead, volunteers welcome.
Dave.
>
> I've had a Xserver lockup in the mga driver, examining it with gdb showed
> this obviously broken loop:
> count = INREG(MGAREG_VCOUNT) + 2;
> while(INREG(MGAREG_VCOUNT) < count);
>
> It reads the line counter and waits until the counter advances by two. The
> cause of the lockup is this - if the kernel reschedules the Xorg process
> and lets it run in such a moment when INREG(MGAREG_VCOUNT) returns the
> maximum (or maximum minus 1) line count, the loop never exits.
>
> I created this patch for the bug, it tries to imitate the old behavior,
> but it also exits the loop when the line counter wraps to zero, preventing
> the lockup.
>
> BTW. did you notice my previous patch for pan_ctl in the mga driver?
>
> Mikulas
>
> ---
> src/mga_driver.c | 12 +++++++++---
> 1 file changed, 9 insertions(+), 3 deletions(-)
>
> Index: xf86-video-mga-1.6.3/src/mga_driver.c
> ===================================================================
> --- xf86-video-mga-1.6.3.orig/src/mga_driver.c 2013-12-05 02:15:53.000000000 +0100
> +++ xf86-video-mga-1.6.3/src/mga_driver.c 2014-03-13 22:56:10.852221315 +0100
> @@ -3618,7 +3618,7 @@ void
> MGAAdjustFrame(ADJUST_FRAME_ARGS_DECL)
> {
> SCRN_INFO_PTR(arg);
> - int Base, tmp, count;
> + int Base, tmp, count, last_vcount;
>
> MGAFBLayout *pLayout;
> MGAPtr pMga;
> @@ -3648,8 +3648,14 @@ MGAAdjustFrame(ADJUST_FRAME_ARGS_DECL)
> while (INREG8(0x1FDA) & 0x08);
> while (!(INREG8(0x1FDA) & 0x08));
> /* wait until we're past the start (fixseg.c in the DDK) */
> - count = INREG(MGAREG_VCOUNT) + 2;
> - while(INREG(MGAREG_VCOUNT) < count);
> + last_vcount = INREG(MGAREG_VCOUNT);
> + count = last_vcount + 2;
> + while (1) {
> + int vcount = INREG(MGAREG_VCOUNT);
> + if (vcount >= count) break;
> + if (vcount < last_vcount) break;
> + last_vcount = count;
> + }
>
> OUTREG16(MGAREG_CRTC_INDEX, (Base & 0x00FF00) | 0x0C);
> OUTREG16(MGAREG_CRTC_INDEX, ((Base & 0x0000FF) << 8) | 0x0D);
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
More information about the xorg-devel
mailing list