diff options
author | Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com> | 2016-10-14 08:34:51 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2016-12-14 10:33:39 -0500 |
commit | e47de21dd35bad6d1e71482a66699cd04e83ea40 (patch) | |
tree | 1089dd285e8cde50690b546db76285efa198b8cc | |
parent | b886a9d1560d6c7d5d58344b16f53ab2cba5b666 (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.h | 3 | ||||
-rw-r--r-- | drivers/s390/crypto/ap_card.c | 4 | ||||
-rw-r--r-- | drivers/s390/crypto/ap_queue.c | 1 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_api.c | 63 |
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 | ||
191 | static 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 | |||
205 | static 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; |