dmapool_test.c 2.9 KB

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