aboutsummaryrefslogtreecommitdiff
path: root/linux-core/drm_agpsupport.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2007-12-16 01:47:51 -0800
committerKeith Packard <keithp@keithp.com>2007-12-21 12:16:29 -0800
commit37fb2ac4071f62bad2c36cc9ca84f9c8feee6bf5 (patch)
tree75b313d56bd7df93dbc0191492b28995a4dd4b99 /linux-core/drm_agpsupport.c
parent881ee70ab7bab5d6f6140dc9bf1e19c7b5844084 (diff)
Use dummy_read_page for unpopulated kernel-allocated ttm pages.
Previously, dummy_read_page was used only for read-only user allocations; it filled in pages that were not present in the user address map (presumably, these were allocated but never written to pages). This patch allows them to be used for read-only ttms allocated from the kernel, so that applications can over-allocate buffers without forcing every page to be allocated.
Diffstat (limited to 'linux-core/drm_agpsupport.c')
-rw-r--r--linux-core/drm_agpsupport.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c
index e8bfaea4..02187017 100644
--- a/linux-core/drm_agpsupport.c
+++ b/linux-core/drm_agpsupport.c
@@ -505,12 +505,14 @@ static int drm_agp_needs_unbind_cache_adjust(struct drm_ttm_backend *backend)
static int drm_agp_populate(struct drm_ttm_backend *backend,
- unsigned long num_pages, struct page **pages)
+ unsigned long num_pages, struct page **pages,
+ struct page *dummy_read_page)
{
struct drm_agp_ttm_backend *agp_be =
container_of(backend, struct drm_agp_ttm_backend, backend);
struct page **cur_page, **last_page = pages + num_pages;
DRM_AGP_MEM *mem;
+ int dummy_page_count = 0;
if (drm_alloc_memctl(num_pages * sizeof(void *)))
return -1;
@@ -528,8 +530,16 @@ static int drm_agp_populate(struct drm_ttm_backend *backend,
DRM_DEBUG("Current page count is %ld\n", (long) mem->page_count);
mem->page_count = 0;
- for (cur_page = pages; cur_page < last_page; ++cur_page)
- mem->memory[mem->page_count++] = phys_to_gart(page_to_phys(*cur_page));
+ for (cur_page = pages; cur_page < last_page; ++cur_page) {
+ struct page *page = *cur_page;
+ if (!page) {
+ page = dummy_read_page;
+ ++dummy_page_count;
+ }
+ mem->memory[mem->page_count++] = phys_to_gart(page_to_phys(page));
+ }
+ if (dummy_page_count)
+ DRM_DEBUG("Mapped %d dummy pages\n", dummy_page_count);
agp_be->mem = mem;
return 0;
}