aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp/intel-agp.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2007-10-14 20:19:16 -0400
committerDave Airlie <airlied@optimus.(none)>2007-10-14 20:32:15 -0400
commita2721e998ede079db10f65e4b42310f79dc8f135 (patch)
tree32963c9bf40f3e0871d4d549bb6c3cf13abbb24c /drivers/char/agp/intel-agp.c
parent23fd50450a34f2558070ceabb0bfebc1c9604af5 (diff)
AGP fix race condition between unmapping and freeing pages
With Andi's clflush fixup, we were getting hangs on server exit, flushing the mappings after freeing each page helped. This showed up a race condition where the pages after being freed could be reused before the agp mappings had been flushed. Flushing after each single page is a bad thing for future drm work, so make the page destroy a two pass unmapping all the pages, flushing the mappings, and then destroying the pages. Signed-off-by: Dave Airlie <airlied@linux.ie> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'drivers/char/agp/intel-agp.c')
-rw-r--r--drivers/char/agp/intel-agp.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 141ca176c397..d87961993ccf 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -400,9 +400,11 @@ static void intel_i810_free_by_type(struct agp_memory *curr)
400 if (curr->page_count == 4) 400 if (curr->page_count == 4)
401 i8xx_destroy_pages(gart_to_virt(curr->memory[0])); 401 i8xx_destroy_pages(gart_to_virt(curr->memory[0]));
402 else { 402 else {
403 agp_bridge->driver->agp_destroy_page( 403 agp_bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[0]),
404 gart_to_virt(curr->memory[0])); 404 AGP_PAGE_DESTROY_UNMAP);
405 global_flush_tlb(); 405 global_flush_tlb();
406 agp_bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[0]),
407 AGP_PAGE_DESTROY_FREE);
406 } 408 }
407 agp_free_page_array(curr); 409 agp_free_page_array(curr);
408 } 410 }