summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2010-04-29 13:10:19 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2010-04-29 13:10:19 +0000
commit8ec47b926472cfd2b4354a9a26045ccb35df0c1e (patch)
tree0ed71cff62632c6016ae779f0a139111a11c9f37 /sys/dev/pci
parentc6fed62d34b230b043a9047721dfc40b9ab4728b (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.c19
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++;
}