aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/block/scm_blk.c48
-rw-r--r--drivers/s390/block/scm_blk.h3
2 files changed, 34 insertions, 17 deletions
diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c
index cd27cb92ac6d..75d9896deccb 100644
--- a/drivers/s390/block/scm_blk.c
+++ b/drivers/s390/block/scm_blk.c
@@ -25,10 +25,14 @@ static mempool_t *aidaw_pool;
25static DEFINE_SPINLOCK(list_lock); 25static DEFINE_SPINLOCK(list_lock);
26static LIST_HEAD(inactive_requests); 26static LIST_HEAD(inactive_requests);
27static unsigned int nr_requests = 64; 27static unsigned int nr_requests = 64;
28static unsigned int nr_requests_per_io = 8;
28static atomic_t nr_devices = ATOMIC_INIT(0); 29static atomic_t nr_devices = ATOMIC_INIT(0);
29module_param(nr_requests, uint, S_IRUGO); 30module_param(nr_requests, uint, S_IRUGO);
30MODULE_PARM_DESC(nr_requests, "Number of parallel requests."); 31MODULE_PARM_DESC(nr_requests, "Number of parallel requests.");
31 32
33module_param(nr_requests_per_io, uint, S_IRUGO);
34MODULE_PARM_DESC(nr_requests_per_io, "Number of requests per IO.");
35
32MODULE_DESCRIPTION("Block driver for s390 storage class memory."); 36MODULE_DESCRIPTION("Block driver for s390 storage class memory.");
33MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL");
34MODULE_ALIAS("scm:scmdev*"); 38MODULE_ALIAS("scm:scmdev*");
@@ -39,6 +43,7 @@ static void __scm_free_rq(struct scm_request *scmrq)
39 43
40 free_page((unsigned long) scmrq->aob); 44 free_page((unsigned long) scmrq->aob);
41 __scm_free_rq_cluster(scmrq); 45 __scm_free_rq_cluster(scmrq);
46 kfree(scmrq->request);
42 kfree(aobrq); 47 kfree(aobrq);
43} 48}
44 49
@@ -69,15 +74,16 @@ static int __scm_alloc_rq(void)
69 74
70 scmrq = (void *) aobrq->data; 75 scmrq = (void *) aobrq->data;
71 scmrq->aob = (void *) get_zeroed_page(GFP_DMA); 76 scmrq->aob = (void *) get_zeroed_page(GFP_DMA);
72 if (!scmrq->aob) { 77 if (!scmrq->aob)
73 __scm_free_rq(scmrq); 78 goto free;
74 return -ENOMEM;
75 }
76 79
77 if (__scm_alloc_rq_cluster(scmrq)) { 80 scmrq->request = kcalloc(nr_requests_per_io, sizeof(scmrq->request[0]),
78 __scm_free_rq(scmrq); 81 GFP_KERNEL);
79 return -ENOMEM; 82 if (!scmrq->request)
80 } 83 goto free;
84
85 if (__scm_alloc_rq_cluster(scmrq))
86 goto free;
81 87
82 INIT_LIST_HEAD(&scmrq->list); 88 INIT_LIST_HEAD(&scmrq->list);
83 spin_lock_irq(&list_lock); 89 spin_lock_irq(&list_lock);
@@ -85,6 +91,9 @@ static int __scm_alloc_rq(void)
85 spin_unlock_irq(&list_lock); 91 spin_unlock_irq(&list_lock);
86 92
87 return 0; 93 return 0;
94free:
95 __scm_free_rq(scmrq);
96 return -ENOMEM;
88} 97}
89 98
90static int scm_alloc_rqs(unsigned int nrqs) 99static int scm_alloc_rqs(unsigned int nrqs)
@@ -122,7 +131,7 @@ static void scm_request_done(struct scm_request *scmrq)
122 u64 aidaw; 131 u64 aidaw;
123 int i; 132 int i;
124 133
125 for (i = 0; i < SCM_RQ_PER_IO && scmrq->request[i]; i++) { 134 for (i = 0; i < nr_requests_per_io && scmrq->request[i]; i++) {
126 msb = &scmrq->aob->msb[i]; 135 msb = &scmrq->aob->msb[i];
127 aidaw = msb->data_addr; 136 aidaw = msb->data_addr;
128 137
@@ -214,7 +223,8 @@ static inline void scm_request_init(struct scm_blk_dev *bdev,
214 struct aob_rq_header *aobrq = to_aobrq(scmrq); 223 struct aob_rq_header *aobrq = to_aobrq(scmrq);
215 struct aob *aob = scmrq->aob; 224 struct aob *aob = scmrq->aob;
216 225
217 memset(scmrq->request, 0, sizeof(scmrq->request)); 226 memset(scmrq->request, 0,
227 nr_requests_per_io * sizeof(scmrq->request[0]));
218 memset(aob, 0, sizeof(*aob)); 228 memset(aob, 0, sizeof(*aob));
219 aobrq->scmdev = bdev->scmdev; 229 aobrq->scmdev = bdev->scmdev;
220 aob->request.cmd_code = ARQB_CMD_MOVE; 230 aob->request.cmd_code = ARQB_CMD_MOVE;
@@ -223,7 +233,7 @@ static inline void scm_request_init(struct scm_blk_dev *bdev,
223 scmrq->retries = 4; 233 scmrq->retries = 4;
224 scmrq->error = 0; 234 scmrq->error = 0;
225 /* We don't use all msbs - place aidaws at the end of the aob page. */ 235 /* We don't use all msbs - place aidaws at the end of the aob page. */
226 scmrq->next_aidaw = (void *) &aob->msb[SCM_RQ_PER_IO]; 236 scmrq->next_aidaw = (void *) &aob->msb[nr_requests_per_io];
227 scm_request_cluster_init(scmrq); 237 scm_request_cluster_init(scmrq);
228} 238}
229 239
@@ -242,7 +252,7 @@ void scm_request_requeue(struct scm_request *scmrq)
242 int i; 252 int i;
243 253
244 scm_release_cluster(scmrq); 254 scm_release_cluster(scmrq);
245 for (i = 0; i < SCM_RQ_PER_IO && scmrq->request[i]; i++) 255 for (i = 0; i < nr_requests_per_io && scmrq->request[i]; i++)
246 blk_requeue_request(bdev->rq, scmrq->request[i]); 256 blk_requeue_request(bdev->rq, scmrq->request[i]);
247 257
248 atomic_dec(&bdev->queued_reqs); 258 atomic_dec(&bdev->queued_reqs);
@@ -256,7 +266,7 @@ void scm_request_finish(struct scm_request *scmrq)
256 int i; 266 int i;
257 267
258 scm_release_cluster(scmrq); 268 scm_release_cluster(scmrq);
259 for (i = 0; i < SCM_RQ_PER_IO && scmrq->request[i]; i++) 269 for (i = 0; i < nr_requests_per_io && scmrq->request[i]; i++)
260 blk_end_request_all(scmrq->request[i], scmrq->error); 270 blk_end_request_all(scmrq->request[i], scmrq->error);
261 271
262 atomic_dec(&bdev->queued_reqs); 272 atomic_dec(&bdev->queued_reqs);
@@ -342,7 +352,7 @@ static void scm_blk_request(struct request_queue *rq)
342 } 352 }
343 blk_start_request(req); 353 blk_start_request(req);
344 354
345 if (scmrq->aob->request.msb_count < SCM_RQ_PER_IO) 355 if (scmrq->aob->request.msb_count < nr_requests_per_io)
346 continue; 356 continue;
347 357
348 if (scm_request_start(scmrq)) 358 if (scm_request_start(scmrq))
@@ -551,11 +561,19 @@ void scm_blk_set_available(struct scm_blk_dev *bdev)
551 spin_unlock_irqrestore(&bdev->lock, flags); 561 spin_unlock_irqrestore(&bdev->lock, flags);
552} 562}
553 563
564static bool __init scm_blk_params_valid(void)
565{
566 if (!nr_requests_per_io || nr_requests_per_io > 64)
567 return false;
568
569 return scm_cluster_size_valid();
570}
571
554static int __init scm_blk_init(void) 572static int __init scm_blk_init(void)
555{ 573{
556 int ret = -EINVAL; 574 int ret = -EINVAL;
557 575
558 if (!scm_cluster_size_valid()) 576 if (!scm_blk_params_valid())
559 goto out; 577 goto out;
560 578
561 ret = register_blkdev(0, "scm"); 579 ret = register_blkdev(0, "scm");
diff --git a/drivers/s390/block/scm_blk.h b/drivers/s390/block/scm_blk.h
index 3dae0a3570ce..09218cdc5129 100644
--- a/drivers/s390/block/scm_blk.h
+++ b/drivers/s390/block/scm_blk.h
@@ -11,7 +11,6 @@
11#include <asm/eadm.h> 11#include <asm/eadm.h>
12 12
13#define SCM_NR_PARTS 8 13#define SCM_NR_PARTS 8
14#define SCM_RQ_PER_IO 8
15#define SCM_QUEUE_DELAY 5 14#define SCM_QUEUE_DELAY 5
16 15
17struct scm_blk_dev { 16struct scm_blk_dev {
@@ -32,7 +31,7 @@ struct scm_blk_dev {
32struct scm_request { 31struct scm_request {
33 struct scm_blk_dev *bdev; 32 struct scm_blk_dev *bdev;
34 struct aidaw *next_aidaw; 33 struct aidaw *next_aidaw;
35 struct request *request[SCM_RQ_PER_IO]; 34 struct request **request;
36 struct aob *aob; 35 struct aob *aob;
37 struct list_head list; 36 struct list_head list;
38 u8 retries; 37 u8 retries;