From owner-svn-src-all@freebsd.org Thu Dec 8 11:39:09 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E9A42C6C146; Thu, 8 Dec 2016 11:39:09 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id AA8D819DE; Thu, 8 Dec 2016 11:39:09 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uB8Bd83L021082; Thu, 8 Dec 2016 11:39:08 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uB8Bd8BE021081; Thu, 8 Dec 2016 11:39:08 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201612081139.uB8Bd8BE021081@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Thu, 8 Dec 2016 11:39:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r309712 - head/sys/dev/drm2/i915 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 08 Dec 2016 11:39:10 -0000 Author: kib Date: Thu Dec 8 11:39:08 2016 New Revision: 309712 URL: https://svnweb.freebsd.org/changeset/base/309712 Log: Use the populate() driver paging method for i915 driver. In particular, the fault access type is accounted for when the aperture page is moved to GTT domain. On the other hand, the current pager structure is left intact, most important, only one page is instantiated per populate call. Reviewed by: alc Sponsored by: The FreeBSD Foundation MFC after: 3 weeks Modified: head/sys/dev/drm2/i915/i915_gem.c Modified: head/sys/dev/drm2/i915/i915_gem.c ============================================================================== --- head/sys/dev/drm2/i915/i915_gem.c Thu Dec 8 11:35:53 2016 (r309711) +++ head/sys/dev/drm2/i915/i915_gem.c Thu Dec 8 11:39:08 2016 (r309712) @@ -1474,8 +1474,8 @@ i915_gem_pager_ctor(void *handle, vm_oof int i915_intr_pf; static int -i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot, - vm_page_t *mres) +i915_gem_pager_populate(vm_object_t vm_obj, vm_pindex_t pidx, int fault_type, + vm_prot_t max_prot, vm_pindex_t *first, vm_pindex_t *last) { struct drm_gem_object *gem_obj = vm_obj->handle; struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); @@ -1483,31 +1483,9 @@ i915_gem_pager_fault(vm_object_t vm_obj, drm_i915_private_t *dev_priv = dev->dev_private; vm_page_t page; int ret = 0; -#ifdef FREEBSD_WIP - bool write = (prot & VM_PROT_WRITE) != 0; -#else - bool write = true; -#endif /* FREEBSD_WIP */ + bool write = (max_prot & VM_PROT_WRITE) != 0; bool pinned; - vm_object_pip_add(vm_obj, 1); - - /* - * Remove the placeholder page inserted by vm_fault() from the - * object before dropping the object lock. If - * i915_gem_release_mmap() is active in parallel on this gem - * object, then it owns the drm device sx and might find the - * placeholder already. Then, since the page is busy, - * i915_gem_release_mmap() sleeps waiting for the busy state - * of the page cleared. We will be unable to acquire drm - * device lock until i915_gem_release_mmap() is able to make a - * progress. - */ - if (*mres != NULL) { - vm_page_lock(*mres); - vm_page_remove(*mres); - vm_page_unlock(*mres); - } VM_OBJECT_WUNLOCK(vm_obj); retry: ret = 0; @@ -1527,7 +1505,7 @@ retry: * mapping for the page. Recheck. */ VM_OBJECT_WLOCK(vm_obj); - page = vm_page_lookup(vm_obj, OFF_TO_IDX(offset)); + page = vm_page_lookup(vm_obj, pidx); if (page != NULL) { if (vm_page_busied(page)) { DRM_UNLOCK(dev); @@ -1543,7 +1521,7 @@ retry: /* Now bind it into the GTT if needed */ ret = i915_gem_object_pin(obj, 0, true, false); if (ret) - goto unlock; + goto unpin; pinned = 1; ret = i915_gem_object_set_to_gtt_domain(obj, write); @@ -1556,20 +1534,19 @@ retry: obj->fault_mappable = true; - VM_OBJECT_WLOCK(vm_obj); - page = PHYS_TO_VM_PAGE(dev_priv->mm.gtt_base_addr + obj->gtt_offset + offset); - KASSERT((page->flags & PG_FICTITIOUS) != 0, - ("physical address %#jx not fictitious", - (uintmax_t)(dev_priv->mm.gtt_base_addr + obj->gtt_offset + offset))); + page = PHYS_TO_VM_PAGE(dev_priv->mm.gtt_base_addr + obj->gtt_offset + + IDX_TO_OFF(pidx)); if (page == NULL) { - VM_OBJECT_WUNLOCK(vm_obj); ret = -EFAULT; goto unpin; } KASSERT((page->flags & PG_FICTITIOUS) != 0, - ("not fictitious %p", page)); + ("physical address %#jx not fictitious, page %p", + (uintmax_t)(dev_priv->mm.gtt_base_addr + obj->gtt_offset + + IDX_TO_OFF(pidx)), page)); KASSERT(page->wire_count == 1, ("wire_count not 1 %p", page)); + VM_OBJECT_WLOCK(vm_obj); if (vm_page_busied(page)) { i915_gem_object_unpin(obj); DRM_UNLOCK(dev); @@ -1578,7 +1555,7 @@ retry: vm_page_busy_sleep(page, "915pbs", false); goto retry; } - if (vm_page_insert(page, vm_obj, OFF_TO_IDX(offset))) { + if (vm_page_insert(page, vm_obj, pidx)) { i915_gem_object_unpin(obj); DRM_UNLOCK(dev); VM_OBJECT_WUNLOCK(vm_obj); @@ -1589,33 +1566,24 @@ retry: have_page: vm_page_xbusy(page); - CTR4(KTR_DRM, "fault %p %jx %x phys %x", gem_obj, offset, prot, + CTR4(KTR_DRM, "fault %p %jx %x phys %x", gem_obj, pidx, fault_type, page->phys_addr); if (pinned) { /* * We may have not pinned the object if the page was - * found by the call to vm_page_lookup() + * found by the call to vm_page_lookup(). */ i915_gem_object_unpin(obj); } DRM_UNLOCK(dev); - if (*mres != NULL) { - KASSERT(*mres != page, ("losing %p %p", *mres, page)); - vm_page_lock(*mres); - vm_page_free(*mres); - vm_page_unlock(*mres); - } - *mres = page; - vm_object_pip_wakeup(vm_obj); + *first = *last = pidx; return (VM_PAGER_OK); unpin: - i915_gem_object_unpin(obj); -unlock: DRM_UNLOCK(dev); out: KASSERT(ret != 0, ("i915_gem_pager_fault: wrong return")); - CTR4(KTR_DRM, "fault_fail %p %jx %x err %d", gem_obj, offset, prot, + CTR4(KTR_DRM, "fault_fail %p %jx %x err %d", gem_obj, pidx, fault_type, -ret); if (ret == -ERESTARTSYS) { /* @@ -1629,7 +1597,6 @@ out: goto retry; } VM_OBJECT_WLOCK(vm_obj); - vm_object_pip_wakeup(vm_obj); return (VM_PAGER_ERROR); } @@ -1645,9 +1612,9 @@ i915_gem_pager_dtor(void *handle) } struct cdev_pager_ops i915_gem_pager_ops = { - .cdev_pg_fault = i915_gem_pager_fault, - .cdev_pg_ctor = i915_gem_pager_ctor, - .cdev_pg_dtor = i915_gem_pager_dtor + .cdev_pg_populate = i915_gem_pager_populate, + .cdev_pg_ctor = i915_gem_pager_ctor, + .cdev_pg_dtor = i915_gem_pager_dtor, }; /**