[patch 2/2] agpgart - Remove unnecessary flushes.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch is to speed up flipping of pages in and out of the AGP aperture as needed by the new drm memory manager.

A number of global cache flushes are removed as well as some PCI posting flushes.
The following guidelines have been used:

1) Memory that is only mapped uncached and that has been subject to a global cache flush after the mapping was changed to uncached does not need any more cache flushes. Neither before binding to the aperture nor after unbinding.

2) Only do one PCI posting flush after a sequence of writes modifying page entries in the GATT.

Patch against davej's agpgart.git

/Thomas Hellström




diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 7a6107f..75557de 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -1076,8 +1076,8 @@ int agp_generic_insert_memory(struct agp
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 		writel(bridge->driver->mask_memory(bridge, mem->memory[i], mask_type), bridge->gatt_table+j);
-		readl(bridge->gatt_table+j);	/* PCI Posting. */
 	}
+	readl(bridge->gatt_table+j-1);	/* PCI Posting. */
 
 	bridge->driver->tlb_flush(mem);
 	return 0;
@@ -1111,10 +1111,9 @@ int agp_generic_remove_memory(struct agp
 	/* AK: bogus, should encode addresses > 4GB */
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
 		writel(bridge->scratch_page, bridge->gatt_table+i);
-		readl(bridge->gatt_table+i);	/* PCI Posting. */
 	}
+	readl(bridge->gatt_table+i-1);	/* PCI Posting. */
 
-	global_cache_flush();
 	bridge->driver->tlb_flush(mem);
 	return 0;
 }
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 677581a..aaf9b30 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -256,9 +256,8 @@ static int intel_i810_insert_entries(str
 		for (i = pg_start; i < (pg_start + mem->page_count); i++) {
 			writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID, 
 			       intel_i810_private.registers+I810_PTE_BASE+(i*4));
-			readl(intel_i810_private.registers+I810_PTE_BASE+(i*4));
-			
 		}
+		readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));
 		break;
 	case AGP_PHYS_MEMORY:
 		if (!mem->is_flushed) 
@@ -268,13 +267,13 @@ static int intel_i810_insert_entries(str
 							       mem->memory[i],
 							       mask_type),
 			       intel_i810_private.registers+I810_PTE_BASE+(j*4));
-			readl(intel_i810_private.registers+I810_PTE_BASE+(j*4));
 		}
+		readl(intel_i810_private.registers+I810_PTE_BASE+((j-1)*4));
 		break;
 	default:
 		goto out_err;
 	}
-	global_cache_flush();
+	
 	agp_bridge->driver->tlb_flush(mem);
 out:
 	ret = 0;
@@ -293,10 +292,9 @@ static int intel_i810_remove_entries(str
 
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
 		writel(agp_bridge->scratch_page, intel_i810_private.registers+I810_PTE_BASE+(i*4));
-		readl(intel_i810_private.registers+I810_PTE_BASE+(i*4))	;
 	}
-	
-	global_cache_flush();
+	readl(intel_i810_private.registers+I810_PTE_BASE+((i-1)*4));	
+
 	agp_bridge->driver->tlb_flush(mem);
 	return 0;
 }
@@ -646,7 +644,7 @@ static int intel_i830_insert_entries(str
 	if (mask_type != 0 && mask_type != AGP_PHYS_MEMORY && 
 	    mask_type != INTEL_AGP_CACHED_MEMORY)
 		goto out_err;
-
+	
 	if (!mem->is_flushed)
 		global_cache_flush();
 
@@ -654,9 +652,8 @@ static int intel_i830_insert_entries(str
 		writel(agp_bridge->driver->mask_memory(agp_bridge,
 						       mem->memory[i], mask_type),
 		       intel_i830_private.registers+I810_PTE_BASE+(j*4));
-		readl(intel_i830_private.registers+I810_PTE_BASE+(j*4));
 	}
-	global_cache_flush();
+	readl(intel_i830_private.registers+I810_PTE_BASE+((j-1)*4));
 	agp_bridge->driver->tlb_flush(mem);
 
 out:
@@ -671,8 +668,6 @@ static int intel_i830_remove_entries(str
 {
 	int i;
 
-	global_cache_flush();
-
 	if (pg_start < intel_i830_private.gtt_entries) {
 		printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
 		return -EINVAL;
@@ -680,10 +675,9 @@ static int intel_i830_remove_entries(str
 
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
 		writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
-		readl(intel_i830_private.registers+I810_PTE_BASE+(i*4));
 	}
-	
-	global_cache_flush();
+	readl(intel_i830_private.registers+I810_PTE_BASE+((i-1)*4));
+
 	agp_bridge->driver->tlb_flush(mem);
 	return 0;
 }
@@ -777,10 +771,9 @@ static int intel_i915_insert_entries(str
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 		writel(agp_bridge->driver->mask_memory(agp_bridge,
 			mem->memory[i], mask_type), intel_i830_private.gtt+j);
-		readl(intel_i830_private.gtt+j);
 	}
 	
-	global_cache_flush();
+	readl(intel_i830_private.gtt+j-1);
 	agp_bridge->driver->tlb_flush(mem);
 
  out:
@@ -795,19 +788,16 @@ static int intel_i915_remove_entries(str
 {
 	int i;
 
-	global_cache_flush();
-
 	if (pg_start < intel_i830_private.gtt_entries) {
 		printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
 		return -EINVAL;
 	}
-
+	
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
 		writel(agp_bridge->scratch_page, intel_i830_private.gtt+i);
-		readl(intel_i830_private.gtt+i);
 	}
-
-	global_cache_flush();
+	readl(intel_i830_private.gtt+i-1);
+	
 	agp_bridge->driver->tlb_flush(mem);
 	return 0;
 }

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux