diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2010-04-29 13:10:19 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2010-04-29 13:10:19 +0000 |
commit | 8ec47b926472cfd2b4354a9a26045ccb35df0c1e (patch) | |
tree | 0ed71cff62632c6016ae779f0a139111a11c9f37 /sys/dev/pci | |
parent | c6fed62d34b230b043a9047721dfc40b9ab4728b (diff) |
Finally fix the bit 17 swizzling code.
- pmap_kremove takes a va and a size, not a va range (unlike pmap_remove,
that gratuitious difference is nothing if not annoying).
- fix a memory leak of the bit 17 bitstring.
- fix the offset calculation when iterating through the dma segments.
Tested by Brandon Mercer, his machine now seems to be rock solid.
Remember kids, if a code path has not been tested fully, it does not work!
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/drm/i915_drv.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/sys/dev/pci/drm/i915_drv.c b/sys/dev/pci/drm/i915_drv.c index 91baf10270c..b3e2b61add3 100644 --- a/sys/dev/pci/drm/i915_drv.c +++ b/sys/dev/pci/drm/i915_drv.c @@ -3650,6 +3650,8 @@ i915_gem_free_object(struct drm_obj *obj) i915_gem_object_unpin(obj); i915_gem_object_unbind(obj, 0); + drm_free(obj_priv->bit_17); + obj_priv->bit_17 = NULL; /* XXX dmatag went away? */ } @@ -4518,7 +4520,7 @@ inteldrm_swizzle_page(struct vm_page *pg) #if defined (__HAVE_PMAP_DIRECT) pmap_unmap_direct(va); #else - pmap_kremove(va, va + PAGE_SIZE); + pmap_kremove(va, PAGE_SIZE); pmap_update(pmap_kernel()); uvm_km_free(kernel_map, va, PAGE_SIZE); #endif @@ -4534,12 +4536,14 @@ i915_gem_bit_17_swizzle(struct drm_obj *obj) struct vm_page *pg; bus_dma_segment_t *segp; int page_count = obj->size >> PAGE_SHIFT; - int i = 0, n = 0, ret; + int i, n, ret; if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17 || obj_priv->bit_17 == NULL) return; + segp = &obj_priv->dma_segs[0]; + n = 0; for (i = 0; i < page_count; i++) { /* compare bit 17 with previous one (in case we swapped). * if they don't match we'll have to swizzle the page @@ -4547,7 +4551,7 @@ i915_gem_bit_17_swizzle(struct drm_obj *obj) if ((((segp->ds_addr + n) >> 17) & 0x1) != test_bit(i, obj_priv->bit_17)) { /* XXX move this to somewhere where we already have pg */ - pg = PHYS_TO_VM_PAGE(segp->ds_addr + n * PAGE_SIZE); + pg = PHYS_TO_VM_PAGE(segp->ds_addr + n); KASSERT(pg != NULL); ret = inteldrm_swizzle_page(pg); if (ret) @@ -4555,7 +4559,8 @@ i915_gem_bit_17_swizzle(struct drm_obj *obj) atomic_clearbits_int(&pg->pg_flags, PG_CLEAN); } - if (++n * PAGE_SIZE > segp->ds_len) { + n += PAGE_SIZE; + if (n >= segp->ds_len) { n = 0; segp++; } @@ -4590,14 +4595,14 @@ i915_gem_save_bit_17_swizzle(struct drm_obj *obj) segp = &obj_priv->dma_segs[0]; n = 0; - i = 0; for (i = 0; i < page_count; i++) { - if ((segp->ds_addr + (n * PAGE_SIZE)) & (1 << 17)) + if ((segp->ds_addr + n) & (1 << 17)) set_bit(i, obj_priv->bit_17); else clear_bit(i, obj_priv->bit_17); - if (++n * PAGE_SIZE > segp->ds_len) { + n += PAGE_SIZE; + if (n >= segp->ds_len) { n = 0; segp++; } |