aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>2016-10-14 08:34:51 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2016-12-14 10:33:39 -0500
commite47de21dd35bad6d1e71482a66699cd04e83ea40 (patch)
tree1089dd285e8cde50690b546db76285efa198b8cc
parentb886a9d1560d6c7d5d58344b16f53ab2cba5b666 (diff)
s390/zcrypt: Fixed attrition of AP adapters and domains
Currently the first eligible AP adapter respectively domain will be selected to service requests. In case of sequential workload, the very same adapter/domain will be used. The adapter/domain selection algorithm now considers the completed transactions per adaper/domain and therefore ensures a homogeneous utilization. Signed-off-by: Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/crypto/ap_bus.h3
-rw-r--r--drivers/s390/crypto/ap_card.c4
-rw-r--r--drivers/s390/crypto/ap_queue.c1
-rw-r--r--drivers/s390/crypto/zcrypt_api.c63
4 files changed, 47 insertions, 24 deletions
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index 54b17e142792..4dc7c88fb054 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -195,6 +195,7 @@ struct ap_card {
195 unsigned int functions; /* AP device function bitfield. */ 195 unsigned int functions; /* AP device function bitfield. */
196 int queue_depth; /* AP queue depth.*/ 196 int queue_depth; /* AP queue depth.*/
197 int id; /* AP card number. */ 197 int id; /* AP card number. */
198 atomic_t total_request_count; /* # requests ever for this AP device.*/
198}; 199};
199 200
200#define to_ap_card(x) container_of((x), struct ap_card, ap_dev.device) 201#define to_ap_card(x) container_of((x), struct ap_card, ap_dev.device)
@@ -211,7 +212,7 @@ struct ap_queue {
211 enum ap_state state; /* State of the AP device. */ 212 enum ap_state state; /* State of the AP device. */
212 int pendingq_count; /* # requests on pendingq list. */ 213 int pendingq_count; /* # requests on pendingq list. */
213 int requestq_count; /* # requests on requestq list. */ 214 int requestq_count; /* # requests on requestq list. */
214 int total_request_count; /* # requests ever for this AP device. */ 215 int total_request_count; /* # requests ever for this AP device.*/
215 int request_timeout; /* Request timout in jiffies. */ 216 int request_timeout; /* Request timout in jiffies. */
216 struct timer_list timeout; /* Timer for request timeouts. */ 217 struct timer_list timeout; /* Timer for request timeouts. */
217 struct list_head pendingq; /* List of message sent to AP queue. */ 218 struct list_head pendingq; /* List of message sent to AP queue. */
diff --git a/drivers/s390/crypto/ap_card.c b/drivers/s390/crypto/ap_card.c
index 731dc0dbfb75..0110d44172a3 100644
--- a/drivers/s390/crypto/ap_card.c
+++ b/drivers/s390/crypto/ap_card.c
@@ -63,13 +63,11 @@ static ssize_t ap_request_count_show(struct device *dev,
63 char *buf) 63 char *buf)
64{ 64{
65 struct ap_card *ac = to_ap_card(dev); 65 struct ap_card *ac = to_ap_card(dev);
66 struct ap_queue *aq;
67 unsigned int req_cnt; 66 unsigned int req_cnt;
68 67
69 req_cnt = 0; 68 req_cnt = 0;
70 spin_lock_bh(&ap_list_lock); 69 spin_lock_bh(&ap_list_lock);
71 for_each_ap_queue(aq, ac) 70 req_cnt = atomic_read(&ac->total_request_count);
72 req_cnt += aq->total_request_count;
73 spin_unlock_bh(&ap_list_lock); 71 spin_unlock_bh(&ap_list_lock);
74 return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt); 72 return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt);
75} 73}
diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c
index 8f95a071b670..b58a917dc510 100644
--- a/drivers/s390/crypto/ap_queue.c
+++ b/drivers/s390/crypto/ap_queue.c
@@ -625,6 +625,7 @@ void ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg)
625 list_add_tail(&ap_msg->list, &aq->requestq); 625 list_add_tail(&ap_msg->list, &aq->requestq);
626 aq->requestq_count++; 626 aq->requestq_count++;
627 aq->total_request_count++; 627 aq->total_request_count++;
628 atomic_inc(&aq->card->total_request_count);
628 /* Send/receive as many request from the queue as possible. */ 629 /* Send/receive as many request from the queue as possible. */
629 ap_wait(ap_sm_event_loop(aq, AP_EVENT_POLL)); 630 ap_wait(ap_sm_event_loop(aq, AP_EVENT_POLL));
630 spin_unlock_bh(&aq->lock); 631 spin_unlock_bh(&aq->lock);
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 403af9d1ebde..c7b5e70f2938 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -188,6 +188,34 @@ static inline void zcrypt_drop_queue(struct zcrypt_card *zc,
188 module_put(mod); 188 module_put(mod);
189} 189}
190 190
191static inline bool zcrypt_card_compare(struct zcrypt_card *zc,
192 struct zcrypt_card *pref_zc,
193 unsigned weight, unsigned pref_weight)
194{
195 if (!pref_zc)
196 return 0;
197 weight += atomic_read(&zc->load);
198 pref_weight += atomic_read(&pref_zc->load);
199 if (weight == pref_weight)
200 return atomic_read(&zc->card->total_request_count) >
201 atomic_read(&pref_zc->card->total_request_count);
202 return weight > pref_weight;
203}
204
205static inline bool zcrypt_queue_compare(struct zcrypt_queue *zq,
206 struct zcrypt_queue *pref_zq,
207 unsigned weight, unsigned pref_weight)
208{
209 if (!pref_zq)
210 return 0;
211 weight += atomic_read(&zq->load);
212 pref_weight += atomic_read(&pref_zq->load);
213 if (weight == pref_weight)
214 return &zq->queue->total_request_count >
215 &pref_zq->queue->total_request_count;
216 return weight > pref_weight;
217}
218
191/* 219/*
192 * zcrypt ioctls. 220 * zcrypt ioctls.
193 */ 221 */
@@ -225,15 +253,14 @@ static long zcrypt_rsa_modexpo(struct ica_rsa_modexpo *mex)
225 continue; 253 continue;
226 /* get weight index of the card device */ 254 /* get weight index of the card device */
227 weight = zc->speed_rating[func_code]; 255 weight = zc->speed_rating[func_code];
228 if (pref_zc && atomic_read(&zc->load) + weight >= 256 if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight))
229 atomic_read(&pref_zc->load) + pref_weight)
230 continue; 257 continue;
231 for_each_zcrypt_queue(zq, zc) { 258 for_each_zcrypt_queue(zq, zc) {
232 /* check if device is online and eligible */ 259 /* check if device is online and eligible */
233 if (!zq->online) 260 if (!zq->online)
234 continue; 261 continue;
235 if (pref_zq && atomic_read(&zq->load) + weight >= 262 if (zcrypt_queue_compare(zq, pref_zq,
236 atomic_read(&pref_zq->load) + pref_weight) 263 weight, pref_weight))
237 continue; 264 continue;
238 pref_zc = zc; 265 pref_zc = zc;
239 pref_zq = zq; 266 pref_zq = zq;
@@ -289,15 +316,14 @@ static long zcrypt_rsa_crt(struct ica_rsa_modexpo_crt *crt)
289 continue; 316 continue;
290 /* get weight index of the card device */ 317 /* get weight index of the card device */
291 weight = zc->speed_rating[func_code]; 318 weight = zc->speed_rating[func_code];
292 if (pref_zc && atomic_read(&zc->load) + weight >= 319 if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight))
293 atomic_read(&pref_zc->load) + pref_weight)
294 continue; 320 continue;
295 for_each_zcrypt_queue(zq, zc) { 321 for_each_zcrypt_queue(zq, zc) {
296 /* check if device is online and eligible */ 322 /* check if device is online and eligible */
297 if (!zq->online) 323 if (!zq->online)
298 continue; 324 continue;
299 if (pref_zq && atomic_read(&zq->load) + weight >= 325 if (zcrypt_queue_compare(zq, pref_zq,
300 atomic_read(&pref_zq->load) + pref_weight) 326 weight, pref_weight))
301 continue; 327 continue;
302 pref_zc = zc; 328 pref_zc = zc;
303 pref_zq = zq; 329 pref_zq = zq;
@@ -346,8 +372,7 @@ static long zcrypt_send_cprb(struct ica_xcRB *xcRB)
346 continue; 372 continue;
347 /* get weight index of the card device */ 373 /* get weight index of the card device */
348 weight = speed_idx_cca(func_code) * zc->speed_rating[SECKEY]; 374 weight = speed_idx_cca(func_code) * zc->speed_rating[SECKEY];
349 if (pref_zc && atomic_read(&zc->load) + weight >= 375 if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight))
350 atomic_read(&pref_zc->load) + pref_weight)
351 continue; 376 continue;
352 for_each_zcrypt_queue(zq, zc) { 377 for_each_zcrypt_queue(zq, zc) {
353 /* check if device is online and eligible */ 378 /* check if device is online and eligible */
@@ -355,8 +380,8 @@ static long zcrypt_send_cprb(struct ica_xcRB *xcRB)
355 ((*domain != (unsigned short) AUTOSELECT) && 380 ((*domain != (unsigned short) AUTOSELECT) &&
356 (*domain != AP_QID_QUEUE(zq->queue->qid)))) 381 (*domain != AP_QID_QUEUE(zq->queue->qid))))
357 continue; 382 continue;
358 if (pref_zq && atomic_read(&zq->load) + weight >= 383 if (zcrypt_queue_compare(zq, pref_zq,
359 atomic_read(&pref_zq->load) + pref_weight) 384 weight, pref_weight))
360 continue; 385 continue;
361 pref_zc = zc; 386 pref_zc = zc;
362 pref_zq = zq; 387 pref_zq = zq;
@@ -450,8 +475,7 @@ static long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
450 continue; 475 continue;
451 /* get weight index of the card device */ 476 /* get weight index of the card device */
452 weight = speed_idx_ep11(func_code) * zc->speed_rating[SECKEY]; 477 weight = speed_idx_ep11(func_code) * zc->speed_rating[SECKEY];
453 if (pref_zc && atomic_read(&zc->load) + weight >= 478 if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight))
454 atomic_read(&pref_zc->load) + pref_weight)
455 continue; 479 continue;
456 for_each_zcrypt_queue(zq, zc) { 480 for_each_zcrypt_queue(zq, zc) {
457 /* check if device is online and eligible */ 481 /* check if device is online and eligible */
@@ -460,8 +484,8 @@ static long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
460 !is_desired_ep11_queue(zq->queue->qid, 484 !is_desired_ep11_queue(zq->queue->qid,
461 target_num, targets))) 485 target_num, targets)))
462 continue; 486 continue;
463 if (pref_zq && atomic_read(&zq->load) + weight >= 487 if (zcrypt_queue_compare(zq, pref_zq,
464 atomic_read(&pref_zq->load) + pref_weight) 488 weight, pref_weight))
465 continue; 489 continue;
466 pref_zc = zc; 490 pref_zc = zc;
467 pref_zq = zq; 491 pref_zq = zq;
@@ -510,15 +534,14 @@ static long zcrypt_rng(char *buffer)
510 continue; 534 continue;
511 /* get weight index of the card device */ 535 /* get weight index of the card device */
512 weight = zc->speed_rating[func_code]; 536 weight = zc->speed_rating[func_code];
513 if (pref_zc && atomic_read(&zc->load) + weight >= 537 if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight))
514 atomic_read(&pref_zc->load) + pref_weight)
515 continue; 538 continue;
516 for_each_zcrypt_queue(zq, zc) { 539 for_each_zcrypt_queue(zq, zc) {
517 /* check if device is online and eligible */ 540 /* check if device is online and eligible */
518 if (!zq->online) 541 if (!zq->online)
519 continue; 542 continue;
520 if (pref_zq && atomic_read(&zq->load) + weight >= 543 if (zcrypt_queue_compare(zq, pref_zq,
521 atomic_read(&pref_zq->load) + pref_weight) 544 weight, pref_weight))
522 continue; 545 continue;
523 pref_zc = zc; 546 pref_zc = zc;
524 pref_zq = zq; 547 pref_zq = zq;