From 983d308cb8f602d1920a8c40196eb2ab6cc07bd2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 26 Jan 2015 10:47:10 +0000 Subject: agp/intel: Serialise after GTT updates An interesting bug occurs on Pineview through which the root cause is that the writes of the PTE values into the GTT is not serialised with subsequent memory access through the GTT (when using WC updates of the PTE values). This is despite there being a posting read after the GTT update. However, by changing the address of the posting read, the memory access is indeed serialised correctly. Whilst we are manipulating the memory barriers, we can remove the compiler :memory restraint on the intermediate PTE writes knowing that we explicitly perform a posting read afterwards. v2: Replace posting reads with explicit write memory barriers - in particular this is advantages in case of single page objects. Update comments to mention this issue is only with WC writes. Testcase: igt/gem_exec_big #pnv Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=88191 Tested-by: huax.lu@intel.com (v1) Signed-off-by: Chris Wilson Cc: Daniel Vetter Signed-off-by: Daniel Vetter --- drivers/char/agp/intel-gtt.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 92aa43fa8d70..0b4188b9af7c 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -225,7 +225,7 @@ static int i810_insert_dcache_entries(struct agp_memory *mem, off_t pg_start, intel_private.driver->write_entry(addr, i, type); } - readl(intel_private.gtt+i-1); + wmb(); return 0; } @@ -329,7 +329,7 @@ static void i810_write_entry(dma_addr_t addr, unsigned int entry, break; } - writel(addr | pte_flags, intel_private.gtt + entry); + writel_relaxed(addr | pte_flags, intel_private.gtt + entry); } static const struct aper_size_info_fixed intel_fake_agp_sizes[] = { @@ -735,7 +735,7 @@ static void i830_write_entry(dma_addr_t addr, unsigned int entry, if (flags == AGP_USER_CACHED_MEMORY) pte_flags |= I830_PTE_SYSTEM_CACHED; - writel(addr | pte_flags, intel_private.gtt + entry); + writel_relaxed(addr | pte_flags, intel_private.gtt + entry); } bool intel_enable_gtt(void) @@ -858,7 +858,7 @@ void intel_gtt_insert_sg_entries(struct sg_table *st, j++; } } - readl(intel_private.gtt+j-1); + wmb(); } EXPORT_SYMBOL(intel_gtt_insert_sg_entries); @@ -875,7 +875,7 @@ static void intel_gtt_insert_pages(unsigned int first_entry, intel_private.driver->write_entry(addr, j, flags); } - readl(intel_private.gtt+j-1); + wmb(); } static int intel_fake_agp_insert_entries(struct agp_memory *mem, @@ -938,7 +938,7 @@ void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries) intel_private.driver->write_entry(intel_private.scratch_page_dma, i, 0); } - readl(intel_private.gtt+i-1); + wmb(); } EXPORT_SYMBOL(intel_gtt_clear_range); @@ -1106,7 +1106,7 @@ static void i965_write_entry(dma_addr_t addr, /* Shift high bits down */ addr |= (addr >> 28) & 0xf0; - writel(addr | pte_flags, intel_private.gtt + entry); + writel_relaxed(addr | pte_flags, intel_private.gtt + entry); } static int i9xx_setup(void) -- cgit v1.2.3 From e410055331c2f474872b364dce3d4042418e892b Mon Sep 17 00:00:00 2001 From: "Wang, Yalin" Date: Wed, 28 Jan 2015 13:57:34 +0800 Subject: agp: change agp_free_page_array to use kvfree Change agp_free_page_array to use kvfree function, remove the duplicated code. Signed-off-by: Yalin Wang Signed-off-by: Dave Airlie --- drivers/char/agp/agp.h | 5 ++++- drivers/char/agp/generic.c | 11 ----------- 2 files changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index b709749c8639..4eb1c772ded7 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -219,7 +219,10 @@ struct agp_bridge_data *agp_generic_find_bridge(struct pci_dev *pdev); /* generic functions for user-populated AGP memory types */ struct agp_memory *agp_generic_alloc_user(size_t page_count, int type); void agp_alloc_page_array(size_t size, struct agp_memory *mem); -void agp_free_page_array(struct agp_memory *mem); +static inline void agp_free_page_array(struct agp_memory *mem) +{ + kvfree(mem->pages); +} /* generic routines for agp>=3 */ diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 0fbccce1cee9..f002fa5d1887 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -98,17 +98,6 @@ void agp_alloc_page_array(size_t size, struct agp_memory *mem) } EXPORT_SYMBOL(agp_alloc_page_array); -void agp_free_page_array(struct agp_memory *mem) -{ - if (is_vmalloc_addr(mem->pages)) { - vfree(mem->pages); - } else { - kfree(mem->pages); - } -} -EXPORT_SYMBOL(agp_free_page_array); - - static struct agp_memory *agp_create_user_memory(unsigned long num_agp_pages) { struct agp_memory *new; -- cgit v1.2.3