dmapool_test.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/device.h>
  3. #include <linux/dma-map-ops.h>
  4. #include <linux/dma-mapping.h>
  5. #include <linux/dmapool.h>
  6. #include <linux/kernel.h>
  7. #include <linux/ktime.h>
  8. #include <linux/module.h>
  9. #define NR_TESTS (100)
  10. struct dma_pool_pair {
  11. dma_addr_t dma;
  12. void *v;
  13. };
  14. struct dmapool_parms {
  15. size_t size;
  16. size_t align;
  17. size_t boundary;
  18. };
  19. static const struct dmapool_parms pool_parms[] = {
  20. { .size = 16, .align = 16, .boundary = 0 },
  21. { .size = 64, .align = 64, .boundary = 0 },
  22. { .size = 256, .align = 256, .boundary = 0 },
  23. { .size = 1024, .align = 1024, .boundary = 0 },
  24. { .size = 4096, .align = 4096, .boundary = 0 },
  25. { .size = 68, .align = 32, .boundary = 4096 },
  26. };
  27. static struct dma_pool *pool;
  28. static struct device test_dev;
  29. static u64 dma_mask;
  30. static inline int nr_blocks(int size)
  31. {
  32. return clamp_t(int, (PAGE_SIZE / size) * 512, 1024, 8192);
  33. }
  34. static int dmapool_test_alloc(struct dma_pool_pair *p, int blocks)
  35. {
  36. int i;
  37. for (i = 0; i < blocks; i++) {
  38. p[i].v = dma_pool_alloc(pool, GFP_KERNEL,
  39. &p[i].dma);
  40. if (!p[i].v)
  41. goto pool_fail;
  42. }
  43. for (i = 0; i < blocks; i++)
  44. dma_pool_free(pool, p[i].v, p[i].dma);
  45. return 0;
  46. pool_fail:
  47. for (--i; i >= 0; i--)
  48. dma_pool_free(pool, p[i].v, p[i].dma);
  49. return -ENOMEM;
  50. }
  51. static int dmapool_test_block(const struct dmapool_parms *parms)
  52. {
  53. int blocks = nr_blocks(parms->size);
  54. ktime_t start_time, end_time;
  55. struct dma_pool_pair *p;
  56. int i, ret;
  57. p = kzalloc_objs(*p, blocks);
  58. if (!p)
  59. return -ENOMEM;
  60. pool = dma_pool_create("test pool", &test_dev, parms->size,
  61. parms->align, parms->boundary);
  62. if (!pool) {
  63. ret = -ENOMEM;
  64. goto free_pairs;
  65. }
  66. start_time = ktime_get();
  67. for (i = 0; i < NR_TESTS; i++) {
  68. ret = dmapool_test_alloc(p, blocks);
  69. if (ret)
  70. goto free_pool;
  71. if (need_resched())
  72. cond_resched();
  73. }
  74. end_time = ktime_get();
  75. printk("dmapool test: size:%-4zu align:%-4zu blocks:%-4d time:%llu\n",
  76. parms->size, parms->align, blocks,
  77. ktime_us_delta(end_time, start_time));
  78. free_pool:
  79. dma_pool_destroy(pool);
  80. free_pairs:
  81. kfree(p);
  82. return ret;
  83. }
  84. static void dmapool_test_release(struct device *dev)
  85. {
  86. }
  87. static int dmapool_checks(void)
  88. {
  89. int i, ret;
  90. ret = dev_set_name(&test_dev, "dmapool-test");
  91. if (ret)
  92. return ret;
  93. ret = device_register(&test_dev);
  94. if (ret) {
  95. printk("%s: register failed:%d\n", __func__, ret);
  96. goto put_device;
  97. }
  98. test_dev.release = dmapool_test_release;
  99. set_dma_ops(&test_dev, NULL);
  100. test_dev.dma_mask = &dma_mask;
  101. ret = dma_set_mask_and_coherent(&test_dev, DMA_BIT_MASK(64));
  102. if (ret) {
  103. printk("%s: mask failed:%d\n", __func__, ret);
  104. goto del_device;
  105. }
  106. for (i = 0; i < ARRAY_SIZE(pool_parms); i++) {
  107. ret = dmapool_test_block(&pool_parms[i]);
  108. if (ret)
  109. break;
  110. }
  111. del_device:
  112. device_del(&test_dev);
  113. put_device:
  114. put_device(&test_dev);
  115. return ret;
  116. }
  117. static void dmapool_exit(void)
  118. {
  119. }
  120. module_init(dmapool_checks);
  121. module_exit(dmapool_exit);
  122. MODULE_DESCRIPTION("dma_pool timing test");
  123. MODULE_LICENSE("GPL");