2 * Block driver for s390 storage class memory.
4 * Copyright IBM Corp. 2012
5 * Author(s): Sebastian Ott <sebott@linux.vnet.ibm.com>
8 #include <linux/spinlock.h>
9 #include <linux/module.h>
10 #include <linux/blkdev.h>
11 #include <linux/genhd.h>
12 #include <linux/slab.h>
13 #include <linux/list.h>
17 static unsigned int write_cluster_size
= 64;
18 module_param(write_cluster_size
, uint
, S_IRUGO
);
19 MODULE_PARM_DESC(write_cluster_size
,
20 "Number of pages used for contiguous writes.");
22 #define CLUSTER_SIZE (write_cluster_size * PAGE_SIZE)
24 void __scm_free_rq_cluster(struct scm_request
*scmrq
)
28 if (!scmrq
->cluster
.buf
)
31 for (i
= 0; i
< 2 * write_cluster_size
; i
++)
32 free_page((unsigned long) scmrq
->cluster
.buf
[i
]);
34 kfree(scmrq
->cluster
.buf
);
37 int __scm_alloc_rq_cluster(struct scm_request
*scmrq
)
41 scmrq
->cluster
.buf
= kzalloc(sizeof(void *) * 2 * write_cluster_size
,
43 if (!scmrq
->cluster
.buf
)
46 for (i
= 0; i
< 2 * write_cluster_size
; i
++) {
47 scmrq
->cluster
.buf
[i
] = (void *) get_zeroed_page(GFP_DMA
);
48 if (!scmrq
->cluster
.buf
[i
])
51 INIT_LIST_HEAD(&scmrq
->cluster
.list
);
55 void scm_request_cluster_init(struct scm_request
*scmrq
)
57 scmrq
->cluster
.state
= CLUSTER_NONE
;
60 static bool clusters_intersect(struct request
*A
, struct request
*B
)
62 unsigned long firstA
, lastA
, firstB
, lastB
;
64 firstA
= ((u64
) blk_rq_pos(A
) << 9) / CLUSTER_SIZE
;
65 lastA
= (((u64
) blk_rq_pos(A
) << 9) +
66 blk_rq_bytes(A
) - 1) / CLUSTER_SIZE
;
68 firstB
= ((u64
) blk_rq_pos(B
) << 9) / CLUSTER_SIZE
;
69 lastB
= (((u64
) blk_rq_pos(B
) << 9) +
70 blk_rq_bytes(B
) - 1) / CLUSTER_SIZE
;
72 return (firstB
<= lastA
&& firstA
<= lastB
);
75 bool scm_reserve_cluster(struct scm_request
*scmrq
)
77 struct request
*req
= scmrq
->request
[scmrq
->aob
->request
.msb_count
];
78 struct scm_blk_dev
*bdev
= scmrq
->bdev
;
79 struct scm_request
*iter
;
82 if (write_cluster_size
== 0)
85 spin_lock(&bdev
->lock
);
86 list_for_each_entry(iter
, &bdev
->cluster_list
, cluster
.list
) {
89 * We don't have to use clusters_intersect here, since
90 * cluster requests are always started separately.
95 for (pos
= 0; pos
< iter
->aob
->request
.msb_count
; pos
++) {
96 if (clusters_intersect(req
, iter
->request
[pos
]) &&
97 (rq_data_dir(req
) == WRITE
||
98 rq_data_dir(iter
->request
[pos
]) == WRITE
)) {
99 spin_unlock(&bdev
->lock
);
105 list_add(&scmrq
->cluster
.list
, &bdev
->cluster_list
);
106 spin_unlock(&bdev
->lock
);
111 void scm_release_cluster(struct scm_request
*scmrq
)
113 struct scm_blk_dev
*bdev
= scmrq
->bdev
;
116 if (write_cluster_size
== 0)
119 spin_lock_irqsave(&bdev
->lock
, flags
);
120 list_del(&scmrq
->cluster
.list
);
121 spin_unlock_irqrestore(&bdev
->lock
, flags
);
124 void scm_blk_dev_cluster_setup(struct scm_blk_dev
*bdev
)
126 INIT_LIST_HEAD(&bdev
->cluster_list
);
127 blk_queue_io_opt(bdev
->rq
, CLUSTER_SIZE
);
130 static int scm_prepare_cluster_request(struct scm_request
*scmrq
)
132 struct scm_blk_dev
*bdev
= scmrq
->bdev
;
133 struct scm_device
*scmdev
= bdev
->gendisk
->private_data
;
134 struct request
*req
= scmrq
->request
[0];
135 struct msb
*msb
= &scmrq
->aob
->msb
[0];
136 struct req_iterator iter
;
142 switch (scmrq
->cluster
.state
) {
144 scmrq
->cluster
.state
= CLUSTER_READ
;
148 msb
->oc
= MSB_OC_READ
;
149 msb
->flags
= MSB_FLAG_IDA
;
150 msb
->blk_count
= write_cluster_size
;
152 addr
= scmdev
->address
+ ((u64
) blk_rq_pos(req
) << 9);
153 msb
->scm_addr
= round_down(addr
, CLUSTER_SIZE
);
156 round_down(addr
+ (u64
) blk_rq_bytes(req
) - 1,
158 msb
->blk_count
= 2 * write_cluster_size
;
160 aidaw
= scm_aidaw_fetch(scmrq
, msb
->blk_count
* PAGE_SIZE
);
164 scmrq
->aob
->request
.msb_count
= 1;
165 msb
->data_addr
= (u64
) aidaw
;
166 for (i
= 0; i
< msb
->blk_count
; i
++) {
167 aidaw
->data_addr
= (u64
) scmrq
->cluster
.buf
[i
];
173 aidaw
= (void *) msb
->data_addr
;
174 msb
->oc
= MSB_OC_WRITE
;
176 for (addr
= msb
->scm_addr
;
177 addr
< scmdev
->address
+ ((u64
) blk_rq_pos(req
) << 9);
179 aidaw
->data_addr
= (u64
) scmrq
->cluster
.buf
[i
];
183 rq_for_each_segment(bv
, req
, iter
) {
184 aidaw
->data_addr
= (u64
) page_address(bv
.bv_page
);
188 for (; i
< msb
->blk_count
; i
++) {
189 aidaw
->data_addr
= (u64
) scmrq
->cluster
.buf
[i
];
197 bool scm_need_cluster_request(struct scm_request
*scmrq
)
199 int pos
= scmrq
->aob
->request
.msb_count
;
201 if (rq_data_dir(scmrq
->request
[pos
]) == READ
)
204 return blk_rq_bytes(scmrq
->request
[pos
]) < CLUSTER_SIZE
;
207 /* Called with queue lock held. */
208 void scm_initiate_cluster_request(struct scm_request
*scmrq
)
210 if (scm_prepare_cluster_request(scmrq
))
212 if (eadm_start_aob(scmrq
->aob
))
216 scm_request_requeue(scmrq
);
219 bool scm_test_cluster_request(struct scm_request
*scmrq
)
221 return scmrq
->cluster
.state
!= CLUSTER_NONE
;
224 void scm_cluster_request_irq(struct scm_request
*scmrq
)
226 struct scm_blk_dev
*bdev
= scmrq
->bdev
;
229 switch (scmrq
->cluster
.state
) {
235 scm_request_finish(scmrq
);
238 scmrq
->cluster
.state
= CLUSTER_WRITE
;
239 spin_lock_irqsave(&bdev
->rq_lock
, flags
);
240 scm_initiate_cluster_request(scmrq
);
241 spin_unlock_irqrestore(&bdev
->rq_lock
, flags
);
244 scm_request_finish(scmrq
);
249 bool scm_cluster_size_valid(void)
251 if (write_cluster_size
== 1 || write_cluster_size
> 128)
254 return !(write_cluster_size
& (write_cluster_size
- 1));