The CPU cache must be flushed _before_ we start modifying the kernel map ptes,

otherwise data will be missing, which becomes apparent when the kernel evicts
batch buffers which are likely to be written into in the evicted state,
and then rebound to the AGP aperture.
This means we cannot rely on the AGP module to flush the
cache for us.
main
Thomas Hellstrom 2006-10-21 14:17:51 +02:00
parent 9321592149
commit 9ed4656799
2 changed files with 16 additions and 1 deletions

View File

@ -610,7 +610,7 @@ static int drm_agp_bind_ttm(drm_ttm_backend_t *backend,
DRM_DEBUG("drm_agp_bind_ttm\n");
DRM_MASK_VAL(backend->flags, DRM_BE_FLAG_BOUND_CACHED,
(cached) ? DRM_BE_FLAG_BOUND_CACHED : 0);
mem->is_flushed = FALSE;
mem->is_flushed = TRUE;
mem->type = (cached) ? agp_priv->cached_type : agp_priv->uncached_type;
ret = drm_agp_bind_memory(mem, offset);
if (ret) {

View File

@ -28,6 +28,18 @@
#include "drmP.h"
static void drm_ttm_ipi_handler(void *null)
{
wbinvd();
}
static void drm_ttm_cache_flush(void)
{
if (on_each_cpu(drm_ttm_ipi_handler, NULL, 1, 1) != 0)
DRM_ERROR("Timed out waiting for drm cache flush.\n");
}
/*
* Use kmalloc if possible. Otherwise fall back to vmalloc.
*/
@ -99,6 +111,9 @@ static int drm_set_caching(drm_ttm_t * ttm, int noncached)
if ((ttm->page_flags & DRM_TTM_PAGE_UNCACHED) == noncached)
return 0;
if (noncached)
drm_ttm_cache_flush();
for (i = 0; i < ttm->num_pages; ++i) {
cur_page = ttm->pages + i;
if (*cur_page) {