Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ingo Tuchscherer and committed by
Martin Schwidefsky
e47de21d b886a9d1

+47 -24
+2 -1
drivers/s390/crypto/ap_bus.h
··· 195 195 unsigned int functions; /* AP device function bitfield. */ 196 196 int queue_depth; /* AP queue depth.*/ 197 197 int id; /* AP card number. */ 198 + atomic_t total_request_count; /* # requests ever for this AP device.*/ 198 199 }; 199 200 200 201 #define to_ap_card(x) container_of((x), struct ap_card, ap_dev.device) ··· 212 211 enum ap_state state; /* State of the AP device. */ 213 212 int pendingq_count; /* # requests on pendingq list. */ 214 213 int requestq_count; /* # requests on requestq list. */ 215 - int total_request_count; /* # requests ever for this AP device. */ 214 + int total_request_count; /* # requests ever for this AP device.*/ 216 215 int request_timeout; /* Request timout in jiffies. */ 217 216 struct timer_list timeout; /* Timer for request timeouts. */ 218 217 struct list_head pendingq; /* List of message sent to AP queue. */
+1 -3
drivers/s390/crypto/ap_card.c
··· 63 63 char *buf) 64 64 { 65 65 struct ap_card *ac = to_ap_card(dev); 66 - struct ap_queue *aq; 67 66 unsigned int req_cnt; 68 67 69 68 req_cnt = 0; 70 69 spin_lock_bh(&ap_list_lock); 71 - for_each_ap_queue(aq, ac) 72 - req_cnt += aq->total_request_count; 70 + req_cnt = atomic_read(&ac->total_request_count); 73 71 spin_unlock_bh(&ap_list_lock); 74 72 return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt); 75 73 }
+1
drivers/s390/crypto/ap_queue.c
··· 625 625 list_add_tail(&ap_msg->list, &aq->requestq); 626 626 aq->requestq_count++; 627 627 aq->total_request_count++; 628 + atomic_inc(&aq->card->total_request_count); 628 629 /* Send/receive as many request from the queue as possible. */ 629 630 ap_wait(ap_sm_event_loop(aq, AP_EVENT_POLL)); 630 631 spin_unlock_bh(&aq->lock);
+43 -20
drivers/s390/crypto/zcrypt_api.c
··· 188 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 220 * zcrypt ioctls. 193 221 */ ··· 253 225 continue; 254 226 /* get weight index of the card device */ 255 227 weight = zc->speed_rating[func_code]; 256 - if (pref_zc && atomic_read(&zc->load) + weight >= 257 - atomic_read(&pref_zc->load) + pref_weight) 228 + if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight)) 258 229 continue; 259 230 for_each_zcrypt_queue(zq, zc) { 260 231 /* check if device is online and eligible */ 261 232 if (!zq->online) 262 233 continue; 263 - if (pref_zq && atomic_read(&zq->load) + weight >= 264 - atomic_read(&pref_zq->load) + pref_weight) 234 + if (zcrypt_queue_compare(zq, pref_zq, 235 + weight, pref_weight)) 265 236 continue; 266 237 pref_zc = zc; 267 238 pref_zq = zq; ··· 316 289 continue; 317 290 /* get weight index of the card device */ 318 291 weight = zc->speed_rating[func_code]; 319 - if (pref_zc && atomic_read(&zc->load) + weight >= 320 - atomic_read(&pref_zc->load) + pref_weight) 292 + if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight)) 321 293 continue; 322 294 for_each_zcrypt_queue(zq, zc) { 323 295 /* check if device is online and eligible */ 324 296 if (!zq->online) 325 297 continue; 326 - if (pref_zq && atomic_read(&zq->load) + weight >= 327 - atomic_read(&pref_zq->load) + pref_weight) 298 + if (zcrypt_queue_compare(zq, pref_zq, 299 + weight, pref_weight)) 328 300 continue; 329 301 pref_zc = zc; 330 302 pref_zq = zq; ··· 372 346 continue; 373 347 /* get weight index of the card device */ 374 348 weight = speed_idx_cca(func_code) * zc->speed_rating[SECKEY]; 375 - if (pref_zc && atomic_read(&zc->load) + weight >= 376 - atomic_read(&pref_zc->load) + pref_weight) 349 + if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight)) 377 350 continue; 378 351 for_each_zcrypt_queue(zq, zc) { 379 352 /* check if device is online and eligible */ ··· 380 355 ((*domain != (unsigned short) AUTOSELECT) && 381 356 (*domain != AP_QID_QUEUE(zq->queue->qid)))) 382 357 continue; 383 - if (pref_zq && atomic_read(&zq->load) + weight >= 384 - atomic_read(&pref_zq->load) + pref_weight) 358 + if (zcrypt_queue_compare(zq, pref_zq, 359 + weight, pref_weight)) 385 360 continue; 386 361 pref_zc = zc; 387 362 pref_zq = zq; ··· 475 450 continue; 476 451 /* get weight index of the card device */ 477 452 weight = speed_idx_ep11(func_code) * zc->speed_rating[SECKEY]; 478 - if (pref_zc && atomic_read(&zc->load) + weight >= 479 - atomic_read(&pref_zc->load) + pref_weight) 453 + if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight)) 480 454 continue; 481 455 for_each_zcrypt_queue(zq, zc) { 482 456 /* check if device is online and eligible */ ··· 484 460 !is_desired_ep11_queue(zq->queue->qid, 485 461 target_num, targets))) 486 462 continue; 487 - if (pref_zq && atomic_read(&zq->load) + weight >= 488 - atomic_read(&pref_zq->load) + pref_weight) 463 + if (zcrypt_queue_compare(zq, pref_zq, 464 + weight, pref_weight)) 489 465 continue; 490 466 pref_zc = zc; 491 467 pref_zq = zq; ··· 534 510 continue; 535 511 /* get weight index of the card device */ 536 512 weight = zc->speed_rating[func_code]; 537 - if (pref_zc && atomic_read(&zc->load) + weight >= 538 - atomic_read(&pref_zc->load) + pref_weight) 513 + if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight)) 539 514 continue; 540 515 for_each_zcrypt_queue(zq, zc) { 541 516 /* check if device is online and eligible */ 542 517 if (!zq->online) 543 518 continue; 544 - if (pref_zq && atomic_read(&zq->load) + weight >= 545 - atomic_read(&pref_zq->load) + pref_weight) 519 + if (zcrypt_queue_compare(zq, pref_zq, 520 + weight, pref_weight)) 546 521 continue; 547 522 pref_zc = zc; 548 523 pref_zq = zq;