svn commit: r254870 - head/sys/dev/drm2/ttm

Jean-Sebastien Pedron dumbbell at FreeBSD.org
Sun Aug 25 15:00:48 UTC 2013


Author: dumbbell
Date: Sun Aug 25 15:00:48 2013
New Revision: 254870
URL: http://svnweb.freebsd.org/changeset/base/254870

Log:
  drm/ttm: Make ttm_bo_wait() call uninterruptible in page fault handler
  
  This fixes a crash where a SIGLALRM, heavily used by X.Org, would
  interrupt the wait, causing the page fault to fail and the "Xorg"
  process to receive a SIGSEGV.
  
  Approved by:	kib@

Modified:
  head/sys/dev/drm2/ttm/ttm_bo_vm.c

Modified: head/sys/dev/drm2/ttm/ttm_bo_vm.c
==============================================================================
--- head/sys/dev/drm2/ttm/ttm_bo_vm.c	Sun Aug 25 15:00:34 2013	(r254869)
+++ head/sys/dev/drm2/ttm/ttm_bo_vm.c	Sun Aug 25 15:00:48 2013	(r254870)
@@ -154,7 +154,23 @@ reserve:
 
 	mtx_lock(&bdev->fence_lock);
 	if (test_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags)) {
-		ret = ttm_bo_wait(bo, false, true, false);
+		/*
+		 * Here, the behavior differs between Linux and FreeBSD.
+		 *
+		 * On Linux, the wait is interruptible (3rd argument to
+		 * ttm_bo_wait). There must be some mechanism to resume
+		 * page fault handling, once the signal is processed.
+		 *
+		 * On FreeBSD, the wait is uninteruptible. This is not a
+		 * problem as we can't end up with an unkillable process
+		 * here, because the wait will eventually time out.
+		 *
+		 * An example of this situation is the Xorg process
+		 * which uses SIGALRM internally. The signal could
+		 * interrupt the wait, causing the page fault to fail
+		 * and the process to receive SIGSEGV.
+		 */
+		ret = ttm_bo_wait(bo, false, false, false);
 		mtx_unlock(&bdev->fence_lock);
 		if (unlikely(ret != 0)) {
 			retval = VM_PAGER_ERROR;


More information about the svn-src-head mailing list