Branch data Line data Source code
1 : : /*
2 : : * SPDX-License-Identifier: MIT
3 : : *
4 : : * Copyright © 2014-2016 Intel Corporation
5 : : */
6 : :
7 : : #include <linux/pagevec.h>
8 : : #include <linux/swap.h>
9 : :
10 : : #include "gem/i915_gem_region.h"
11 : : #include "i915_drv.h"
12 : : #include "i915_gemfs.h"
13 : : #include "i915_gem_object.h"
14 : : #include "i915_scatterlist.h"
15 : : #include "i915_trace.h"
16 : :
17 : : /*
18 : : * Move pages to appropriate lru and release the pagevec, decrementing the
19 : : * ref count of those pages.
20 : : */
21 : 0 : static void check_release_pagevec(struct pagevec *pvec)
22 : : {
23 : 0 : check_move_unevictable_pages(pvec);
24 : 0 : __pagevec_release(pvec);
25 : 0 : cond_resched();
26 : 0 : }
27 : :
28 : 0 : static int shmem_get_pages(struct drm_i915_gem_object *obj)
29 : : {
30 : 0 : struct drm_i915_private *i915 = to_i915(obj->base.dev);
31 : 0 : struct intel_memory_region *mem = obj->mm.region;
32 : 0 : const unsigned long page_count = obj->base.size / PAGE_SIZE;
33 : 0 : unsigned long i;
34 : 0 : struct address_space *mapping;
35 : 0 : struct sg_table *st;
36 : 0 : struct scatterlist *sg;
37 : 0 : struct sgt_iter sgt_iter;
38 : 0 : struct page *page;
39 : 0 : unsigned long last_pfn = 0; /* suppress gcc warning */
40 : 0 : unsigned int max_segment = i915_sg_segment_size();
41 : 0 : unsigned int sg_page_sizes;
42 : 0 : struct pagevec pvec;
43 : 0 : gfp_t noreclaim;
44 : 0 : int ret;
45 : :
46 : : /*
47 : : * Assert that the object is not currently in any GPU domain. As it
48 : : * wasn't in the GTT, there shouldn't be any way it could have been in
49 : : * a GPU cache
50 : : */
51 : 0 : GEM_BUG_ON(obj->read_domains & I915_GEM_GPU_DOMAINS);
52 : 0 : GEM_BUG_ON(obj->write_domain & I915_GEM_GPU_DOMAINS);
53 : :
54 : : /*
55 : : * If there's no chance of allocating enough pages for the whole
56 : : * object, bail early.
57 : : */
58 [ # # ]: 0 : if (obj->base.size > resource_size(&mem->region))
59 : : return -ENOMEM;
60 : :
61 : 0 : st = kmalloc(sizeof(*st), GFP_KERNEL);
62 [ # # ]: 0 : if (!st)
63 : : return -ENOMEM;
64 : :
65 : 0 : rebuild_st:
66 [ # # ]: 0 : if (sg_alloc_table(st, page_count, GFP_KERNEL)) {
67 : 0 : kfree(st);
68 : 0 : return -ENOMEM;
69 : : }
70 : :
71 : : /*
72 : : * Get the list of pages out of our struct file. They'll be pinned
73 : : * at this point until we release them.
74 : : *
75 : : * Fail silently without starting the shrinker
76 : : */
77 : 0 : mapping = obj->base.filp->f_mapping;
78 : 0 : mapping_set_unevictable(mapping);
79 : 0 : noreclaim = mapping_gfp_constraint(mapping, ~__GFP_RECLAIM);
80 : 0 : noreclaim |= __GFP_NORETRY | __GFP_NOWARN;
81 : :
82 : 0 : sg = st->sgl;
83 : 0 : st->nents = 0;
84 : 0 : sg_page_sizes = 0;
85 [ # # ]: 0 : for (i = 0; i < page_count; i++) {
86 : 0 : const unsigned int shrink[] = {
87 : : I915_SHRINK_BOUND | I915_SHRINK_UNBOUND,
88 : : 0,
89 : : }, *s = shrink;
90 : 0 : gfp_t gfp = noreclaim;
91 : :
92 : 0 : do {
93 : 0 : cond_resched();
94 : 0 : page = shmem_read_mapping_page_gfp(mapping, i, gfp);
95 [ # # ]: 0 : if (!IS_ERR(page))
96 : : break;
97 : :
98 [ # # ]: 0 : if (!*s) {
99 : 0 : ret = PTR_ERR(page);
100 : 0 : goto err_sg;
101 : : }
102 : :
103 : 0 : i915_gem_shrink(i915, 2 * page_count, NULL, *s++);
104 : :
105 : : /*
106 : : * We've tried hard to allocate the memory by reaping
107 : : * our own buffer, now let the real VM do its job and
108 : : * go down in flames if truly OOM.
109 : : *
110 : : * However, since graphics tend to be disposable,
111 : : * defer the oom here by reporting the ENOMEM back
112 : : * to userspace.
113 : : */
114 [ # # ]: 0 : if (!*s) {
115 : : /* reclaim and warn, but no oom */
116 : 0 : gfp = mapping_gfp_mask(mapping);
117 : :
118 : : /*
119 : : * Our bo are always dirty and so we require
120 : : * kswapd to reclaim our pages (direct reclaim
121 : : * does not effectively begin pageout of our
122 : : * buffers on its own). However, direct reclaim
123 : : * only waits for kswapd when under allocation
124 : : * congestion. So as a result __GFP_RECLAIM is
125 : : * unreliable and fails to actually reclaim our
126 : : * dirty pages -- unless you try over and over
127 : : * again with !__GFP_NORETRY. However, we still
128 : : * want to fail this allocation rather than
129 : : * trigger the out-of-memory killer and for
130 : : * this we want __GFP_RETRY_MAYFAIL.
131 : : */
132 : 0 : gfp |= __GFP_RETRY_MAYFAIL;
133 : : }
134 : : } while (1);
135 : :
136 [ # # ]: 0 : if (!i ||
137 [ # # ]: 0 : sg->length >= max_segment ||
138 [ # # ]: 0 : page_to_pfn(page) != last_pfn + 1) {
139 [ # # ]: 0 : if (i) {
140 : 0 : sg_page_sizes |= sg->length;
141 : 0 : sg = sg_next(sg);
142 : : }
143 : 0 : st->nents++;
144 [ # # ]: 0 : sg_set_page(sg, page, PAGE_SIZE, 0);
145 : : } else {
146 : 0 : sg->length += PAGE_SIZE;
147 : : }
148 : 0 : last_pfn = page_to_pfn(page);
149 : :
150 : : /* Check that the i965g/gm workaround works. */
151 [ # # # # : 0 : WARN_ON((gfp & __GFP_DMA32) && (last_pfn >= 0x00100000UL));
# # ]
152 : : }
153 [ # # ]: 0 : if (sg) { /* loop terminated early; short sg table */
154 : 0 : sg_page_sizes |= sg->length;
155 : 0 : sg_mark_end(sg);
156 : : }
157 : :
158 : : /* Trim unused sg entries to avoid wasting memory. */
159 : 0 : i915_sg_trim(st);
160 : :
161 : 0 : ret = i915_gem_gtt_prepare_pages(obj, st);
162 [ # # ]: 0 : if (ret) {
163 : : /*
164 : : * DMA remapping failed? One possible cause is that
165 : : * it could not reserve enough large entries, asking
166 : : * for PAGE_SIZE chunks instead may be helpful.
167 : : */
168 [ # # ]: 0 : if (max_segment > PAGE_SIZE) {
169 [ # # # # : 0 : for_each_sgt_page(page, sgt_iter, st)
# # # # ]
170 : 0 : put_page(page);
171 : 0 : sg_free_table(st);
172 : :
173 : 0 : max_segment = PAGE_SIZE;
174 : 0 : goto rebuild_st;
175 : : } else {
176 : 0 : dev_warn(&i915->drm.pdev->dev,
177 : : "Failed to DMA remap %lu pages\n",
178 : : page_count);
179 : 0 : goto err_pages;
180 : : }
181 : : }
182 : :
183 [ # # # # ]: 0 : if (i915_gem_object_needs_bit17_swizzle(obj))
184 : 0 : i915_gem_object_do_bit_17_swizzle(obj, st);
185 : :
186 : 0 : __i915_gem_object_set_pages(obj, st, sg_page_sizes);
187 : :
188 : 0 : return 0;
189 : :
190 : : err_sg:
191 : 0 : sg_mark_end(sg);
192 : 0 : err_pages:
193 : 0 : mapping_clear_unevictable(mapping);
194 [ # # ]: 0 : pagevec_init(&pvec);
195 [ # # # # : 0 : for_each_sgt_page(page, sgt_iter, st) {
# # # # ]
196 [ # # ]: 0 : if (!pagevec_add(&pvec, page))
197 : 0 : check_release_pagevec(&pvec);
198 : : }
199 [ # # ]: 0 : if (pagevec_count(&pvec))
200 : 0 : check_release_pagevec(&pvec);
201 : 0 : sg_free_table(st);
202 : 0 : kfree(st);
203 : :
204 : : /*
205 : : * shmemfs first checks if there is enough memory to allocate the page
206 : : * and reports ENOSPC should there be insufficient, along with the usual
207 : : * ENOMEM for a genuine allocation failure.
208 : : *
209 : : * We use ENOSPC in our driver to mean that we have run out of aperture
210 : : * space and so want to translate the error from shmemfs back to our
211 : : * usual understanding of ENOMEM.
212 : : */
213 [ # # ]: 0 : if (ret == -ENOSPC)
214 : 0 : ret = -ENOMEM;
215 : :
216 : : return ret;
217 : : }
218 : :
219 : : static void
220 : 0 : shmem_truncate(struct drm_i915_gem_object *obj)
221 : : {
222 : : /*
223 : : * Our goal here is to return as much of the memory as
224 : : * is possible back to the system as we are called from OOM.
225 : : * To do this we must instruct the shmfs to drop all of its
226 : : * backing pages, *now*.
227 : : */
228 : 0 : shmem_truncate_range(file_inode(obj->base.filp), 0, (loff_t)-1);
229 : 0 : obj->mm.madv = __I915_MADV_PURGED;
230 : 0 : obj->mm.pages = ERR_PTR(-EFAULT);
231 : 0 : }
232 : :
233 : : static void
234 : 0 : shmem_writeback(struct drm_i915_gem_object *obj)
235 : : {
236 : 0 : struct address_space *mapping;
237 : 0 : struct writeback_control wbc = {
238 : : .sync_mode = WB_SYNC_NONE,
239 : : .nr_to_write = SWAP_CLUSTER_MAX,
240 : : .range_start = 0,
241 : : .range_end = LLONG_MAX,
242 : : .for_reclaim = 1,
243 : : };
244 : 0 : unsigned long i;
245 : :
246 : : /*
247 : : * Leave mmapings intact (GTT will have been revoked on unbinding,
248 : : * leaving only CPU mmapings around) and add those pages to the LRU
249 : : * instead of invoking writeback so they are aged and paged out
250 : : * as normal.
251 : : */
252 : 0 : mapping = obj->base.filp->f_mapping;
253 : :
254 : : /* Begin writeback on each dirty page */
255 [ # # ]: 0 : for (i = 0; i < obj->base.size >> PAGE_SHIFT; i++) {
256 : 0 : struct page *page;
257 : :
258 : 0 : page = find_lock_entry(mapping, i);
259 [ # # # # ]: 0 : if (!page || xa_is_value(page))
260 : 0 : continue;
261 : :
262 [ # # # # ]: 0 : if (!page_mapped(page) && clear_page_dirty_for_io(page)) {
263 : 0 : int ret;
264 : :
265 [ # # ]: 0 : SetPageReclaim(page);
266 : 0 : ret = mapping->a_ops->writepage(page, &wbc);
267 [ # # # # ]: 0 : if (!PageWriteback(page))
268 [ # # ]: 0 : ClearPageReclaim(page);
269 [ # # ]: 0 : if (!ret)
270 : 0 : goto put;
271 : : }
272 : 0 : unlock_page(page);
273 : 0 : put:
274 : 0 : put_page(page);
275 : : }
276 : 0 : }
277 : :
278 : : void
279 : 0 : __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj,
280 : : struct sg_table *pages,
281 : : bool needs_clflush)
282 : : {
283 : 0 : GEM_BUG_ON(obj->mm.madv == __I915_MADV_PURGED);
284 : :
285 [ # # ]: 0 : if (obj->mm.madv == I915_MADV_DONTNEED)
286 : 0 : obj->mm.dirty = false;
287 : :
288 [ # # ]: 0 : if (needs_clflush &&
289 [ # # ]: 0 : (obj->read_domains & I915_GEM_DOMAIN_CPU) == 0 &&
290 [ # # ]: 0 : !(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ))
291 : 0 : drm_clflush_sg(pages);
292 : :
293 [ # # ]: 0 : __start_cpu_write(obj);
294 : 0 : }
295 : :
296 : : static void
297 : 0 : shmem_put_pages(struct drm_i915_gem_object *obj, struct sg_table *pages)
298 : : {
299 : 0 : struct sgt_iter sgt_iter;
300 : 0 : struct pagevec pvec;
301 : 0 : struct page *page;
302 : :
303 : 0 : __i915_gem_object_release_shmem(obj, pages, true);
304 : :
305 : 0 : i915_gem_gtt_finish_pages(obj, pages);
306 : :
307 [ # # # # ]: 0 : if (i915_gem_object_needs_bit17_swizzle(obj))
308 : 0 : i915_gem_object_save_bit_17_swizzle(obj, pages);
309 : :
310 : 0 : mapping_clear_unevictable(file_inode(obj->base.filp)->i_mapping);
311 : :
312 [ # # ]: 0 : pagevec_init(&pvec);
313 [ # # # # : 0 : for_each_sgt_page(page, sgt_iter, pages) {
# # # # ]
314 [ # # ]: 0 : if (obj->mm.dirty)
315 : 0 : set_page_dirty(page);
316 : :
317 [ # # ]: 0 : if (obj->mm.madv == I915_MADV_WILLNEED)
318 : 0 : mark_page_accessed(page);
319 : :
320 [ # # ]: 0 : if (!pagevec_add(&pvec, page))
321 : 0 : check_release_pagevec(&pvec);
322 : : }
323 [ # # ]: 0 : if (pagevec_count(&pvec))
324 : 0 : check_release_pagevec(&pvec);
325 : 0 : obj->mm.dirty = false;
326 : :
327 : 0 : sg_free_table(pages);
328 : 0 : kfree(pages);
329 : 0 : }
330 : :
331 : : static int
332 : 0 : shmem_pwrite(struct drm_i915_gem_object *obj,
333 : : const struct drm_i915_gem_pwrite *arg)
334 : : {
335 : 0 : struct address_space *mapping = obj->base.filp->f_mapping;
336 : 0 : char __user *user_data = u64_to_user_ptr(arg->data_ptr);
337 : 0 : u64 remain, offset;
338 : 0 : unsigned int pg;
339 : :
340 : : /* Caller already validated user args */
341 : 0 : GEM_BUG_ON(!access_ok(user_data, arg->size));
342 : :
343 : : /*
344 : : * Before we instantiate/pin the backing store for our use, we
345 : : * can prepopulate the shmemfs filp efficiently using a write into
346 : : * the pagecache. We avoid the penalty of instantiating all the
347 : : * pages, important if the user is just writing to a few and never
348 : : * uses the object on the GPU, and using a direct write into shmemfs
349 : : * allows it to avoid the cost of retrieving a page (either swapin
350 : : * or clearing-before-use) before it is overwritten.
351 : : */
352 [ # # # # ]: 0 : if (i915_gem_object_has_pages(obj))
353 : : return -ENODEV;
354 : :
355 [ # # ]: 0 : if (obj->mm.madv != I915_MADV_WILLNEED)
356 : : return -EFAULT;
357 : :
358 : : /*
359 : : * Before the pages are instantiated the object is treated as being
360 : : * in the CPU domain. The pages will be clflushed as required before
361 : : * use, and we can freely write into the pages directly. If userspace
362 : : * races pwrite with any other operation; corruption will ensue -
363 : : * that is userspace's prerogative!
364 : : */
365 : :
366 : 0 : remain = arg->size;
367 : 0 : offset = arg->offset;
368 : 0 : pg = offset_in_page(offset);
369 : :
370 : 0 : do {
371 : 0 : unsigned int len, unwritten;
372 : 0 : struct page *page;
373 : 0 : void *data, *vaddr;
374 : 0 : int err;
375 : 0 : char c;
376 : :
377 : 0 : len = PAGE_SIZE - pg;
378 [ # # ]: 0 : if (len > remain)
379 : 0 : len = remain;
380 : :
381 : : /* Prefault the user page to reduce potential recursion */
382 : 0 : err = __get_user(c, user_data);
383 [ # # ]: 0 : if (err)
384 : 0 : return err;
385 : :
386 : 0 : err = __get_user(c, user_data + len - 1);
387 [ # # ]: 0 : if (err)
388 : 0 : return err;
389 : :
390 : 0 : err = pagecache_write_begin(obj->base.filp, mapping,
391 : : offset, len, 0,
392 : : &page, &data);
393 [ # # ]: 0 : if (err < 0)
394 : 0 : return err;
395 : :
396 : 0 : vaddr = kmap_atomic(page);
397 : 0 : unwritten = __copy_from_user_inatomic(vaddr + pg,
398 : : user_data,
399 : : len);
400 : 0 : kunmap_atomic(vaddr);
401 : :
402 : 0 : err = pagecache_write_end(obj->base.filp, mapping,
403 : : offset, len, len - unwritten,
404 : : page, data);
405 [ # # ]: 0 : if (err < 0)
406 : 0 : return err;
407 : :
408 : : /* We don't handle -EFAULT, leave it to the caller to check */
409 [ # # ]: 0 : if (unwritten)
410 : : return -ENODEV;
411 : :
412 : 0 : remain -= len;
413 : 0 : user_data += len;
414 : 0 : offset += len;
415 : 0 : pg = 0;
416 [ # # ]: 0 : } while (remain);
417 : :
418 : : return 0;
419 : : }
420 : :
421 : 0 : static void shmem_release(struct drm_i915_gem_object *obj)
422 : : {
423 : 0 : i915_gem_object_release_memory_region(obj);
424 : :
425 : 0 : fput(obj->base.filp);
426 : 0 : }
427 : :
428 : : const struct drm_i915_gem_object_ops i915_gem_shmem_ops = {
429 : : .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE |
430 : : I915_GEM_OBJECT_IS_SHRINKABLE,
431 : :
432 : : .get_pages = shmem_get_pages,
433 : : .put_pages = shmem_put_pages,
434 : : .truncate = shmem_truncate,
435 : : .writeback = shmem_writeback,
436 : :
437 : : .pwrite = shmem_pwrite,
438 : :
439 : : .release = shmem_release,
440 : : };
441 : :
442 : 0 : static int __create_shmem(struct drm_i915_private *i915,
443 : : struct drm_gem_object *obj,
444 : : resource_size_t size)
445 : : {
446 : 0 : unsigned long flags = VM_NORESERVE;
447 : 0 : struct file *filp;
448 : :
449 : 0 : drm_gem_private_object_init(&i915->drm, obj, size);
450 : :
451 [ # # ]: 0 : if (i915->mm.gemfs)
452 : 0 : filp = shmem_file_setup_with_mnt(i915->mm.gemfs, "i915", size,
453 : : flags);
454 : : else
455 : 0 : filp = shmem_file_setup("i915", size, flags);
456 [ # # ]: 0 : if (IS_ERR(filp))
457 : 0 : return PTR_ERR(filp);
458 : :
459 : 0 : obj->filp = filp;
460 : 0 : return 0;
461 : : }
462 : :
463 : : static struct drm_i915_gem_object *
464 : 0 : create_shmem(struct intel_memory_region *mem,
465 : : resource_size_t size,
466 : : unsigned int flags)
467 : : {
468 : 0 : static struct lock_class_key lock_class;
469 : 0 : struct drm_i915_private *i915 = mem->i915;
470 : 0 : struct drm_i915_gem_object *obj;
471 : 0 : struct address_space *mapping;
472 : 0 : unsigned int cache_level;
473 : 0 : gfp_t mask;
474 : 0 : int ret;
475 : :
476 : 0 : obj = i915_gem_object_alloc();
477 [ # # ]: 0 : if (!obj)
478 : : return ERR_PTR(-ENOMEM);
479 : :
480 : 0 : ret = __create_shmem(i915, &obj->base, size);
481 [ # # ]: 0 : if (ret)
482 : 0 : goto fail;
483 : :
484 : 0 : mask = GFP_HIGHUSER | __GFP_RECLAIMABLE;
485 [ # # # # ]: 0 : if (IS_I965GM(i915) || IS_I965G(i915)) {
486 : : /* 965gm cannot relocate objects above 4GiB. */
487 : : mask &= ~__GFP_HIGHMEM;
488 : : mask |= __GFP_DMA32;
489 : : }
490 : :
491 : 0 : mapping = obj->base.filp->f_mapping;
492 : 0 : mapping_set_gfp_mask(mapping, mask);
493 : 0 : GEM_BUG_ON(!(mapping_gfp_mask(mapping) & __GFP_RECLAIM));
494 : :
495 : 0 : i915_gem_object_init(obj, &i915_gem_shmem_ops, &lock_class);
496 : :
497 : 0 : obj->write_domain = I915_GEM_DOMAIN_CPU;
498 : 0 : obj->read_domains = I915_GEM_DOMAIN_CPU;
499 : :
500 [ # # ]: 0 : if (HAS_LLC(i915))
501 : : /* On some devices, we can have the GPU use the LLC (the CPU
502 : : * cache) for about a 10% performance improvement
503 : : * compared to uncached. Graphics requests other than
504 : : * display scanout are coherent with the CPU in
505 : : * accessing this cache. This means in this mode we
506 : : * don't need to clflush on the CPU side, and on the
507 : : * GPU side we only need to flush internal caches to
508 : : * get data visible to the CPU.
509 : : *
510 : : * However, we maintain the display planes as UC, and so
511 : : * need to rebind when first used as such.
512 : : */
513 : : cache_level = I915_CACHE_LLC;
514 : : else
515 : 0 : cache_level = I915_CACHE_NONE;
516 : :
517 : 0 : i915_gem_object_set_cache_coherency(obj, cache_level);
518 : :
519 : 0 : i915_gem_object_init_memory_region(obj, mem, 0);
520 : :
521 : 0 : return obj;
522 : :
523 : : fail:
524 : 0 : i915_gem_object_free(obj);
525 : 0 : return ERR_PTR(ret);
526 : : }
527 : :
528 : : struct drm_i915_gem_object *
529 : 0 : i915_gem_object_create_shmem(struct drm_i915_private *i915,
530 : : resource_size_t size)
531 : : {
532 : 0 : return i915_gem_object_create_region(i915->mm.regions[INTEL_REGION_SMEM],
533 : : size, 0);
534 : : }
535 : :
536 : : /* Allocate a new GEM object and fill it with the supplied data */
537 : : struct drm_i915_gem_object *
538 : 0 : i915_gem_object_create_shmem_from_data(struct drm_i915_private *dev_priv,
539 : : const void *data, resource_size_t size)
540 : : {
541 : 0 : struct drm_i915_gem_object *obj;
542 : 0 : struct file *file;
543 : 0 : resource_size_t offset;
544 : 0 : int err;
545 : :
546 : 0 : obj = i915_gem_object_create_shmem(dev_priv, round_up(size, PAGE_SIZE));
547 [ # # ]: 0 : if (IS_ERR(obj))
548 : : return obj;
549 : :
550 : 0 : GEM_BUG_ON(obj->write_domain != I915_GEM_DOMAIN_CPU);
551 : :
552 : 0 : file = obj->base.filp;
553 : 0 : offset = 0;
554 : 0 : do {
555 : 0 : unsigned int len = min_t(typeof(size), size, PAGE_SIZE);
556 : 0 : struct page *page;
557 : 0 : void *pgdata, *vaddr;
558 : :
559 : 0 : err = pagecache_write_begin(file, file->f_mapping,
560 : : offset, len, 0,
561 : : &page, &pgdata);
562 [ # # ]: 0 : if (err < 0)
563 : 0 : goto fail;
564 : :
565 : 0 : vaddr = kmap(page);
566 : 0 : memcpy(vaddr, data, len);
567 : 0 : kunmap(page);
568 : :
569 : 0 : err = pagecache_write_end(file, file->f_mapping,
570 : : offset, len, len,
571 : : page, pgdata);
572 [ # # ]: 0 : if (err < 0)
573 : 0 : goto fail;
574 : :
575 : 0 : size -= len;
576 : 0 : data += len;
577 : 0 : offset += len;
578 [ # # ]: 0 : } while (size);
579 : :
580 : : return obj;
581 : :
582 : : fail:
583 : 0 : i915_gem_object_put(obj);
584 : 0 : return ERR_PTR(err);
585 : : }
586 : :
587 : 0 : static int init_shmem(struct intel_memory_region *mem)
588 : : {
589 : 0 : int err;
590 : :
591 : 0 : err = i915_gemfs_init(mem->i915);
592 [ # # ]: 0 : if (err) {
593 : 0 : DRM_NOTE("Unable to create a private tmpfs mount, hugepage support will be disabled(%d).\n",
594 : : err);
595 : : }
596 : :
597 : 0 : intel_memory_region_set_name(mem, "system");
598 : :
599 : 0 : return 0; /* Don't error, we can simply fallback to the kernel mnt */
600 : : }
601 : :
602 : 0 : static void release_shmem(struct intel_memory_region *mem)
603 : : {
604 : 0 : i915_gemfs_fini(mem->i915);
605 : 0 : }
606 : :
607 : : static const struct intel_memory_region_ops shmem_region_ops = {
608 : : .init = init_shmem,
609 : : .release = release_shmem,
610 : : .create_object = create_shmem,
611 : : };
612 : :
613 : 0 : struct intel_memory_region *i915_gem_shmem_setup(struct drm_i915_private *i915)
614 : : {
615 : 0 : return intel_memory_region_create(i915, 0,
616 : 0 : totalram_pages() << PAGE_SHIFT,
617 : : PAGE_SIZE, 0,
618 : : &shmem_region_ops);
619 : : }
|