Certainly can't see any immediate problem David. We can always cut a 4.3.1 if issues are found anyway.
Alan. On Fri, Feb 14, 2003 at 04:17:16 -0500, David Dawes wrote: > Egbert and I have been looking into the issues that are preventing a second > X server to be started for i810/830M platforms when DRI is enabled. Several > issues were found: > > 1. The i810 support doesn't unbind/release the agpgart module when VT > switching away, and this prevents a second X server from acquiring > it. Since the i810 driver requires agpgart access even for 2D > operation, this is prevents a second X server from running. A fix > for this is to add the unbind/release calls at LeaveVT, and > acquire/rebind at EnterVT. The attached patch does this. It also > makes a small change to the unbind code in the DRM kernel modules > to handle this. > > 2. The 830M support does unbind/release the agpgart module, but code > in DRM(release) called when closing a /dev/dri/* device blocks > until it can obtain the lock. Since the first server holds the > lock while switched away, the second one can never get it, so it > ends up blocking in close(). The second server opens/closes the > devices to find out whether DRI can be enabled. DRI can't be > enabled on the second server (which isn't a problem), but this > blocking behaviour is preventing it from starting up at all. I've > found that this can be solved by keeping track of whether the opener > has ever tried to acquire the lock, and not try to acquire it at > close/release when it had never previously been acquired. The patch > below implements this. > > 3. The drm module AGP support code keeps track of a "handle" for > allocated AGP regions. It uses the memory address returned from > the allocation for this purpose. This would normally be unique, > but for the i810 driver case where "DCACHE" memory is "allocated". > In the DCACHE case, the allocated memory is freed immediately (since > DCACHE doesn't come from the system memory pool), and the next > allocation often ends up getting the same memory address, and thus > the same "handle". This showed up as a problem when the unbind/rebind > code was added. > > The user-level agpgart interfaces use a "key" value to uniquely > identify allocated AGP regions. I don't know why the DRM module > doesn't do the same, since the key is guaranteed to be unique. > The patch below changes the handle to be the "key" value. > > I'm wary of making changes like this so close to the 4.3 release, but > I would like to see this problem fixed in 4.3. Does anyone see any > potential problems with the attached patch? > > David > -- > David Dawes > Release Engineer/Architect The XFree86 Project > www.XFree86.org/~dawes > Index: drivers/i810/i810.h > =================================================================== > RCS file: /home/x-cvs/xc/programs/Xserver/hw/xfree86/drivers/i810/i810.h,v > retrieving revision 1.37 > diff -u -r1.37 i810.h > --- drivers/i810/i810.h 2002/12/10 01:27:04 1.37 > +++ drivers/i810/i810.h 2003/02/14 20:00:33 > @@ -264,6 +264,9 @@ > extern Bool I810DRIFinishScreenInit(ScreenPtr pScreen); > extern Bool I810InitDma(ScrnInfoPtr pScrn); > extern Bool I810CleanupDma(ScrnInfoPtr pScrn); > +extern Bool I810DRILeave(ScrnInfoPtr pScrn); > +extern Bool I810DRIEnter(ScrnInfoPtr pScrn); > + > > #define I810PTR(p) ((I810Ptr)((p)->driverPrivate)) > #define I810REGPTR(p) (&(I810PTR(p)->ModeReg)) > Index: drivers/i810/i810_dri.c > =================================================================== > RCS file: /home/x-cvs/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_dri.c,v > retrieving revision 1.33 > diff -u -r1.33 i810_dri.c > --- drivers/i810/i810_dri.c 2002/12/10 01:27:04 1.33 > +++ drivers/i810/i810_dri.c 2003/02/14 20:00:33 > @@ -1218,3 +1218,84 @@ > > pI810->AccelInfoRec->NeedToSync = TRUE; > } > + > +Bool > +I810DRILeave(ScrnInfoPtr pScrn) > +{ > + I810Ptr pI810 = I810PTR(pScrn); > + > + if (pI810->directRenderingEnabled) { > + if (pI810->dcacheHandle != 0) > + if (drmAgpUnbind(pI810->drmSubFD, pI810->dcacheHandle) != 0) { > + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); > + return FALSE; > + } > + if (pI810->backHandle != 0) > + if (drmAgpUnbind(pI810->drmSubFD, pI810->backHandle) != 0) { > + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); > + return FALSE; > + } > + if (pI810->zHandle != 0) > + if (drmAgpUnbind(pI810->drmSubFD, pI810->zHandle) != 0) { > + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); > + return FALSE; > + } > + if (pI810->sysmemHandle != 0) > + if (drmAgpUnbind(pI810->drmSubFD, pI810->sysmemHandle) != 0) { > + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); > + return FALSE; > + } > + if (pI810->xvmcHandle != 0) > + if (drmAgpUnbind(pI810->drmSubFD, pI810->xvmcHandle) != 0) { > + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); > + return FALSE; > + } > + if (pI810->cursorHandle != 0) > + if (drmAgpUnbind(pI810->drmSubFD, pI810->cursorHandle) != 0) { > + xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"%s\n",strerror(errno)); > + return FALSE; > + } > + if (pI810->agpAcquired == TRUE) > + drmAgpRelease(pI810->drmSubFD); > + pI810->agpAcquired = FALSE; > + } > + return TRUE; > +} > + > +Bool > +I810DRIEnter(ScrnInfoPtr pScrn) > +{ > + I810Ptr pI810 = I810PTR(pScrn); > + > + if (pI810->directRenderingEnabled) { > + > + if (pI810->agpAcquired == FALSE) > + drmAgpAcquire(pI810->drmSubFD); > + pI810->agpAcquired = TRUE; > + if (pI810->dcacheHandle != 0) > + if (drmAgpBind(pI810->drmSubFD, pI810->dcacheHandle, > + pI810->DepthOffset) != 0) > + return FALSE; > + if (pI810->backHandle != 0) > + if (drmAgpBind(pI810->drmSubFD, pI810->backHandle, > + pI810->BackOffset) != 0) > + return FALSE; > + if (pI810->zHandle != 0) > + if (drmAgpBind(pI810->drmSubFD, pI810->zHandle, > + pI810->DepthOffset) != 0) > + return FALSE; > + if (pI810->sysmemHandle != 0) > + if (drmAgpBind(pI810->drmSubFD, pI810->sysmemHandle, > + 0) != 0) > + return FALSE; > + if (pI810->xvmcHandle != 0) > + if (drmAgpBind(pI810->drmSubFD, pI810->xvmcHandle, > + pI810->MC.Start) != 0) > + return FALSE; > + if (pI810->cursorHandle != 0) > + if (drmAgpBind(pI810->drmSubFD, pI810->cursorHandle, > + pI810->CursorStart) != 0) > + return FALSE; > + } > + return TRUE; > +} > Index: drivers/i810/i810_driver.c > =================================================================== > RCS file: /home/x-cvs/xc/programs/Xserver/hw/xfree86/drivers/i810/i810_driver.c,v > retrieving revision 1.79 > diff -u -r1.79 i810_driver.c > --- drivers/i810/i810_driver.c 2003/02/14 17:12:42 1.79 > +++ drivers/i810/i810_driver.c 2003/02/14 20:00:21 > @@ -2218,6 +2218,9 @@ > return FALSE; > > #ifdef XF86DRI > + if (!I810DRIEnter(pScrn)) > + return FALSE; > + > if (pI810->directRenderingEnabled) { > if (I810_DEBUG & DEBUG_VERBOSE_DRI) > ErrorF("calling dri unlock\n"); > @@ -2260,6 +2263,11 @@ > > if (!I810UnbindGARTMemory(pScrn)) > return; > + > +#ifdef XF86DRI > + if (!I810DRILeave(pScrn)) > + return; > +#endif > > vgaHWLock(hwp); > } > Index: os-support/linux/drm/kernel/drmP.h > =================================================================== > RCS file: >/home/x-cvs/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h,v > retrieving revision 1.27 > diff -u -r1.27 drmP.h > --- os-support/linux/drm/kernel/drmP.h 2003/01/29 23:00:43 1.27 > +++ os-support/linux/drm/kernel/drmP.h 2003/02/14 19:53:44 > @@ -418,6 +418,7 @@ > struct drm_file *prev; > struct drm_device *dev; > int remove_auth_on_close; > + unsigned long lock_count; > } drm_file_t; > > > @@ -484,7 +485,7 @@ > > #if __REALLY_HAVE_AGP > typedef struct drm_agp_mem { > - unsigned long handle; > + int key; > agp_memory *memory; > unsigned long bound; /* address */ > int pages; > Index: os-support/linux/drm/kernel/drm_agpsupport.h > =================================================================== > RCS file: >/home/x-cvs/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_agpsupport.h,v > retrieving revision 1.7 > diff -u -r1.7 drm_agpsupport.h > --- os-support/linux/drm/kernel/drm_agpsupport.h 2002/12/16 16:19:28 1.7 > +++ os-support/linux/drm/kernel/drm_agpsupport.h 2003/02/14 20:01:18 > @@ -147,7 +147,7 @@ > return -ENOMEM; > } > > - entry->handle = (unsigned long)memory->memory; > + entry->key = memory->key; > entry->memory = memory; > entry->bound = 0; > entry->pages = pages; > @@ -156,7 +156,7 @@ > if (dev->agp->memory) dev->agp->memory->prev = entry; > dev->agp->memory = entry; > > - request.handle = entry->handle; > + request.handle = entry->key; > request.physical = memory->physical; > > if (copy_to_user((drm_agp_buffer_t *)arg, &request, sizeof(request))) { > @@ -175,7 +175,7 @@ > drm_agp_mem_t *entry; > > for (entry = dev->agp->memory; entry; entry = entry->next) { > - if (entry->handle == handle) return entry; > + if (entry->key == handle) return entry; > } > return NULL; > } > @@ -187,6 +187,7 @@ > drm_device_t *dev = priv->dev; > drm_agp_binding_t request; > drm_agp_mem_t *entry; > + int ret; > > if (!dev->agp || !dev->agp->acquired) return -EINVAL; > if (copy_from_user(&request, (drm_agp_binding_t *)arg, sizeof(request))) > @@ -194,7 +195,10 @@ > if (!(entry = DRM(agp_lookup_entry)(dev, request.handle))) > return -EINVAL; > if (!entry->bound) return -EINVAL; > - return DRM(unbind_agp)(entry->memory); > + ret = DRM(unbind_agp)(entry->memory); > + if (ret == 0) > + entry->bound = 0; > + return ret; > } > > int DRM(agp_bind)(struct inode *inode, struct file *filp, > Index: os-support/linux/drm/kernel/drm_drv.h > =================================================================== > RCS file: >/home/x-cvs/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_drv.h,v > retrieving revision 1.10 > diff -u -r1.10 drm_drv.h > --- os-support/linux/drm/kernel/drm_drv.h 2002/11/25 14:05:04 1.10 > +++ os-support/linux/drm/kernel/drm_drv.h 2003/02/14 17:32:02 > @@ -768,7 +768,7 @@ > DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", > current->pid, (long)dev->device, dev->open_count ); > > - if ( dev->lock.hw_lock && > + if ( priv->lock_count && dev->lock.hw_lock && > _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && > dev->lock.pid == current->pid ) { > DRM_DEBUG( "Process %d dead, freeing lock for context %d\n", > @@ -786,7 +786,7 @@ > server. */ > } > #if __HAVE_RELEASE > - else if ( dev->lock.hw_lock ) { > + else if ( priv->lock_count && dev->lock.hw_lock ) { > /* The lock is required to reclaim buffers */ > DECLARE_WAITQUEUE( entry, current ); > add_wait_queue( &dev->lock.lock_queue, &entry ); > @@ -932,6 +932,8 @@ > > dev->lck_start = start = get_cycles(); > #endif > + > + ++priv->lock_count; > > if ( copy_from_user( &lock, (drm_lock_t *)arg, sizeof(lock) ) ) > return -EFAULT; > Index: os-support/linux/drm/kernel/drm_fops.h > =================================================================== > RCS file: >/home/x-cvs/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm_fops.h,v > retrieving revision 1.7 > diff -u -r1.7 drm_fops.h > --- os-support/linux/drm/kernel/drm_fops.h 2002/11/25 14:05:04 1.7 > +++ os-support/linux/drm/kernel/drm_fops.h 2003/02/14 17:32:26 > @@ -57,6 +57,7 @@ > priv->dev = dev; > priv->ioctl_count = 0; > priv->authenticated = capable(CAP_SYS_ADMIN); > + priv->lock_count = 0; > > down(&dev->struct_sem); > if (!dev->file_last) { ------------------------------------------------------- This SF.NET email is sponsored by: FREE SSL Guide from Thawte are you planning your Web Server Security? Click here to get a FREE Thawte SSL guide and find the answers to all your SSL security issues. http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0026en _______________________________________________ Dri-devel mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/dri-devel