[Intel-gfx] [PATCH] Use zero videoRam and aligned size limit in DRM mode

Wu Fengguang fengguang.wu at intel.com
Thu Apr 30 15:17:26 CEST 2009


On Thu, Apr 30, 2009 at 08:56:36PM +0800, Magnus Kessler wrote:
> On Thursday 30 Apr 2009 13:24:17 Wu Fengguang wrote:
> > On Thu, Apr 30, 2009 at 07:44:21PM +0800, Magnus Kessler wrote:
> > > On Thursday 30 Apr 2009 11:44:59 Wu Fengguang wrote:
> > > > Explictly set videoRam to 0 in drm mode, to indicate "no size limit".
> > > > And to use a large _aligned_ size limit in this case. Because
> > > > i830_allocate_aperture() does a testing
> > > >
> > > >         if (mem->end <= scan->next->offset)
> > > >                 break;
> > > >
> > > > which can fail in a very tricky way when
> > > >         mem->end           = rounded up size limit
> > > >         scan->next->offset = untouched size limit
> > > >
> > > > Reported-by: Magnus Kessler <Magnus.Kessler at gmx.net>
> > > > Tested-by: Magnus Kessler <Magnus.Kessler at gmx.net>
> > > > Signed-off-by: Wu Fengguang <fengguang.wu at intel.com>
> > > > ---
> > > >  src/i830_driver.c |    2 +-
> > > >  src/i830_memory.c |    5 ++++-
> > > >  2 files changed, 5 insertions(+), 2 deletions(-)
> > > >
> > > > --- xf86-video-intel.orig/src/i830_driver.c
> > > > +++ xf86-video-intel/src/i830_driver.c
> > > > @@ -2550,7 +2550,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr
> > > >
> > > >     if (pI830->use_drm_mode) {
> > > >         pI830->stolen_size = 0;
> > > > -       pScrn->videoRam = ~0UL / KB(1);
> > > > +       pScrn->videoRam = 0;
> > > >     } else {
> > > >         I830AdjustMemory(pScreen);
> > > >     }
> > > > --- xf86-video-intel.orig/src/i830_memory.c
> > > > +++ xf86-video-intel/src/i830_memory.c
> > > > @@ -394,6 +394,9 @@ i830_allocator_init(ScrnInfoPtr pScrn, u
> > > >  	return FALSE;
> > > >      }
> > > >
> > > > +    if (size == 0) /* use_drm_mode: no size limit */
> > > > +	    size = ALIGN(ULONG_MAX >> 16, GTT_PAGE_SIZE);
> > > > +
> > >
> > > ATTENTION: This only limits the size to 48 bits on a 64 bit machine. On
> > > 32- bit it limits it to just 16. Just ULONG_MAX mimics the previous
> > > behaviour. Can you explain the subtle symptoms with unaligned values a
> > > bit more in detail?
> >
> > Ah, good spot!
> >
> > i830_allocate_aperture() does ALIGN() for mem->end. So..
> >
> >          663         mem->end = mem->offset + size;
> >          664         if (flags & ALIGN_BOTH_ENDS)
> >          665             mem->end = ROUND_TO(mem->end, alignment);
> >          666         if (mem->end <= scan->next->offset)
> > (expands to) =====>  if (ALIGN(size) <= size)
> >          667             break;
> >          668     }
> >
> > So either @size is already aligned, or size=ULONG_MAX so that
> > ALIGN(size) wraps around to 0. Otherwise the testing is wrong.
> 
> Thanks for the explanation.
> 
> >
> > > >      start->key = -1;
> > > >      start->offset = 0;
> > > >      start->end = start->offset;
> > > > @@ -425,7 +428,7 @@ i830_allocator_init(ScrnInfoPtr pScrn, u
> > > >       * rather than after DRIFinishScreenInit.
> > > >       */
> > > >      if (pI830->directRenderingType == DRI_DRI2 && has_gem) {
> > > > -	int mmsize;
> > > > +	unsigned long mmsize;
> > > >
> > > >  	/* Take over all of the graphics aperture minus enough to for
> > > >  	 * physical-address allocations of cursor/overlay registers.
> > >
> > > Although this works fine for me on 64 bit I'm going to
> > >
> > > NAcked-by: Magnus Kessler <Magnus.Kessler at gmx.net>
> >
> > So let's do (ULONG_MAX/2)? You know an unaligned size is wrong anyway:
> > all offset and size shall be aligned as imposed by the current design.
> 
> Sorry, you are right about the need for alignment. Oversimplification on my 
> part. However, I'm still not sure about the value. The original code used 
> ~0UL/KB(1), which is equivalent to ULONG_MAX/KB(1) (i.e ULONG_MAX/1024 or 
> ULONG_MAX >> 10). Would this be appropriate (with alignment, of course)? It 
> changes nothing on 32-bit AFAICT and works fine on 64-bit as well.

We have to do something. Because the current value is *unsafe*.

        I830ScreenInit()
          videoRam = ULONG_MAX/KB(1)
          i830_memory_init()
            i830_allocator_init(videoRam * KB(1)))
              size = ULONG_MAX - 1023

So size is aligned to 1K instead of 4K.

Why the bug didn't turn up in our tests?  Here is one more caveat:
size (or rather mmsize) will be *substracted* in i830_allocator_init()
before passing on into i830_allocate_aperture().

 436         mmsize = size;
 437 
 438         /* Overlay and cursors, if physical, need to be allocated outside
 439          * of the kernel memory manager.
 440          */
 441         if (!OVERLAY_NOPHYSICAL(pI830) && !OVERLAY_NOEXIST(pI830)) {
 442             mmsize -= ROUND_TO(OVERLAY_SIZE, GTT_PAGE_SIZE);
 443         }
 444         if (pI830->CursorNeedsPhysical) {
 445             mmsize -= 2 * (ROUND_TO(HWCURSOR_SIZE, GTT_PAGE_SIZE) +
 446                     ROUND_TO(HWCURSOR_SIZE_ARGB, GTT_PAGE_SIZE));
 447         }
 448         if (pI830->fb_compression)
 449             mmsize -= MB(6) + ROUND_TO_PAGE(FBC_LL_SIZE + FBC_LL_PAD);
 450         /* Can't do GEM on stolen memory */
 451         mmsize -= pI830->stolen_size;
 452         
 453         /* Create the aperture allocation */
 454         pI830->memory_manager =
 455             i830_allocate_aperture(pScrn, "DRI memory manager",
 456                                    mmsize, 0, GTT_PAGE_SIZE,

So: if the substractions are more than 3K, then we are safe. Otherwise
the bug is going to show up.

Thanks,
Fengguang




More information about the Intel-gfx mailing list