> Running the updated xf86-video-intel driver uncovered a bug in the
> kernel drm code.  The page fault handler wasn't handling some of the
> possible errors correctly.  This made the X server die with a SIGSEGV.
> The diff below brings things closer to what Linux does, and seems to
> fix the crashes I was seeing.  A bit more testing would be welcome
> though.  Note that this needs the commit to drmP.h I just made, which
> might not have made it to all the anoncvs servers yet.
> 
> 
> Index: i915_gem.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_gem.c,v
> retrieving revision 1.68
> diff -u -p -r1.68 i915_gem.c
> --- i915_gem.c        2 Feb 2014 10:54:10 -0000       1.68
> +++ i915_gem.c        4 Feb 2014 22:47:53 -0000
> @@ -1522,6 +1522,7 @@ i915_gem_fault(struct drm_gem_object *ge
>                           NULL, NULL);
>                       DRM_UNLOCK();
>                       dev_priv->entries--;
> +                     pmap_update(ufi->orig_map->pmap);
>                       uvm_wait("intelflt");
>                       return (VM_PAGER_REFAULT);
>               }
> @@ -1533,18 +1534,42 @@ unlock:
>       DRM_UNLOCK();
>       dev_priv->entries--;
>       pmap_update(ufi->orig_map->pmap);
> -     if (ret == -EIO) {
> +
> +     switch (ret) {
> +     case -EIO:
> +             /* If this -EIO is due to a gpu hang, give the reset code a
> +              * chance to clean up the mess. Otherwise return the proper
> +              * SIGBUS. */
> +             if (!atomic_read(&dev_priv->mm.wedged))
> +                     return VM_PAGER_ERROR;
> +     case -EAGAIN:
> +             /* Give the error handler a chance to run and move the
> +              * objects off the GPU active list. Next time we service the
> +              * fault, we should be able to transition the page into the
> +              * GTT without touching the GPU (and so avoid further
> +              * EIO/EGAIN). If the GPU is wedged, then there is no issue
> +              * with coherency, just lost writes.
> +              */
> +#if 0
> +             set_need_resched();
> +#endif
> +     case 0:
> +     case -ERESTART:
> +     case -EINTR:
> +     case -EBUSY:
>               /*
> -              * EIO means we're wedged, so upon resetting the gpu we'll
> -              * be alright and can refault. XXX only on resettable chips.
> +              * EBUSY is ok: this just means that another thread
> +              * already did the job.
>                */
> -             ret = VM_PAGER_REFAULT;
> -     } else if (ret) {
> -             ret = VM_PAGER_ERROR;
> -     } else {
> -             ret = VM_PAGER_OK;
> +             return VM_PAGER_OK;
> +     case -ENOMEM:
> +             return VM_PAGER_ERROR;
> +     case -ENOSPC:
> +             return VM_PAGER_ERROR;
> +     default:
> +             WARN_ONCE(ret, "unhandled error in i915_gem_fault: %i\n", ret);
> +             return VM_PAGER_ERROR;
>       }
> -     return ret;
>  }
>  
>  /**
> 
Thanks, this works good for me too -- no X segfaults anymore.

Reply via email to