system_heap.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * DMABUF System heap exporter
  4. *
  5. * Copyright (C) 2011 Google, Inc.
  6. * Copyright (C) 2019, 2020 Linaro Ltd.
  7. *
  8. * Portions based off of Andrew Davis' SRAM heap:
  9. * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
  10. * Andrew F. Davis <afd@ti.com>
  11. */
  12. #include <linux/dma-buf.h>
  13. #include <linux/dma-mapping.h>
  14. #include <linux/dma-heap.h>
  15. #include <linux/err.h>
  16. #include <linux/highmem.h>
  17. #include <linux/mm.h>
  18. #include <linux/module.h>
  19. #include <linux/scatterlist.h>
  20. #include <linux/slab.h>
  21. #include <linux/vmalloc.h>
  22. struct system_heap_buffer {
  23. struct dma_heap *heap;
  24. struct list_head attachments;
  25. struct mutex lock;
  26. unsigned long len;
  27. struct sg_table sg_table;
  28. int vmap_cnt;
  29. void *vaddr;
  30. };
  31. struct dma_heap_attachment {
  32. struct device *dev;
  33. struct sg_table table;
  34. struct list_head list;
  35. bool mapped;
  36. };
  37. #define LOW_ORDER_GFP (GFP_HIGHUSER | __GFP_ZERO)
  38. #define HIGH_ORDER_GFP (((GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN \
  39. | __GFP_NORETRY) & ~__GFP_RECLAIM) \
  40. | __GFP_COMP)
  41. static gfp_t order_flags[] = {HIGH_ORDER_GFP, HIGH_ORDER_GFP, LOW_ORDER_GFP};
  42. /*
  43. * The selection of the orders used for allocation (1MB, 64K, 4K) is designed
  44. * to match with the sizes often found in IOMMUs. Using order 4 pages instead
  45. * of order 0 pages can significantly improve the performance of many IOMMUs
  46. * by reducing TLB pressure and time spent updating page tables.
  47. */
  48. static const unsigned int orders[] = {8, 4, 0};
  49. #define NUM_ORDERS ARRAY_SIZE(orders)
  50. static int dup_sg_table(struct sg_table *from, struct sg_table *to)
  51. {
  52. struct scatterlist *sg, *new_sg;
  53. int ret, i;
  54. ret = sg_alloc_table(to, from->orig_nents, GFP_KERNEL);
  55. if (ret)
  56. return ret;
  57. new_sg = to->sgl;
  58. for_each_sgtable_sg(from, sg, i) {
  59. sg_set_page(new_sg, sg_page(sg), sg->length, sg->offset);
  60. new_sg = sg_next(new_sg);
  61. }
  62. return 0;
  63. }
  64. static int system_heap_attach(struct dma_buf *dmabuf,
  65. struct dma_buf_attachment *attachment)
  66. {
  67. struct system_heap_buffer *buffer = dmabuf->priv;
  68. struct dma_heap_attachment *a;
  69. int ret;
  70. a = kzalloc_obj(*a);
  71. if (!a)
  72. return -ENOMEM;
  73. ret = dup_sg_table(&buffer->sg_table, &a->table);
  74. if (ret) {
  75. kfree(a);
  76. return ret;
  77. }
  78. a->dev = attachment->dev;
  79. INIT_LIST_HEAD(&a->list);
  80. a->mapped = false;
  81. attachment->priv = a;
  82. mutex_lock(&buffer->lock);
  83. list_add(&a->list, &buffer->attachments);
  84. mutex_unlock(&buffer->lock);
  85. return 0;
  86. }
  87. static void system_heap_detach(struct dma_buf *dmabuf,
  88. struct dma_buf_attachment *attachment)
  89. {
  90. struct system_heap_buffer *buffer = dmabuf->priv;
  91. struct dma_heap_attachment *a = attachment->priv;
  92. mutex_lock(&buffer->lock);
  93. list_del(&a->list);
  94. mutex_unlock(&buffer->lock);
  95. sg_free_table(&a->table);
  96. kfree(a);
  97. }
  98. static struct sg_table *system_heap_map_dma_buf(struct dma_buf_attachment *attachment,
  99. enum dma_data_direction direction)
  100. {
  101. struct dma_heap_attachment *a = attachment->priv;
  102. struct sg_table *table = &a->table;
  103. int ret;
  104. ret = dma_map_sgtable(attachment->dev, table, direction, 0);
  105. if (ret)
  106. return ERR_PTR(ret);
  107. a->mapped = true;
  108. return table;
  109. }
  110. static void system_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
  111. struct sg_table *table,
  112. enum dma_data_direction direction)
  113. {
  114. struct dma_heap_attachment *a = attachment->priv;
  115. a->mapped = false;
  116. dma_unmap_sgtable(attachment->dev, table, direction, 0);
  117. }
  118. static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
  119. enum dma_data_direction direction)
  120. {
  121. struct system_heap_buffer *buffer = dmabuf->priv;
  122. struct dma_heap_attachment *a;
  123. mutex_lock(&buffer->lock);
  124. if (buffer->vmap_cnt)
  125. invalidate_kernel_vmap_range(buffer->vaddr, buffer->len);
  126. list_for_each_entry(a, &buffer->attachments, list) {
  127. if (!a->mapped)
  128. continue;
  129. dma_sync_sgtable_for_cpu(a->dev, &a->table, direction);
  130. }
  131. mutex_unlock(&buffer->lock);
  132. return 0;
  133. }
  134. static int system_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
  135. enum dma_data_direction direction)
  136. {
  137. struct system_heap_buffer *buffer = dmabuf->priv;
  138. struct dma_heap_attachment *a;
  139. mutex_lock(&buffer->lock);
  140. if (buffer->vmap_cnt)
  141. flush_kernel_vmap_range(buffer->vaddr, buffer->len);
  142. list_for_each_entry(a, &buffer->attachments, list) {
  143. if (!a->mapped)
  144. continue;
  145. dma_sync_sgtable_for_device(a->dev, &a->table, direction);
  146. }
  147. mutex_unlock(&buffer->lock);
  148. return 0;
  149. }
  150. static int system_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
  151. {
  152. struct system_heap_buffer *buffer = dmabuf->priv;
  153. struct sg_table *table = &buffer->sg_table;
  154. unsigned long addr = vma->vm_start;
  155. unsigned long pgoff = vma->vm_pgoff;
  156. struct scatterlist *sg;
  157. int i, ret;
  158. for_each_sgtable_sg(table, sg, i) {
  159. unsigned long n = sg->length >> PAGE_SHIFT;
  160. if (pgoff < n)
  161. break;
  162. pgoff -= n;
  163. }
  164. for (; sg && addr < vma->vm_end; sg = sg_next(sg)) {
  165. unsigned long n = (sg->length >> PAGE_SHIFT) - pgoff;
  166. struct page *page = sg_page(sg) + pgoff;
  167. unsigned long size = n << PAGE_SHIFT;
  168. if (addr + size > vma->vm_end)
  169. size = vma->vm_end - addr;
  170. ret = remap_pfn_range(vma, addr, page_to_pfn(page),
  171. size, vma->vm_page_prot);
  172. if (ret)
  173. return ret;
  174. addr += size;
  175. pgoff = 0;
  176. }
  177. return 0;
  178. }
  179. static void *system_heap_do_vmap(struct system_heap_buffer *buffer)
  180. {
  181. struct sg_table *table = &buffer->sg_table;
  182. int npages = PAGE_ALIGN(buffer->len) / PAGE_SIZE;
  183. struct page **pages = vmalloc(sizeof(struct page *) * npages);
  184. struct page **tmp = pages;
  185. struct sg_page_iter piter;
  186. void *vaddr;
  187. if (!pages)
  188. return ERR_PTR(-ENOMEM);
  189. for_each_sgtable_page(table, &piter, 0) {
  190. WARN_ON(tmp - pages >= npages);
  191. *tmp++ = sg_page_iter_page(&piter);
  192. }
  193. vaddr = vmap(pages, npages, VM_MAP, PAGE_KERNEL);
  194. vfree(pages);
  195. if (!vaddr)
  196. return ERR_PTR(-ENOMEM);
  197. return vaddr;
  198. }
  199. static int system_heap_vmap(struct dma_buf *dmabuf, struct iosys_map *map)
  200. {
  201. struct system_heap_buffer *buffer = dmabuf->priv;
  202. void *vaddr;
  203. int ret = 0;
  204. mutex_lock(&buffer->lock);
  205. if (buffer->vmap_cnt) {
  206. buffer->vmap_cnt++;
  207. iosys_map_set_vaddr(map, buffer->vaddr);
  208. goto out;
  209. }
  210. vaddr = system_heap_do_vmap(buffer);
  211. if (IS_ERR(vaddr)) {
  212. ret = PTR_ERR(vaddr);
  213. goto out;
  214. }
  215. buffer->vaddr = vaddr;
  216. buffer->vmap_cnt++;
  217. iosys_map_set_vaddr(map, buffer->vaddr);
  218. out:
  219. mutex_unlock(&buffer->lock);
  220. return ret;
  221. }
  222. static void system_heap_vunmap(struct dma_buf *dmabuf, struct iosys_map *map)
  223. {
  224. struct system_heap_buffer *buffer = dmabuf->priv;
  225. mutex_lock(&buffer->lock);
  226. if (!--buffer->vmap_cnt) {
  227. vunmap(buffer->vaddr);
  228. buffer->vaddr = NULL;
  229. }
  230. mutex_unlock(&buffer->lock);
  231. iosys_map_clear(map);
  232. }
  233. static void system_heap_dma_buf_release(struct dma_buf *dmabuf)
  234. {
  235. struct system_heap_buffer *buffer = dmabuf->priv;
  236. struct sg_table *table;
  237. struct scatterlist *sg;
  238. int i;
  239. table = &buffer->sg_table;
  240. for_each_sgtable_sg(table, sg, i) {
  241. struct page *page = sg_page(sg);
  242. __free_pages(page, compound_order(page));
  243. }
  244. sg_free_table(table);
  245. kfree(buffer);
  246. }
  247. static const struct dma_buf_ops system_heap_buf_ops = {
  248. .attach = system_heap_attach,
  249. .detach = system_heap_detach,
  250. .map_dma_buf = system_heap_map_dma_buf,
  251. .unmap_dma_buf = system_heap_unmap_dma_buf,
  252. .begin_cpu_access = system_heap_dma_buf_begin_cpu_access,
  253. .end_cpu_access = system_heap_dma_buf_end_cpu_access,
  254. .mmap = system_heap_mmap,
  255. .vmap = system_heap_vmap,
  256. .vunmap = system_heap_vunmap,
  257. .release = system_heap_dma_buf_release,
  258. };
  259. static struct page *alloc_largest_available(unsigned long size,
  260. unsigned int max_order)
  261. {
  262. struct page *page;
  263. int i;
  264. gfp_t flags;
  265. for (i = 0; i < NUM_ORDERS; i++) {
  266. if (size < (PAGE_SIZE << orders[i]))
  267. continue;
  268. if (max_order < orders[i])
  269. continue;
  270. flags = order_flags[i];
  271. if (mem_accounting)
  272. flags |= __GFP_ACCOUNT;
  273. page = alloc_pages(flags, orders[i]);
  274. if (!page)
  275. continue;
  276. return page;
  277. }
  278. return NULL;
  279. }
  280. static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
  281. unsigned long len,
  282. u32 fd_flags,
  283. u64 heap_flags)
  284. {
  285. struct system_heap_buffer *buffer;
  286. DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
  287. unsigned long size_remaining = len;
  288. unsigned int max_order = orders[0];
  289. struct dma_buf *dmabuf;
  290. struct sg_table *table;
  291. struct scatterlist *sg;
  292. struct list_head pages;
  293. struct page *page, *tmp_page;
  294. int i, ret = -ENOMEM;
  295. buffer = kzalloc_obj(*buffer);
  296. if (!buffer)
  297. return ERR_PTR(-ENOMEM);
  298. INIT_LIST_HEAD(&buffer->attachments);
  299. mutex_init(&buffer->lock);
  300. buffer->heap = heap;
  301. buffer->len = len;
  302. INIT_LIST_HEAD(&pages);
  303. i = 0;
  304. while (size_remaining > 0) {
  305. /*
  306. * Avoid trying to allocate memory if the process
  307. * has been killed by SIGKILL
  308. */
  309. if (fatal_signal_pending(current)) {
  310. ret = -EINTR;
  311. goto free_buffer;
  312. }
  313. page = alloc_largest_available(size_remaining, max_order);
  314. if (!page)
  315. goto free_buffer;
  316. list_add_tail(&page->lru, &pages);
  317. size_remaining -= page_size(page);
  318. max_order = compound_order(page);
  319. i++;
  320. }
  321. table = &buffer->sg_table;
  322. if (sg_alloc_table(table, i, GFP_KERNEL))
  323. goto free_buffer;
  324. sg = table->sgl;
  325. list_for_each_entry_safe(page, tmp_page, &pages, lru) {
  326. sg_set_page(sg, page, page_size(page), 0);
  327. sg = sg_next(sg);
  328. list_del(&page->lru);
  329. }
  330. /* create the dmabuf */
  331. exp_info.exp_name = dma_heap_get_name(heap);
  332. exp_info.ops = &system_heap_buf_ops;
  333. exp_info.size = buffer->len;
  334. exp_info.flags = fd_flags;
  335. exp_info.priv = buffer;
  336. dmabuf = dma_buf_export(&exp_info);
  337. if (IS_ERR(dmabuf)) {
  338. ret = PTR_ERR(dmabuf);
  339. goto free_pages;
  340. }
  341. return dmabuf;
  342. free_pages:
  343. for_each_sgtable_sg(table, sg, i) {
  344. struct page *p = sg_page(sg);
  345. __free_pages(p, compound_order(p));
  346. }
  347. sg_free_table(table);
  348. free_buffer:
  349. list_for_each_entry_safe(page, tmp_page, &pages, lru)
  350. __free_pages(page, compound_order(page));
  351. kfree(buffer);
  352. return ERR_PTR(ret);
  353. }
  354. static const struct dma_heap_ops system_heap_ops = {
  355. .allocate = system_heap_allocate,
  356. };
  357. static int __init system_heap_create(void)
  358. {
  359. struct dma_heap_export_info exp_info;
  360. struct dma_heap *sys_heap;
  361. exp_info.name = "system";
  362. exp_info.ops = &system_heap_ops;
  363. exp_info.priv = NULL;
  364. sys_heap = dma_heap_add(&exp_info);
  365. if (IS_ERR(sys_heap))
  366. return PTR_ERR(sys_heap);
  367. return 0;
  368. }
  369. module_init(system_heap_create);