intel_memory_region.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. // SPDX-License-Identifier: MIT
  2. /*
  3. * Copyright © 2019 Intel Corporation
  4. */
  5. #include <linux/prandom.h>
  6. #include <drm/drm_print.h>
  7. #include <uapi/drm/i915_drm.h>
  8. #include "intel_memory_region.h"
  9. #include "i915_drv.h"
  10. #include "i915_ttm_buddy_manager.h"
  11. static const struct {
  12. u16 class;
  13. u16 instance;
  14. } intel_region_map[] = {
  15. [INTEL_REGION_SMEM] = {
  16. .class = INTEL_MEMORY_SYSTEM,
  17. .instance = 0,
  18. },
  19. [INTEL_REGION_LMEM_0] = {
  20. .class = INTEL_MEMORY_LOCAL,
  21. .instance = 0,
  22. },
  23. [INTEL_REGION_STOLEN_SMEM] = {
  24. .class = INTEL_MEMORY_STOLEN_SYSTEM,
  25. .instance = 0,
  26. },
  27. [INTEL_REGION_STOLEN_LMEM] = {
  28. .class = INTEL_MEMORY_STOLEN_LOCAL,
  29. .instance = 0,
  30. },
  31. };
  32. static int __iopagetest(struct intel_memory_region *mem,
  33. u8 __iomem *va, int pagesize,
  34. u8 value, resource_size_t offset,
  35. const void *caller)
  36. {
  37. int byte = get_random_u32_below(pagesize);
  38. u8 result[3];
  39. memset_io(va, value, pagesize); /* or GPF! */
  40. wmb();
  41. result[0] = ioread8(va);
  42. result[1] = ioread8(va + byte);
  43. result[2] = ioread8(va + pagesize - 1);
  44. if (memchr_inv(result, value, sizeof(result))) {
  45. dev_err(mem->i915->drm.dev,
  46. "Failed to read back from memory region:%pR at [%pa + %pa] for %ps; wrote %x, read (%x, %x, %x)\n",
  47. &mem->region, &mem->io.start, &offset, caller,
  48. value, result[0], result[1], result[2]);
  49. return -EINVAL;
  50. }
  51. return 0;
  52. }
  53. static int iopagetest(struct intel_memory_region *mem,
  54. resource_size_t offset,
  55. const void *caller)
  56. {
  57. const u8 val[] = { 0x0, 0xa5, 0xc3, 0xf0 };
  58. void __iomem *va;
  59. int err;
  60. int i;
  61. va = ioremap_wc(mem->io.start + offset, PAGE_SIZE);
  62. if (!va) {
  63. dev_err(mem->i915->drm.dev,
  64. "Failed to ioremap memory region [%pa + %pa] for %ps\n",
  65. &mem->io.start, &offset, caller);
  66. return -EFAULT;
  67. }
  68. for (i = 0; i < ARRAY_SIZE(val); i++) {
  69. err = __iopagetest(mem, va, PAGE_SIZE, val[i], offset, caller);
  70. if (err)
  71. break;
  72. err = __iopagetest(mem, va, PAGE_SIZE, ~val[i], offset, caller);
  73. if (err)
  74. break;
  75. }
  76. iounmap(va);
  77. return err;
  78. }
  79. static resource_size_t random_page(resource_size_t last)
  80. {
  81. /* Limited to low 44b (16TiB), but should suffice for a spot check */
  82. return get_random_u32_below(last >> PAGE_SHIFT) << PAGE_SHIFT;
  83. }
  84. static int iomemtest(struct intel_memory_region *mem,
  85. bool test_all,
  86. const void *caller)
  87. {
  88. resource_size_t last, page;
  89. int err;
  90. if (resource_size(&mem->io) < PAGE_SIZE)
  91. return 0;
  92. last = resource_size(&mem->io) - PAGE_SIZE;
  93. /*
  94. * Quick test to check read/write access to the iomap (backing store).
  95. *
  96. * Write a byte, read it back. If the iomapping fails, we expect
  97. * a GPF preventing further execution. If the backing store does not
  98. * exist, the read back will return garbage. We check a couple of pages,
  99. * the first and last of the specified region to confirm the backing
  100. * store + iomap does cover the entire memory region; and we check
  101. * a random offset within as a quick spot check for bad memory.
  102. */
  103. if (test_all) {
  104. for (page = 0; page <= last; page += PAGE_SIZE) {
  105. err = iopagetest(mem, page, caller);
  106. if (err)
  107. return err;
  108. }
  109. } else {
  110. err = iopagetest(mem, 0, caller);
  111. if (err)
  112. return err;
  113. err = iopagetest(mem, last, caller);
  114. if (err)
  115. return err;
  116. err = iopagetest(mem, random_page(last), caller);
  117. if (err)
  118. return err;
  119. }
  120. return 0;
  121. }
  122. struct intel_memory_region *
  123. intel_memory_region_lookup(struct drm_i915_private *i915,
  124. u16 class, u16 instance)
  125. {
  126. struct intel_memory_region *mr;
  127. int id;
  128. /* XXX: consider maybe converting to an rb tree at some point */
  129. for_each_memory_region(mr, i915, id) {
  130. if (mr->type == class && mr->instance == instance)
  131. return mr;
  132. }
  133. return NULL;
  134. }
  135. struct intel_memory_region *
  136. intel_memory_region_by_type(struct drm_i915_private *i915,
  137. enum intel_memory_type mem_type)
  138. {
  139. struct intel_memory_region *mr;
  140. int id;
  141. for_each_memory_region(mr, i915, id)
  142. if (mr->type == mem_type)
  143. return mr;
  144. return NULL;
  145. }
  146. bool intel_memory_type_is_local(enum intel_memory_type mem_type)
  147. {
  148. switch (mem_type) {
  149. case INTEL_MEMORY_LOCAL:
  150. case INTEL_MEMORY_STOLEN_LOCAL:
  151. return true;
  152. default:
  153. return false;
  154. }
  155. }
  156. /**
  157. * intel_memory_region_reserve - Reserve a memory range
  158. * @mem: The region for which we want to reserve a range.
  159. * @offset: Start of the range to reserve.
  160. * @size: The size of the range to reserve.
  161. *
  162. * Return: 0 on success, negative error code on failure.
  163. */
  164. int intel_memory_region_reserve(struct intel_memory_region *mem,
  165. resource_size_t offset,
  166. resource_size_t size)
  167. {
  168. struct ttm_resource_manager *man = mem->region_private;
  169. GEM_BUG_ON(mem->is_range_manager);
  170. return i915_ttm_buddy_man_reserve(man, offset, size);
  171. }
  172. void intel_memory_region_debug(struct intel_memory_region *mr,
  173. struct drm_printer *printer)
  174. {
  175. drm_printf(printer, "%s: ", mr->name);
  176. if (mr->region_private)
  177. ttm_resource_manager_debug(mr->region_private, printer);
  178. else
  179. drm_printf(printer, "total:%pa bytes\n", &mr->total);
  180. }
  181. static int intel_memory_region_memtest(struct intel_memory_region *mem,
  182. void *caller)
  183. {
  184. struct drm_i915_private *i915 = mem->i915;
  185. int err = 0;
  186. if (!mem->io.start)
  187. return 0;
  188. if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) || i915->params.memtest)
  189. err = iomemtest(mem, i915->params.memtest, caller);
  190. return err;
  191. }
  192. const char *intel_memory_type_str(enum intel_memory_type type)
  193. {
  194. switch (type) {
  195. case INTEL_MEMORY_SYSTEM:
  196. return "system";
  197. case INTEL_MEMORY_LOCAL:
  198. return "local";
  199. case INTEL_MEMORY_STOLEN_LOCAL:
  200. return "stolen-local";
  201. case INTEL_MEMORY_STOLEN_SYSTEM:
  202. return "stolen-system";
  203. default:
  204. return "unknown";
  205. }
  206. }
  207. struct intel_memory_region *
  208. intel_memory_region_create(struct drm_i915_private *i915,
  209. resource_size_t start,
  210. resource_size_t size,
  211. resource_size_t min_page_size,
  212. resource_size_t io_start,
  213. resource_size_t io_size,
  214. u16 type,
  215. u16 instance,
  216. const struct intel_memory_region_ops *ops)
  217. {
  218. struct intel_memory_region *mem;
  219. int err;
  220. mem = kzalloc_obj(*mem);
  221. if (!mem)
  222. return ERR_PTR(-ENOMEM);
  223. mem->i915 = i915;
  224. mem->region = DEFINE_RES_MEM(start, size);
  225. mem->io = DEFINE_RES_MEM(io_start, io_size);
  226. mem->min_page_size = min_page_size;
  227. mem->ops = ops;
  228. mem->total = size;
  229. mem->type = type;
  230. mem->instance = instance;
  231. snprintf(mem->uabi_name, sizeof(mem->uabi_name), "%s%u",
  232. intel_memory_type_str(type), instance);
  233. mutex_init(&mem->objects.lock);
  234. INIT_LIST_HEAD(&mem->objects.list);
  235. if (ops->init) {
  236. err = ops->init(mem);
  237. if (err)
  238. goto err_free;
  239. }
  240. err = intel_memory_region_memtest(mem, (void *)_RET_IP_);
  241. if (err)
  242. goto err_release;
  243. return mem;
  244. err_release:
  245. if (mem->ops->release)
  246. mem->ops->release(mem);
  247. err_free:
  248. kfree(mem);
  249. return ERR_PTR(err);
  250. }
  251. void intel_memory_region_set_name(struct intel_memory_region *mem,
  252. const char *fmt, ...)
  253. {
  254. va_list ap;
  255. va_start(ap, fmt);
  256. vsnprintf(mem->name, sizeof(mem->name), fmt, ap);
  257. va_end(ap);
  258. }
  259. void intel_memory_region_avail(struct intel_memory_region *mr,
  260. u64 *avail, u64 *visible_avail)
  261. {
  262. if (mr->type == INTEL_MEMORY_LOCAL) {
  263. i915_ttm_buddy_man_avail(mr->region_private,
  264. avail, visible_avail);
  265. *avail <<= PAGE_SHIFT;
  266. *visible_avail <<= PAGE_SHIFT;
  267. } else {
  268. *avail = mr->total;
  269. *visible_avail = mr->total;
  270. }
  271. }
  272. void intel_memory_region_destroy(struct intel_memory_region *mem)
  273. {
  274. int ret = 0;
  275. if (mem->ops->release)
  276. ret = mem->ops->release(mem);
  277. GEM_WARN_ON(!list_empty_careful(&mem->objects.list));
  278. mutex_destroy(&mem->objects.lock);
  279. if (!ret)
  280. kfree(mem);
  281. }
  282. /* Global memory region registration -- only slight layer inversions! */
  283. int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
  284. {
  285. int err, i;
  286. for (i = 0; i < ARRAY_SIZE(i915->mm.regions); i++) {
  287. struct intel_memory_region *mem = ERR_PTR(-ENODEV);
  288. u16 type, instance;
  289. if (!HAS_REGION(i915, i))
  290. continue;
  291. type = intel_region_map[i].class;
  292. instance = intel_region_map[i].instance;
  293. switch (type) {
  294. case INTEL_MEMORY_SYSTEM:
  295. if (IS_DGFX(i915))
  296. mem = i915_gem_ttm_system_setup(i915, type,
  297. instance);
  298. else
  299. mem = i915_gem_shmem_setup(i915, type,
  300. instance);
  301. break;
  302. case INTEL_MEMORY_STOLEN_LOCAL:
  303. mem = i915_gem_stolen_lmem_setup(i915, type, instance);
  304. if (!IS_ERR(mem))
  305. i915->mm.stolen_region = mem;
  306. break;
  307. case INTEL_MEMORY_STOLEN_SYSTEM:
  308. mem = i915_gem_stolen_smem_setup(i915, type, instance);
  309. if (!IS_ERR(mem))
  310. i915->mm.stolen_region = mem;
  311. break;
  312. default:
  313. continue;
  314. }
  315. if (IS_ERR(mem)) {
  316. err = PTR_ERR(mem);
  317. drm_err(&i915->drm,
  318. "Failed to setup region(%d) type=%d\n",
  319. err, type);
  320. goto out_cleanup;
  321. }
  322. if (mem) { /* Skip on non-fatal errors */
  323. mem->id = i;
  324. i915->mm.regions[i] = mem;
  325. }
  326. }
  327. for (i = 0; i < ARRAY_SIZE(i915->mm.regions); i++) {
  328. struct intel_memory_region *mem = i915->mm.regions[i];
  329. u64 region_size, io_size;
  330. if (!mem)
  331. continue;
  332. region_size = resource_size(&mem->region) >> 20;
  333. io_size = resource_size(&mem->io) >> 20;
  334. if (resource_size(&mem->io))
  335. drm_dbg(&i915->drm, "Memory region(%d): %s: %llu MiB %pR, io: %llu MiB %pR\n",
  336. mem->id, mem->name, region_size, &mem->region, io_size, &mem->io);
  337. else
  338. drm_dbg(&i915->drm, "Memory region(%d): %s: %llu MiB %pR, io: n/a\n",
  339. mem->id, mem->name, region_size, &mem->region);
  340. }
  341. return 0;
  342. out_cleanup:
  343. intel_memory_regions_driver_release(i915);
  344. return err;
  345. }
  346. void intel_memory_regions_driver_release(struct drm_i915_private *i915)
  347. {
  348. int i;
  349. for (i = 0; i < ARRAY_SIZE(i915->mm.regions); i++) {
  350. struct intel_memory_region *region =
  351. fetch_and_zero(&i915->mm.regions[i]);
  352. if (region)
  353. intel_memory_region_destroy(region);
  354. }
  355. }
  356. #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
  357. #include "selftests/intel_memory_region.c"
  358. #include "selftests/mock_region.c"
  359. #endif