ttm_tt.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /* SPDX-License-Identifier: GPL-2.0 OR MIT */
  2. /**************************************************************************
  3. *
  4. * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
  5. * All Rights Reserved.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the
  9. * "Software"), to deal in the Software without restriction, including
  10. * without limitation the rights to use, copy, modify, merge, publish,
  11. * distribute, sub license, and/or sell copies of the Software, and to
  12. * permit persons to whom the Software is furnished to do so, subject to
  13. * the following conditions:
  14. *
  15. * The above copyright notice and this permission notice (including the
  16. * next paragraph) shall be included in all copies or substantial portions
  17. * of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  22. * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  23. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  24. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  25. * USE OR OTHER DEALINGS IN THE SOFTWARE.
  26. *
  27. **************************************************************************/
  28. /*
  29. * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
  30. */
  31. #define pr_fmt(fmt) "[TTM] " fmt
  32. #include <linux/cc_platform.h>
  33. #include <linux/debugfs.h>
  34. #include <linux/file.h>
  35. #include <linux/module.h>
  36. #include <linux/sched.h>
  37. #include <linux/shmem_fs.h>
  38. #include <drm/drm_cache.h>
  39. #include <drm/drm_device.h>
  40. #include <drm/drm_util.h>
  41. #include <drm/ttm/ttm_bo.h>
  42. #include <drm/ttm/ttm_tt.h>
  43. #include "ttm_module.h"
  44. static unsigned long ttm_pages_limit;
  45. MODULE_PARM_DESC(pages_limit, "Limit for the allocated pages");
  46. module_param_named(pages_limit, ttm_pages_limit, ulong, 0644);
  47. static unsigned long ttm_dma32_pages_limit;
  48. MODULE_PARM_DESC(dma32_pages_limit, "Limit for the allocated DMA32 pages");
  49. module_param_named(dma32_pages_limit, ttm_dma32_pages_limit, ulong, 0644);
  50. static atomic_long_t ttm_pages_allocated;
  51. static atomic_long_t ttm_dma32_pages_allocated;
  52. /*
  53. * Allocates a ttm structure for the given BO.
  54. */
  55. int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc)
  56. {
  57. struct ttm_device *bdev = bo->bdev;
  58. struct drm_device *ddev = bo->base.dev;
  59. uint32_t page_flags = 0;
  60. dma_resv_assert_held(bo->base.resv);
  61. if (bo->ttm)
  62. return 0;
  63. switch (bo->type) {
  64. case ttm_bo_type_device:
  65. if (zero_alloc)
  66. page_flags |= TTM_TT_FLAG_ZERO_ALLOC;
  67. break;
  68. case ttm_bo_type_kernel:
  69. break;
  70. case ttm_bo_type_sg:
  71. page_flags |= TTM_TT_FLAG_EXTERNAL;
  72. break;
  73. default:
  74. pr_err("Illegal buffer object type\n");
  75. return -EINVAL;
  76. }
  77. /*
  78. * When using dma_alloc_coherent with memory encryption the
  79. * mapped TT pages need to be decrypted or otherwise the drivers
  80. * will end up sending encrypted mem to the gpu.
  81. */
  82. if (bdev->pool.use_dma_alloc && cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) {
  83. page_flags |= TTM_TT_FLAG_DECRYPTED;
  84. drm_info_once(ddev, "TT memory decryption enabled.");
  85. }
  86. bo->ttm = bdev->funcs->ttm_tt_create(bo, page_flags);
  87. if (unlikely(bo->ttm == NULL))
  88. return -ENOMEM;
  89. WARN_ON(bo->ttm->page_flags & TTM_TT_FLAG_EXTERNAL_MAPPABLE &&
  90. !(bo->ttm->page_flags & TTM_TT_FLAG_EXTERNAL));
  91. return 0;
  92. }
  93. EXPORT_SYMBOL_FOR_TESTS_ONLY(ttm_tt_create);
  94. /*
  95. * Allocates storage for pointers to the pages that back the ttm.
  96. */
  97. static int ttm_tt_alloc_page_directory(struct ttm_tt *ttm)
  98. {
  99. ttm->pages = kvcalloc(ttm->num_pages, sizeof(void*), GFP_KERNEL);
  100. if (!ttm->pages)
  101. return -ENOMEM;
  102. return 0;
  103. }
  104. static int ttm_dma_tt_alloc_page_directory(struct ttm_tt *ttm)
  105. {
  106. ttm->pages = kvcalloc(ttm->num_pages, sizeof(*ttm->pages) +
  107. sizeof(*ttm->dma_address), GFP_KERNEL);
  108. if (!ttm->pages)
  109. return -ENOMEM;
  110. ttm->dma_address = (void *)(ttm->pages + ttm->num_pages);
  111. return 0;
  112. }
  113. static int ttm_sg_tt_alloc_page_directory(struct ttm_tt *ttm)
  114. {
  115. ttm->dma_address = kvcalloc(ttm->num_pages, sizeof(*ttm->dma_address),
  116. GFP_KERNEL);
  117. if (!ttm->dma_address)
  118. return -ENOMEM;
  119. return 0;
  120. }
  121. void ttm_tt_destroy(struct ttm_device *bdev, struct ttm_tt *ttm)
  122. {
  123. bdev->funcs->ttm_tt_destroy(bdev, ttm);
  124. }
  125. EXPORT_SYMBOL_FOR_TESTS_ONLY(ttm_tt_destroy);
  126. static void ttm_tt_init_fields(struct ttm_tt *ttm,
  127. struct ttm_buffer_object *bo,
  128. uint32_t page_flags,
  129. enum ttm_caching caching,
  130. unsigned long extra_pages)
  131. {
  132. ttm->num_pages = (PAGE_ALIGN(bo->base.size) >> PAGE_SHIFT) + extra_pages;
  133. ttm->page_flags = page_flags;
  134. ttm->dma_address = NULL;
  135. ttm->swap_storage = NULL;
  136. ttm->sg = bo->sg;
  137. ttm->caching = caching;
  138. }
  139. int ttm_tt_init(struct ttm_tt *ttm, struct ttm_buffer_object *bo,
  140. uint32_t page_flags, enum ttm_caching caching,
  141. unsigned long extra_pages)
  142. {
  143. ttm_tt_init_fields(ttm, bo, page_flags, caching, extra_pages);
  144. if (ttm_tt_alloc_page_directory(ttm)) {
  145. pr_err("Failed allocating page table\n");
  146. return -ENOMEM;
  147. }
  148. return 0;
  149. }
  150. EXPORT_SYMBOL(ttm_tt_init);
  151. void ttm_tt_fini(struct ttm_tt *ttm)
  152. {
  153. WARN_ON(ttm->page_flags & TTM_TT_FLAG_PRIV_POPULATED);
  154. if (ttm->swap_storage)
  155. fput(ttm->swap_storage);
  156. ttm->swap_storage = NULL;
  157. if (ttm->pages)
  158. kvfree(ttm->pages);
  159. else
  160. kvfree(ttm->dma_address);
  161. ttm->pages = NULL;
  162. ttm->dma_address = NULL;
  163. }
  164. EXPORT_SYMBOL(ttm_tt_fini);
  165. int ttm_sg_tt_init(struct ttm_tt *ttm, struct ttm_buffer_object *bo,
  166. uint32_t page_flags, enum ttm_caching caching)
  167. {
  168. int ret;
  169. ttm_tt_init_fields(ttm, bo, page_flags, caching, 0);
  170. if (page_flags & TTM_TT_FLAG_EXTERNAL)
  171. ret = ttm_sg_tt_alloc_page_directory(ttm);
  172. else
  173. ret = ttm_dma_tt_alloc_page_directory(ttm);
  174. if (ret) {
  175. pr_err("Failed allocating page table\n");
  176. return -ENOMEM;
  177. }
  178. return 0;
  179. }
  180. EXPORT_SYMBOL(ttm_sg_tt_init);
  181. int ttm_tt_swapin(struct ttm_tt *ttm)
  182. {
  183. struct address_space *swap_space;
  184. struct file *swap_storage;
  185. struct page *from_page;
  186. struct page *to_page;
  187. gfp_t gfp_mask;
  188. int i, ret;
  189. swap_storage = ttm->swap_storage;
  190. BUG_ON(swap_storage == NULL);
  191. swap_space = swap_storage->f_mapping;
  192. gfp_mask = mapping_gfp_mask(swap_space);
  193. for (i = 0; i < ttm->num_pages; ++i) {
  194. from_page = shmem_read_mapping_page_gfp(swap_space, i,
  195. gfp_mask);
  196. if (IS_ERR(from_page)) {
  197. ret = PTR_ERR(from_page);
  198. goto out_err;
  199. }
  200. to_page = ttm->pages[i];
  201. if (unlikely(to_page == NULL)) {
  202. ret = -ENOMEM;
  203. goto out_err;
  204. }
  205. copy_highpage(to_page, from_page);
  206. put_page(from_page);
  207. }
  208. fput(swap_storage);
  209. ttm->swap_storage = NULL;
  210. ttm->page_flags &= ~TTM_TT_FLAG_SWAPPED;
  211. return 0;
  212. out_err:
  213. return ret;
  214. }
  215. EXPORT_SYMBOL_FOR_TESTS_ONLY(ttm_tt_swapin);
  216. /**
  217. * ttm_tt_swapout - swap out tt object
  218. *
  219. * @bdev: TTM device structure.
  220. * @ttm: The struct ttm_tt.
  221. * @gfp_flags: Flags to use for memory allocation.
  222. *
  223. * Swapout a TT object to a shmem_file, return number of pages swapped out or
  224. * negative error code.
  225. */
  226. int ttm_tt_swapout(struct ttm_device *bdev, struct ttm_tt *ttm,
  227. gfp_t gfp_flags)
  228. {
  229. loff_t size = (loff_t)ttm->num_pages << PAGE_SHIFT;
  230. struct address_space *swap_space;
  231. struct file *swap_storage;
  232. struct page *from_page;
  233. struct page *to_page;
  234. int i, ret;
  235. swap_storage = shmem_file_setup("ttm swap", size, 0);
  236. if (IS_ERR(swap_storage)) {
  237. pr_err("Failed allocating swap storage\n");
  238. return PTR_ERR(swap_storage);
  239. }
  240. swap_space = swap_storage->f_mapping;
  241. gfp_flags &= mapping_gfp_mask(swap_space);
  242. for (i = 0; i < ttm->num_pages; ++i) {
  243. from_page = ttm->pages[i];
  244. if (unlikely(from_page == NULL))
  245. continue;
  246. to_page = shmem_read_mapping_page_gfp(swap_space, i, gfp_flags);
  247. if (IS_ERR(to_page)) {
  248. ret = PTR_ERR(to_page);
  249. goto out_err;
  250. }
  251. copy_highpage(to_page, from_page);
  252. set_page_dirty(to_page);
  253. mark_page_accessed(to_page);
  254. put_page(to_page);
  255. }
  256. ttm_tt_unpopulate(bdev, ttm);
  257. ttm->swap_storage = swap_storage;
  258. ttm->page_flags |= TTM_TT_FLAG_SWAPPED;
  259. return ttm->num_pages;
  260. out_err:
  261. fput(swap_storage);
  262. return ret;
  263. }
  264. EXPORT_SYMBOL_FOR_TESTS_ONLY(ttm_tt_swapout);
  265. int ttm_tt_populate(struct ttm_device *bdev,
  266. struct ttm_tt *ttm, struct ttm_operation_ctx *ctx)
  267. {
  268. int ret;
  269. if (!ttm)
  270. return -EINVAL;
  271. if (ttm_tt_is_populated(ttm))
  272. return 0;
  273. if (!(ttm->page_flags & TTM_TT_FLAG_EXTERNAL)) {
  274. atomic_long_add(ttm->num_pages, &ttm_pages_allocated);
  275. if (bdev->pool.use_dma32)
  276. atomic_long_add(ttm->num_pages,
  277. &ttm_dma32_pages_allocated);
  278. }
  279. while (atomic_long_read(&ttm_pages_allocated) > ttm_pages_limit ||
  280. atomic_long_read(&ttm_dma32_pages_allocated) >
  281. ttm_dma32_pages_limit) {
  282. ret = ttm_global_swapout(ctx, GFP_KERNEL);
  283. if (ret == 0)
  284. break;
  285. if (ret < 0)
  286. goto error;
  287. }
  288. if (bdev->funcs->ttm_tt_populate)
  289. ret = bdev->funcs->ttm_tt_populate(bdev, ttm, ctx);
  290. else
  291. ret = ttm_pool_alloc(&bdev->pool, ttm, ctx);
  292. if (ret)
  293. goto error;
  294. ttm->page_flags |= TTM_TT_FLAG_PRIV_POPULATED;
  295. if (unlikely(ttm->page_flags & TTM_TT_FLAG_SWAPPED)) {
  296. ret = ttm_tt_swapin(ttm);
  297. if (unlikely(ret != 0)) {
  298. ttm_tt_unpopulate(bdev, ttm);
  299. return ret;
  300. }
  301. }
  302. return 0;
  303. error:
  304. if (!(ttm->page_flags & TTM_TT_FLAG_EXTERNAL)) {
  305. atomic_long_sub(ttm->num_pages, &ttm_pages_allocated);
  306. if (bdev->pool.use_dma32)
  307. atomic_long_sub(ttm->num_pages,
  308. &ttm_dma32_pages_allocated);
  309. }
  310. return ret;
  311. }
  312. EXPORT_SYMBOL(ttm_tt_populate);
  313. void ttm_tt_unpopulate(struct ttm_device *bdev, struct ttm_tt *ttm)
  314. {
  315. if (!ttm_tt_is_populated(ttm))
  316. return;
  317. if (bdev->funcs->ttm_tt_unpopulate)
  318. bdev->funcs->ttm_tt_unpopulate(bdev, ttm);
  319. else
  320. ttm_pool_free(&bdev->pool, ttm);
  321. if (!(ttm->page_flags & TTM_TT_FLAG_EXTERNAL)) {
  322. atomic_long_sub(ttm->num_pages, &ttm_pages_allocated);
  323. if (bdev->pool.use_dma32)
  324. atomic_long_sub(ttm->num_pages,
  325. &ttm_dma32_pages_allocated);
  326. }
  327. ttm->page_flags &= ~TTM_TT_FLAG_PRIV_POPULATED;
  328. }
  329. EXPORT_SYMBOL_FOR_TESTS_ONLY(ttm_tt_unpopulate);
  330. #ifdef CONFIG_DEBUG_FS
  331. /* Test the shrinker functions and dump the result */
  332. static int ttm_tt_debugfs_shrink_show(struct seq_file *m, void *data)
  333. {
  334. struct ttm_operation_ctx ctx = { false, false };
  335. seq_printf(m, "%d\n", ttm_global_swapout(&ctx, GFP_KERNEL));
  336. return 0;
  337. }
  338. DEFINE_SHOW_ATTRIBUTE(ttm_tt_debugfs_shrink);
  339. #endif
  340. /*
  341. * ttm_tt_mgr_init - register with the MM shrinker
  342. *
  343. * Register with the MM shrinker for swapping out BOs.
  344. */
  345. void ttm_tt_mgr_init(unsigned long num_pages, unsigned long num_dma32_pages)
  346. {
  347. #ifdef CONFIG_DEBUG_FS
  348. debugfs_create_file("tt_shrink", 0400, ttm_debugfs_root, NULL,
  349. &ttm_tt_debugfs_shrink_fops);
  350. #endif
  351. if (!ttm_pages_limit)
  352. ttm_pages_limit = num_pages;
  353. if (!ttm_dma32_pages_limit)
  354. ttm_dma32_pages_limit = num_dma32_pages;
  355. }
  356. static void ttm_kmap_iter_tt_map_local(struct ttm_kmap_iter *iter,
  357. struct iosys_map *dmap,
  358. pgoff_t i)
  359. {
  360. struct ttm_kmap_iter_tt *iter_tt =
  361. container_of(iter, typeof(*iter_tt), base);
  362. iosys_map_set_vaddr(dmap, kmap_local_page_prot(iter_tt->tt->pages[i],
  363. iter_tt->prot));
  364. }
  365. static void ttm_kmap_iter_tt_unmap_local(struct ttm_kmap_iter *iter,
  366. struct iosys_map *map)
  367. {
  368. kunmap_local(map->vaddr);
  369. }
  370. static const struct ttm_kmap_iter_ops ttm_kmap_iter_tt_ops = {
  371. .map_local = ttm_kmap_iter_tt_map_local,
  372. .unmap_local = ttm_kmap_iter_tt_unmap_local,
  373. .maps_tt = true,
  374. };
  375. /**
  376. * ttm_kmap_iter_tt_init - Initialize a struct ttm_kmap_iter_tt
  377. * @iter_tt: The struct ttm_kmap_iter_tt to initialize.
  378. * @tt: Struct ttm_tt holding page pointers of the struct ttm_resource.
  379. *
  380. * Return: Pointer to the embedded struct ttm_kmap_iter.
  381. */
  382. struct ttm_kmap_iter *
  383. ttm_kmap_iter_tt_init(struct ttm_kmap_iter_tt *iter_tt,
  384. struct ttm_tt *tt)
  385. {
  386. iter_tt->base.ops = &ttm_kmap_iter_tt_ops;
  387. iter_tt->tt = tt;
  388. if (tt)
  389. iter_tt->prot = ttm_prot_from_caching(tt->caching, PAGE_KERNEL);
  390. else
  391. iter_tt->prot = PAGE_KERNEL;
  392. return &iter_tt->base;
  393. }
  394. EXPORT_SYMBOL(ttm_kmap_iter_tt_init);
  395. unsigned long ttm_tt_pages_limit(void)
  396. {
  397. return ttm_pages_limit;
  398. }
  399. EXPORT_SYMBOL(ttm_tt_pages_limit);