From 881ee70ab7bab5d6f6140dc9bf1e19c7b5844084 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 16 Dec 2007 01:12:07 -0800 Subject: Move dummy_read_page from drm_ttm_set_user to drm_ttm_create. I'm hoping to use the dummy_read_page for kernel allocated buffers to avoid allocating extra pages for read-only buffers (like vertex and batch buffers). This also eliminates the 'write' parameter to drm_ttm_set_user and just has DRM_TTM_PAGE_WRITE passed into drm_ttm_create. --- linux-core/drm_bo.c | 15 ++++++++++----- linux-core/drm_objects.h | 10 +++++----- linux-core/drm_ttm.c | 16 +++++++--------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index eced94ea..e7b9c5b1 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -137,27 +137,32 @@ static int drm_bo_add_ttm(struct drm_buffer_object *bo) { struct drm_device *dev = bo->dev; int ret = 0; + uint32_t page_flags = 0; DRM_ASSERT_LOCKED(&bo->mutex); bo->ttm = NULL; + if (bo->mem.mask & DRM_BO_FLAG_WRITE) + page_flags |= DRM_TTM_PAGE_WRITE; + switch (bo->type) { case drm_bo_type_dc: case drm_bo_type_kernel: - bo->ttm = drm_ttm_create(dev, bo->num_pages << PAGE_SHIFT, 0); + bo->ttm = drm_ttm_create(dev, bo->num_pages << PAGE_SHIFT, + page_flags, dev->bm.dummy_read_page); if (!bo->ttm) ret = -ENOMEM; break; case drm_bo_type_user: - bo->ttm = drm_ttm_create(dev, bo->num_pages << PAGE_SHIFT, DRM_TTM_PAGE_USER); + bo->ttm = drm_ttm_create(dev, bo->num_pages << PAGE_SHIFT, + page_flags | DRM_TTM_PAGE_USER, + dev->bm.dummy_read_page); if (!bo->ttm) ret = -ENOMEM; ret = drm_ttm_set_user(bo->ttm, current, - bo->mem.mask & DRM_BO_FLAG_WRITE, bo->buffer_start, - bo->num_pages, - dev->bm.dummy_read_page); + bo->num_pages); if (ret) return ret; diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index fa029d8e..375420dc 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -297,7 +297,9 @@ struct drm_ttm { }; -extern struct drm_ttm *drm_ttm_create(struct drm_device *dev, unsigned long size, uint32_t page_flags); +extern struct drm_ttm *drm_ttm_create(struct drm_device *dev, unsigned long size, + uint32_t page_flags, + struct page *dummy_read_page); extern int drm_ttm_bind(struct drm_ttm *ttm, struct drm_bo_mem_reg *bo_mem); extern void drm_ttm_unbind(struct drm_ttm *ttm); extern void drm_ttm_evict(struct drm_ttm *ttm); @@ -307,10 +309,8 @@ extern void drm_ttm_cache_flush(void); extern int drm_ttm_populate(struct drm_ttm *ttm); extern int drm_ttm_set_user(struct drm_ttm *ttm, struct task_struct *tsk, - int write, unsigned long start, - unsigned long num_pages, - struct page *dummy_read_page); + unsigned long num_pages); /* * Destroy a ttm. The user normally calls drmRmMap or a similar IOCTL to do @@ -362,7 +362,7 @@ extern int drm_ttm_destroy(struct drm_ttm *ttm); /* * This ttm will be written to by the GPU */ -#define DRM_TTM_PAGE_USER_WRITE (1 << 6) +#define DRM_TTM_PAGE_WRITE (1 << 6) /* * This ttm was mapped to the GPU, and so the contents may have * been modified diff --git a/linux-core/drm_ttm.c b/linux-core/drm_ttm.c index e3b9fcce..c1fc13fc 100644 --- a/linux-core/drm_ttm.c +++ b/linux-core/drm_ttm.c @@ -145,7 +145,7 @@ static void drm_ttm_free_user_pages(struct drm_ttm *ttm) int i; BUG_ON(!(ttm->page_flags & DRM_TTM_PAGE_USER)); - write = ((ttm->page_flags & DRM_TTM_PAGE_USER_WRITE) != 0); + write = ((ttm->page_flags & DRM_TTM_PAGE_WRITE) != 0); dirty = ((ttm->page_flags & DRM_TTM_PAGE_USER_DIRTY) != 0); for (i = 0; i < ttm->num_pages; ++i) { @@ -257,22 +257,17 @@ EXPORT_SYMBOL(drm_ttm_get_page); */ int drm_ttm_set_user(struct drm_ttm *ttm, struct task_struct *tsk, - int write, unsigned long start, - unsigned long num_pages, - struct page *dummy_read_page) + unsigned long num_pages) { struct mm_struct *mm = tsk->mm; int ret; int i; + int write = (ttm->page_flags & DRM_TTM_PAGE_WRITE) != 0; BUG_ON(num_pages != ttm->num_pages); BUG_ON((ttm->page_flags & DRM_TTM_PAGE_USER) == 0); - ttm->dummy_read_page = dummy_read_page; - if (write) - ttm->page_flags |= DRM_TTM_PAGE_USER_WRITE; - down_read(&mm->mmap_sem); ret = get_user_pages(tsk, mm, start, num_pages, write, 0, ttm->pages, NULL); @@ -331,7 +326,8 @@ int drm_ttm_populate(struct drm_ttm *ttm) * Allocate and initialize a ttm, leaving it unpopulated at this time */ -struct drm_ttm *drm_ttm_create(struct drm_device *dev, unsigned long size, uint32_t page_flags) +struct drm_ttm *drm_ttm_create(struct drm_device *dev, unsigned long size, + uint32_t page_flags, struct page *dummy_read_page) { struct drm_bo_driver *bo_driver = dev->driver->bo_driver; struct drm_ttm *ttm; @@ -351,6 +347,8 @@ struct drm_ttm *drm_ttm_create(struct drm_device *dev, unsigned long size, uint3 ttm->page_flags = page_flags; + ttm->dummy_read_page = dummy_read_page; + /* * Account also for AGP module memory usage. */ -- cgit v1.2.3