From owner-svn-src-stable-7@FreeBSD.ORG Tue Jun 23 15:59:10 2009 Return-Path: Delivered-To: svn-src-stable-7@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CAD821065673; Tue, 23 Jun 2009 15:59:10 +0000 (UTC) (envelope-from rnoland@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id AF0598FC1B; Tue, 23 Jun 2009 15:59:10 +0000 (UTC) (envelope-from rnoland@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n5NFxAYK081863; Tue, 23 Jun 2009 15:59:10 GMT (envelope-from rnoland@svn.freebsd.org) Received: (from rnoland@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n5NFxA44081861; Tue, 23 Jun 2009 15:59:10 GMT (envelope-from rnoland@svn.freebsd.org) Message-Id: <200906231559.n5NFxA44081861@svn.freebsd.org> From: Robert Noland Date: Tue, 23 Jun 2009 15:59:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r194728 - in stable/7/sys: . contrib/pf dev/drm X-BeenThere: svn-src-stable-7@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 7-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 23 Jun 2009 15:59:12 -0000 Author: rnoland Date: Tue Jun 23 15:59:10 2009 New Revision: 194728 URL: http://svn.freebsd.org/changeset/base/194728 Log: Merge 190401 from HEAD Rework the management of vblank interrupts a bit. When a vt switch occurs the irq handler is uninstalled. Interrupts and the state tracking of what was enabled/disabled wasn't working properly. This should resolve the reports of "slow windows" after a vt switch, among other things. The radeon 2d driver seems to work a bit more correctly than the Intel driver. With the Intel driver, vblank interrupts will be enabled at system startup and will only be disabled after an additional modeset (vt switch, dpms, randr event). With this patch, I am able to run glxgears synced to vblank and vt switch while it is running without ill effects. (Still didn't fix the slow window issues on Intel) Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/sys/dev/drm/drm_irq.c Modified: stable/7/sys/dev/drm/drm_irq.c ============================================================================== --- stable/7/sys/dev/drm/drm_irq.c Tue Jun 23 15:56:10 2009 (r194727) +++ stable/7/sys/dev/drm/drm_irq.c Tue Jun 23 15:59:10 2009 (r194728) @@ -80,13 +80,14 @@ static void vblank_disable_fn(void *arg) } callout_deactivate(&dev->vblank_disable_timer); - DRM_DEBUG("vblank_disable_allowed=%d\n", dev->vblank_disable_allowed); + DRM_DEBUG("vblank_disable: %s\n", dev->vblank_disable_allowed ? + "allowed" : "denied"); if (!dev->vblank_disable_allowed) return; for (i = 0; i < dev->num_crtcs; i++) { if (atomic_read(&dev->vblank[i].refcount) == 0 && - dev->vblank[i].enabled) { + dev->vblank[i].enabled && !dev->vblank[i].inmodeset) { DRM_DEBUG("disabling vblank on crtc %d\n", i); dev->vblank[i].last = dev->driver->get_vblank_counter(dev, i); @@ -149,7 +150,7 @@ err: int drm_irq_install(struct drm_device *dev) { - int retcode; + int crtc, retcode; if (dev->irq == 0 || dev->dev_private == NULL) return EINVAL; @@ -186,6 +187,17 @@ int drm_irq_install(struct drm_device *d DRM_LOCK(); dev->driver->irq_postinstall(dev); DRM_UNLOCK(); + if (dev->driver->enable_vblank) { + DRM_SPINLOCK(&dev->vbl_lock); + for( crtc = 0 ; crtc < dev->num_crtcs ; crtc++) { + if (dev->driver->enable_vblank(dev, crtc) == 0) { + dev->vblank[crtc].enabled = 1; + } + } + callout_reset(&dev->vblank_disable_timer, 5 * DRM_HZ, + (timeout_t *)vblank_disable_fn, (void *)dev); + DRM_SPINUNLOCK(&dev->vbl_lock); + } return 0; err: @@ -212,9 +224,9 @@ int drm_irq_uninstall(struct drm_device for (crtc = 0; crtc < dev->num_crtcs; crtc++) { if (dev->vblank[crtc].enabled) { DRM_WAKEUP(&dev->vblank[crtc].queue); - dev->vblank[crtc].enabled = 0; dev->vblank[crtc].last = - dev->driver->get_vblank_counter(dev, crtc); + dev->driver->get_vblank_counter(dev, crtc); + dev->vblank[crtc].enabled = 0; } } DRM_SPINUNLOCK(&dev->vbl_lock); @@ -320,9 +332,11 @@ void drm_vblank_put(struct drm_device *d /* Last user schedules interrupt disable */ atomic_subtract_acq_int(&dev->vblank[crtc].refcount, 1); + DRM_SPINLOCK(&dev->vbl_lock); if (dev->vblank[crtc].refcount == 0) callout_reset(&dev->vblank_disable_timer, 5 * DRM_HZ, (timeout_t *)vblank_disable_fn, (void *)dev); + DRM_SPINUNLOCK(&dev->vbl_lock); } int drm_modeset_ctl(struct drm_device *dev, void *data, @@ -449,31 +463,26 @@ int drm_wait_vblank(struct drm_device *d } else { DRM_DEBUG("waiting on vblank count %d, crtc %d\n", vblwait->request.sequence, crtc); - for ( ret = 0 ; !ret && !((drm_vblank_count(dev, crtc) - - vblwait->request.sequence) <= (1 << 23)) ; ) { - mtx_lock(&dev->irq_lock); - if (!((drm_vblank_count(dev, crtc) - - vblwait->request.sequence) <= (1 << 23))) - ret = mtx_sleep(&dev->vblank[crtc].queue, - &dev->irq_lock, PCATCH, "vblwtq", - 3 * DRM_HZ); - mtx_unlock(&dev->irq_lock); - } - - if (ret == ERESTART) { - DRM_DEBUG("restarting syscall\n"); - return ret; + mtx_lock(&dev->irq_lock); + dev->vblank[crtc].last = vblwait->request.sequence; + for ( ret = 0 ; !ret && !(((drm_vblank_count(dev, crtc) - + vblwait->request.sequence) <= (1 << 23)) || + !dev->irq_enabled) ; ) { + ret = mtx_sleep(&dev->vblank[crtc].queue, + &dev->irq_lock, PCATCH, "vblwtq", + 3 * DRM_HZ); } + mtx_unlock(&dev->irq_lock); - if (ret != EINTR) { + if (ret != EINTR && ret != ERESTART) { struct timeval now; microtime(&now); vblwait->reply.tval_sec = now.tv_sec; vblwait->reply.tval_usec = now.tv_usec; vblwait->reply.sequence = drm_vblank_count(dev, crtc); - DRM_DEBUG("returning %d to client\n", - vblwait->reply.sequence); + DRM_DEBUG("returning %d to client, irq_enabled %d\n", + vblwait->reply.sequence, dev->irq_enabled); } else { DRM_DEBUG("vblank wait interrupted by signal\n"); }