scm_blk_cluster.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. * Block driver for s390 storage class memory.
  3. *
  4. * Copyright IBM Corp. 2012
  5. * Author(s): Sebastian Ott <sebott@linux.vnet.ibm.com>
  6. */
  7. #include <linux/spinlock.h>
  8. #include <linux/module.h>
  9. #include <linux/blkdev.h>
  10. #include <linux/genhd.h>
  11. #include <linux/slab.h>
  12. #include <linux/list.h>
  13. #include <asm/eadm.h>
  14. #include "scm_blk.h"
  15. static unsigned int write_cluster_size = 64;
  16. module_param(write_cluster_size, uint, S_IRUGO);
  17. MODULE_PARM_DESC(write_cluster_size,
  18. "Number of pages used for contiguous writes.");
  19. #define CLUSTER_SIZE (write_cluster_size * PAGE_SIZE)
  20. void __scm_free_rq_cluster(struct scm_request *scmrq)
  21. {
  22. int i;
  23. if (!scmrq->cluster.buf)
  24. return;
  25. for (i = 0; i < 2 * write_cluster_size; i++)
  26. free_page((unsigned long) scmrq->cluster.buf[i]);
  27. kfree(scmrq->cluster.buf);
  28. }
  29. int __scm_alloc_rq_cluster(struct scm_request *scmrq)
  30. {
  31. int i;
  32. scmrq->cluster.buf = kzalloc(sizeof(void *) * 2 * write_cluster_size,
  33. GFP_KERNEL);
  34. if (!scmrq->cluster.buf)
  35. return -ENOMEM;
  36. for (i = 0; i < 2 * write_cluster_size; i++) {
  37. scmrq->cluster.buf[i] = (void *) get_zeroed_page(GFP_DMA);
  38. if (!scmrq->cluster.buf[i])
  39. return -ENOMEM;
  40. }
  41. INIT_LIST_HEAD(&scmrq->cluster.list);
  42. return 0;
  43. }
  44. void scm_request_cluster_init(struct scm_request *scmrq)
  45. {
  46. scmrq->cluster.state = CLUSTER_NONE;
  47. }
  48. static bool clusters_intersect(struct request *A, struct request *B)
  49. {
  50. unsigned long firstA, lastA, firstB, lastB;
  51. firstA = ((u64) blk_rq_pos(A) << 9) / CLUSTER_SIZE;
  52. lastA = (((u64) blk_rq_pos(A) << 9) +
  53. blk_rq_bytes(A) - 1) / CLUSTER_SIZE;
  54. firstB = ((u64) blk_rq_pos(B) << 9) / CLUSTER_SIZE;
  55. lastB = (((u64) blk_rq_pos(B) << 9) +
  56. blk_rq_bytes(B) - 1) / CLUSTER_SIZE;
  57. return (firstB <= lastA && firstA <= lastB);
  58. }
  59. bool scm_reserve_cluster(struct scm_request *scmrq)
  60. {
  61. struct request *req = scmrq->request[scmrq->aob->request.msb_count];
  62. struct scm_blk_dev *bdev = scmrq->bdev;
  63. struct scm_request *iter;
  64. int pos, add = 1;
  65. if (write_cluster_size == 0)
  66. return true;
  67. spin_lock(&bdev->lock);
  68. list_for_each_entry(iter, &bdev->cluster_list, cluster.list) {
  69. if (iter == scmrq) {
  70. /*
  71. * We don't have to use clusters_intersect here, since
  72. * cluster requests are always started separately.
  73. */
  74. add = 0;
  75. continue;
  76. }
  77. for (pos = 0; pos < iter->aob->request.msb_count; pos++) {
  78. if (clusters_intersect(req, iter->request[pos]) &&
  79. (rq_data_dir(req) == WRITE ||
  80. rq_data_dir(iter->request[pos]) == WRITE)) {
  81. spin_unlock(&bdev->lock);
  82. return false;
  83. }
  84. }
  85. }
  86. if (add)
  87. list_add(&scmrq->cluster.list, &bdev->cluster_list);
  88. spin_unlock(&bdev->lock);
  89. return true;
  90. }
  91. void scm_release_cluster(struct scm_request *scmrq)
  92. {
  93. struct scm_blk_dev *bdev = scmrq->bdev;
  94. unsigned long flags;
  95. if (write_cluster_size == 0)
  96. return;
  97. spin_lock_irqsave(&bdev->lock, flags);
  98. list_del(&scmrq->cluster.list);
  99. spin_unlock_irqrestore(&bdev->lock, flags);
  100. }
  101. void scm_blk_dev_cluster_setup(struct scm_blk_dev *bdev)
  102. {
  103. INIT_LIST_HEAD(&bdev->cluster_list);
  104. blk_queue_io_opt(bdev->rq, CLUSTER_SIZE);
  105. }
  106. static int scm_prepare_cluster_request(struct scm_request *scmrq)
  107. {
  108. struct scm_blk_dev *bdev = scmrq->bdev;
  109. struct scm_device *scmdev = bdev->gendisk->private_data;
  110. struct request *req = scmrq->request[0];
  111. struct msb *msb = &scmrq->aob->msb[0];
  112. struct req_iterator iter;
  113. struct aidaw *aidaw;
  114. struct bio_vec bv;
  115. int i = 0;
  116. u64 addr;
  117. switch (scmrq->cluster.state) {
  118. case CLUSTER_NONE:
  119. scmrq->cluster.state = CLUSTER_READ;
  120. /* fall through */
  121. case CLUSTER_READ:
  122. msb->bs = MSB_BS_4K;
  123. msb->oc = MSB_OC_READ;
  124. msb->flags = MSB_FLAG_IDA;
  125. msb->blk_count = write_cluster_size;
  126. addr = scmdev->address + ((u64) blk_rq_pos(req) << 9);
  127. msb->scm_addr = round_down(addr, CLUSTER_SIZE);
  128. if (msb->scm_addr !=
  129. round_down(addr + (u64) blk_rq_bytes(req) - 1,
  130. CLUSTER_SIZE))
  131. msb->blk_count = 2 * write_cluster_size;
  132. aidaw = scm_aidaw_fetch(scmrq, msb->blk_count * PAGE_SIZE);
  133. if (!aidaw)
  134. return -ENOMEM;
  135. scmrq->aob->request.msb_count = 1;
  136. msb->data_addr = (u64) aidaw;
  137. for (i = 0; i < msb->blk_count; i++) {
  138. aidaw->data_addr = (u64) scmrq->cluster.buf[i];
  139. aidaw++;
  140. }
  141. break;
  142. case CLUSTER_WRITE:
  143. aidaw = (void *) msb->data_addr;
  144. msb->oc = MSB_OC_WRITE;
  145. for (addr = msb->scm_addr;
  146. addr < scmdev->address + ((u64) blk_rq_pos(req) << 9);
  147. addr += PAGE_SIZE) {
  148. aidaw->data_addr = (u64) scmrq->cluster.buf[i];
  149. aidaw++;
  150. i++;
  151. }
  152. rq_for_each_segment(bv, req, iter) {
  153. aidaw->data_addr = (u64) page_address(bv.bv_page);
  154. aidaw++;
  155. i++;
  156. }
  157. for (; i < msb->blk_count; i++) {
  158. aidaw->data_addr = (u64) scmrq->cluster.buf[i];
  159. aidaw++;
  160. }
  161. break;
  162. }
  163. return 0;
  164. }
  165. bool scm_need_cluster_request(struct scm_request *scmrq)
  166. {
  167. int pos = scmrq->aob->request.msb_count;
  168. if (rq_data_dir(scmrq->request[pos]) == READ)
  169. return false;
  170. return blk_rq_bytes(scmrq->request[pos]) < CLUSTER_SIZE;
  171. }
  172. /* Called with queue lock held. */
  173. void scm_initiate_cluster_request(struct scm_request *scmrq)
  174. {
  175. if (scm_prepare_cluster_request(scmrq))
  176. goto requeue;
  177. if (eadm_start_aob(scmrq->aob))
  178. goto requeue;
  179. return;
  180. requeue:
  181. scm_request_requeue(scmrq);
  182. }
  183. bool scm_test_cluster_request(struct scm_request *scmrq)
  184. {
  185. return scmrq->cluster.state != CLUSTER_NONE;
  186. }
  187. void scm_cluster_request_irq(struct scm_request *scmrq)
  188. {
  189. struct scm_blk_dev *bdev = scmrq->bdev;
  190. unsigned long flags;
  191. switch (scmrq->cluster.state) {
  192. case CLUSTER_NONE:
  193. BUG();
  194. break;
  195. case CLUSTER_READ:
  196. if (scmrq->error) {
  197. scm_request_finish(scmrq);
  198. break;
  199. }
  200. scmrq->cluster.state = CLUSTER_WRITE;
  201. spin_lock_irqsave(&bdev->rq_lock, flags);
  202. scm_initiate_cluster_request(scmrq);
  203. spin_unlock_irqrestore(&bdev->rq_lock, flags);
  204. break;
  205. case CLUSTER_WRITE:
  206. scm_request_finish(scmrq);
  207. break;
  208. }
  209. }
  210. bool scm_cluster_size_valid(void)
  211. {
  212. if (write_cluster_size == 1 || write_cluster_size > 128)
  213. return false;
  214. return !(write_cluster_size & (write_cluster_size - 1));
  215. }