aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/ttm/ttm_tt.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2011-11-02 23:59:28 -0400
committerDave Airlie <airlied@redhat.com>2011-12-06 05:39:24 -0500
commitb1e5f172325547270f35e7d1e42416a606e1dbd2 (patch)
tree03fc21fd5f74add89441308008b45987d09cfbc6 /drivers/gpu/drm/ttm/ttm_tt.c
parent649bf3ca77343e3be1e0af8e21356fa569b1abd9 (diff)
drm/ttm: introduce callback for ttm_tt populate & unpopulate V4
Move the page allocation and freeing to driver callback and provide ttm code helper function for those. Most intrusive change, is the fact that we now only fully populate an object this simplify some of code designed around the page fault design. V2 Rebase on top of memory accounting overhaul V3 New rebase on top of more memory accouting changes V4 Rebase on top of no memory account changes (where/when is my delorean when i need it ?) Signed-off-by: Jerome Glisse <jglisse@redhat.com> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
Diffstat (limited to 'drivers/gpu/drm/ttm/ttm_tt.c')
-rw-r--r--drivers/gpu/drm/ttm/ttm_tt.c91
1 files changed, 5 insertions, 86 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index fbc90dce1de8..77f0e6f79f30 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -43,8 +43,6 @@
43#include "ttm/ttm_placement.h" 43#include "ttm/ttm_placement.h"
44#include "ttm/ttm_page_alloc.h" 44#include "ttm/ttm_page_alloc.h"
45 45
46static int ttm_tt_swapin(struct ttm_tt *ttm);
47
48/** 46/**
49 * Allocates storage for pointers to the pages that back the ttm. 47 * Allocates storage for pointers to the pages that back the ttm.
50 */ 48 */
@@ -63,69 +61,6 @@ static void ttm_tt_free_page_directory(struct ttm_tt *ttm)
63 ttm->dma_address = NULL; 61 ttm->dma_address = NULL;
64} 62}
65 63
66static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int index)
67{
68 struct page *p;
69 struct ttm_mem_global *mem_glob = ttm->glob->mem_glob;
70 int ret;
71
72 if (NULL == (p = ttm->pages[index])) {
73
74 ret = ttm_get_pages(&p, ttm->page_flags, ttm->caching_state, 1,
75 &ttm->dma_address[index]);
76 if (ret != 0)
77 return NULL;
78
79 ret = ttm_mem_global_alloc_page(mem_glob, p, false, false);
80 if (unlikely(ret != 0))
81 goto out_err;
82
83 ttm->pages[index] = p;
84 }
85 return p;
86out_err:
87 ttm_put_pages(&p, 1, ttm->page_flags,
88 ttm->caching_state, &ttm->dma_address[index]);
89 return NULL;
90}
91
92struct page *ttm_tt_get_page(struct ttm_tt *ttm, int index)
93{
94 int ret;
95
96 if (unlikely(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) {
97 ret = ttm_tt_swapin(ttm);
98 if (unlikely(ret != 0))
99 return NULL;
100 }
101 return __ttm_tt_get_page(ttm, index);
102}
103
104int ttm_tt_populate(struct ttm_tt *ttm)
105{
106 struct page *page;
107 unsigned long i;
108 int ret;
109
110 if (ttm->state != tt_unpopulated)
111 return 0;
112
113 if (unlikely(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) {
114 ret = ttm_tt_swapin(ttm);
115 if (unlikely(ret != 0))
116 return ret;
117 }
118
119 for (i = 0; i < ttm->num_pages; ++i) {
120 page = __ttm_tt_get_page(ttm, i);
121 if (!page)
122 return -ENOMEM;
123 }
124 ttm->state = tt_unbound;
125 return 0;
126}
127EXPORT_SYMBOL(ttm_tt_populate);
128
129#ifdef CONFIG_X86 64#ifdef CONFIG_X86
130static inline int ttm_tt_set_page_caching(struct page *p, 65static inline int ttm_tt_set_page_caching(struct page *p,
131 enum ttm_caching_state c_old, 66 enum ttm_caching_state c_old,
@@ -227,21 +162,6 @@ int ttm_tt_set_placement_caching(struct ttm_tt *ttm, uint32_t placement)
227} 162}
228EXPORT_SYMBOL(ttm_tt_set_placement_caching); 163EXPORT_SYMBOL(ttm_tt_set_placement_caching);
229 164
230static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm)
231{
232 unsigned i;
233
234 for (i = 0; i < ttm->num_pages; ++i) {
235 if (ttm->pages[i]) {
236 ttm_mem_global_free_page(ttm->glob->mem_glob,
237 ttm->pages[i]);
238 ttm_put_pages(&ttm->pages[i], 1, ttm->page_flags,
239 ttm->caching_state, &ttm->dma_address[i]);
240 }
241 }
242 ttm->state = tt_unpopulated;
243}
244
245void ttm_tt_destroy(struct ttm_tt *ttm) 165void ttm_tt_destroy(struct ttm_tt *ttm)
246{ 166{
247 if (unlikely(ttm == NULL)) 167 if (unlikely(ttm == NULL))
@@ -252,7 +172,7 @@ void ttm_tt_destroy(struct ttm_tt *ttm)
252 } 172 }
253 173
254 if (likely(ttm->pages != NULL)) { 174 if (likely(ttm->pages != NULL)) {
255 ttm_tt_free_alloced_pages(ttm); 175 ttm->bdev->driver->ttm_tt_unpopulate(ttm);
256 ttm_tt_free_page_directory(ttm); 176 ttm_tt_free_page_directory(ttm);
257 } 177 }
258 178
@@ -307,7 +227,7 @@ int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
307 if (ttm->state == tt_bound) 227 if (ttm->state == tt_bound)
308 return 0; 228 return 0;
309 229
310 ret = ttm_tt_populate(ttm); 230 ret = ttm->bdev->driver->ttm_tt_populate(ttm);
311 if (ret) 231 if (ret)
312 return ret; 232 return ret;
313 233
@@ -321,7 +241,7 @@ int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
321} 241}
322EXPORT_SYMBOL(ttm_tt_bind); 242EXPORT_SYMBOL(ttm_tt_bind);
323 243
324static int ttm_tt_swapin(struct ttm_tt *ttm) 244int ttm_tt_swapin(struct ttm_tt *ttm)
325{ 245{
326 struct address_space *swap_space; 246 struct address_space *swap_space;
327 struct file *swap_storage; 247 struct file *swap_storage;
@@ -343,7 +263,7 @@ static int ttm_tt_swapin(struct ttm_tt *ttm)
343 ret = PTR_ERR(from_page); 263 ret = PTR_ERR(from_page);
344 goto out_err; 264 goto out_err;
345 } 265 }
346 to_page = __ttm_tt_get_page(ttm, i); 266 to_page = ttm->pages[i];
347 if (unlikely(to_page == NULL)) 267 if (unlikely(to_page == NULL))
348 goto out_err; 268 goto out_err;
349 269
@@ -364,7 +284,6 @@ static int ttm_tt_swapin(struct ttm_tt *ttm)
364 284
365 return 0; 285 return 0;
366out_err: 286out_err:
367 ttm_tt_free_alloced_pages(ttm);
368 return ret; 287 return ret;
369} 288}
370 289
@@ -416,7 +335,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
416 page_cache_release(to_page); 335 page_cache_release(to_page);
417 } 336 }
418 337
419 ttm_tt_free_alloced_pages(ttm); 338 ttm->bdev->driver->ttm_tt_unpopulate(ttm);
420 ttm->swap_storage = swap_storage; 339 ttm->swap_storage = swap_storage;
421 ttm->page_flags |= TTM_PAGE_FLAG_SWAPPED; 340 ttm->page_flags |= TTM_PAGE_FLAG_SWAPPED;
422 if (persistent_swap_storage) 341 if (persistent_swap_storage)