Skip to content

Commit

Permalink
agp/intel: Serialise after GTT updates
Browse files Browse the repository at this point in the history
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 <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
ickle authored and danvet committed Jan 28, 2015
1 parent cea3bf8 commit 983d308
Showing 1 changed file with 7 additions and 7 deletions.
14 changes: 7 additions & 7 deletions drivers/char/agp/intel-gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);

Expand All @@ -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,
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 983d308

Please sign in to comment.