Commit af512ed0f8a7e6a3c6fd93b2b5882c8e837a6939

Authored by Ralph Wuerthner
Committed by Martin Schwidefsky
1 parent 987ad70a4d

[S390] zcrypt: fix request timeout handling

Under very high load zcrypt requests may timeout while waiting on the
request queue. Modify zcrypt that timeouts are based on crypto adapter
responses. A timeout occurs only if a crypto adapter does not respond
within a given time frame to sumitted requests.

Signed-off-by: Ralph Wuerthner <rwuerthn@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

Showing 6 changed files with 140 additions and 90 deletions Side-by-side Diff

drivers/s390/crypto/ap_bus.c
... ... @@ -43,6 +43,7 @@
43 43 static void ap_poll_timeout(unsigned long);
44 44 static int ap_poll_thread_start(void);
45 45 static void ap_poll_thread_stop(void);
  46 +static void ap_request_timeout(unsigned long);
46 47  
47 48 /**
48 49 * Module description.
... ... @@ -189,6 +190,7 @@
189 190 case AP_RESPONSE_NORMAL:
190 191 return 0;
191 192 case AP_RESPONSE_Q_FULL:
  193 + case AP_RESPONSE_RESET_IN_PROGRESS:
192 194 return -EBUSY;
193 195 default: /* Device is gone. */
194 196 return -ENODEV;
... ... @@ -252,6 +254,8 @@
252 254 if (status.queue_empty)
253 255 return -ENOENT;
254 256 return -EBUSY;
  257 + case AP_RESPONSE_RESET_IN_PROGRESS:
  258 + return -EBUSY;
255 259 default:
256 260 return -ENODEV;
257 261 }
258 262  
... ... @@ -326,11 +330,12 @@
326 330 i = AP_MAX_RESET; /* return with -ENODEV */
327 331 break;
328 332 case AP_RESPONSE_RESET_IN_PROGRESS:
  333 + rc = -EBUSY;
329 334 case AP_RESPONSE_BUSY:
330 335 default:
331 336 break;
332 337 }
333   - if (rc != -ENODEV)
  338 + if (rc != -ENODEV && rc != -EBUSY)
334 339 break;
335 340 if (i < AP_MAX_RESET - 1) {
336 341 udelay(5);
... ... @@ -341,6 +346,40 @@
341 346 }
342 347  
343 348 /**
  349 + * Arm request timeout if a AP device was idle and a new request is submitted.
  350 + */
  351 +static void ap_increase_queue_count(struct ap_device *ap_dev)
  352 +{
  353 + int timeout = ap_dev->drv->request_timeout;
  354 +
  355 + ap_dev->queue_count++;
  356 + if (ap_dev->queue_count == 1) {
  357 + mod_timer(&ap_dev->timeout, jiffies + timeout);
  358 + ap_dev->reset = AP_RESET_ARMED;
  359 + }
  360 +}
  361 +
  362 +/**
  363 + * AP device is still alive, re-schedule request timeout if there are still
  364 + * pending requests.
  365 + */
  366 +static void ap_decrease_queue_count(struct ap_device *ap_dev)
  367 +{
  368 + int timeout = ap_dev->drv->request_timeout;
  369 +
  370 + ap_dev->queue_count--;
  371 + if (ap_dev->queue_count > 0)
  372 + mod_timer(&ap_dev->timeout, jiffies + timeout);
  373 + else
  374 + /**
  375 + * The timeout timer should to be disabled now - since
  376 + * del_timer_sync() is very expensive, we just tell via the
  377 + * reset flag to ignore the pending timeout timer.
  378 + */
  379 + ap_dev->reset = AP_RESET_IGNORE;
  380 +}
  381 +
  382 +/**
344 383 * AP device related attributes.
345 384 */
346 385 static ssize_t ap_hwtype_show(struct device *dev,
... ... @@ -498,6 +537,7 @@
498 537 struct ap_driver *ap_drv = ap_dev->drv;
499 538  
500 539 ap_flush_queue(ap_dev);
  540 + del_timer_sync(&ap_dev->timeout);
501 541 if (ap_drv->remove)
502 542 ap_drv->remove(ap_dev);
503 543 spin_lock_bh(&ap_device_lock);
504 544  
505 545  
506 546  
... ... @@ -759,17 +799,21 @@
759 799 __ap_scan_bus);
760 800 rc = ap_query_queue(qid, &queue_depth, &device_type);
761 801 if (dev) {
  802 + if (rc == -EBUSY) {
  803 + set_current_state(TASK_UNINTERRUPTIBLE);
  804 + schedule_timeout(AP_RESET_TIMEOUT);
  805 + rc = ap_query_queue(qid, &queue_depth,
  806 + &device_type);
  807 + }
762 808 ap_dev = to_ap_dev(dev);
763 809 spin_lock_bh(&ap_dev->lock);
764 810 if (rc || ap_dev->unregistered) {
765 811 spin_unlock_bh(&ap_dev->lock);
766   - put_device(dev);
767 812 device_unregister(dev);
  813 + put_device(dev);
768 814 continue;
769   - } else
770   - spin_unlock_bh(&ap_dev->lock);
771   - }
772   - if (dev) {
  815 + }
  816 + spin_unlock_bh(&ap_dev->lock);
773 817 put_device(dev);
774 818 continue;
775 819 }
... ... @@ -788,6 +832,8 @@
788 832 INIT_LIST_HEAD(&ap_dev->pendingq);
789 833 INIT_LIST_HEAD(&ap_dev->requestq);
790 834 INIT_LIST_HEAD(&ap_dev->list);
  835 + setup_timer(&ap_dev->timeout, ap_request_timeout,
  836 + (unsigned long) ap_dev);
791 837 if (device_type == 0)
792 838 ap_probe_device_type(ap_dev);
793 839 else
... ... @@ -853,7 +899,7 @@
853 899 switch (status.response_code) {
854 900 case AP_RESPONSE_NORMAL:
855 901 atomic_dec(&ap_poll_requests);
856   - ap_dev->queue_count--;
  902 + ap_decrease_queue_count(ap_dev);
857 903 list_for_each_entry(ap_msg, &ap_dev->pendingq, list) {
858 904 if (ap_msg->psmid != ap_dev->reply->psmid)
859 905 continue;
... ... @@ -904,7 +950,7 @@
904 950 switch (status.response_code) {
905 951 case AP_RESPONSE_NORMAL:
906 952 atomic_inc(&ap_poll_requests);
907   - ap_dev->queue_count++;
  953 + ap_increase_queue_count(ap_dev);
908 954 list_move_tail(&ap_msg->list, &ap_dev->pendingq);
909 955 ap_dev->requestq_count--;
910 956 ap_dev->pendingq_count++;
... ... @@ -914,6 +960,7 @@
914 960 *flags |= 2;
915 961 break;
916 962 case AP_RESPONSE_Q_FULL:
  963 + case AP_RESPONSE_RESET_IN_PROGRESS:
917 964 *flags |= 2;
918 965 break;
919 966 case AP_RESPONSE_MESSAGE_TOO_BIG:
920 967  
... ... @@ -960,10 +1007,11 @@
960 1007 list_add_tail(&ap_msg->list, &ap_dev->pendingq);
961 1008 atomic_inc(&ap_poll_requests);
962 1009 ap_dev->pendingq_count++;
963   - ap_dev->queue_count++;
  1010 + ap_increase_queue_count(ap_dev);
964 1011 ap_dev->total_request_count++;
965 1012 break;
966 1013 case AP_RESPONSE_Q_FULL:
  1014 + case AP_RESPONSE_RESET_IN_PROGRESS:
967 1015 list_add_tail(&ap_msg->list, &ap_dev->requestq);
968 1016 ap_dev->requestq_count++;
969 1017 ap_dev->total_request_count++;
... ... @@ -1046,6 +1094,25 @@
1046 1094 }
1047 1095  
1048 1096 /**
  1097 + * Reset a not responding AP device and move all requests from the
  1098 + * pending queue to the request queue.
  1099 + */
  1100 +static void ap_reset(struct ap_device *ap_dev)
  1101 +{
  1102 + int rc;
  1103 +
  1104 + ap_dev->reset = AP_RESET_IGNORE;
  1105 + atomic_sub(ap_dev->queue_count, &ap_poll_requests);
  1106 + ap_dev->queue_count = 0;
  1107 + list_splice_init(&ap_dev->pendingq, &ap_dev->requestq);
  1108 + ap_dev->requestq_count += ap_dev->pendingq_count;
  1109 + ap_dev->pendingq_count = 0;
  1110 + rc = ap_init_queue(ap_dev->qid);
  1111 + if (rc == -ENODEV)
  1112 + ap_dev->unregistered = 1;
  1113 +}
  1114 +
  1115 +/**
1049 1116 * Poll all AP devices on the bus in a round robin fashion. Continue
1050 1117 * polling until bit 2^0 of the control flags is not set. If bit 2^1
1051 1118 * of the control flags has been set arm the poll timer.
... ... @@ -1056,6 +1123,8 @@
1056 1123 if (!ap_dev->unregistered) {
1057 1124 if (ap_poll_queue(ap_dev, flags))
1058 1125 ap_dev->unregistered = 1;
  1126 + if (ap_dev->reset == AP_RESET_DO)
  1127 + ap_reset(ap_dev);
1059 1128 }
1060 1129 spin_unlock(&ap_dev->lock);
1061 1130 return 0;
... ... @@ -1145,6 +1214,17 @@
1145 1214 ap_poll_kthread = NULL;
1146 1215 }
1147 1216 mutex_unlock(&ap_poll_thread_mutex);
  1217 +}
  1218 +
  1219 +/**
  1220 + * Handling of request timeouts
  1221 + */
  1222 +static void ap_request_timeout(unsigned long data)
  1223 +{
  1224 + struct ap_device *ap_dev = (struct ap_device *) data;
  1225 +
  1226 + if (ap_dev->reset == AP_RESET_ARMED)
  1227 + ap_dev->reset = AP_RESET_DO;
1148 1228 }
1149 1229  
1150 1230 static void ap_reset_domain(void)
drivers/s390/crypto/ap_bus.h
... ... @@ -33,6 +33,7 @@
33 33 #define AP_DEVICES 64 /* Number of AP devices. */
34 34 #define AP_DOMAINS 16 /* Number of AP domains. */
35 35 #define AP_MAX_RESET 90 /* Maximum number of resets. */
  36 +#define AP_RESET_TIMEOUT (HZ/2) /* Time in ticks for reset timeouts. */
36 37 #define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */
37 38 #define AP_POLL_TIME 1 /* Time in ticks between receive polls. */
38 39  
... ... @@ -83,6 +84,13 @@
83 84 #define AP_DEVICE_TYPE_CEX2A 6
84 85 #define AP_DEVICE_TYPE_CEX2C 7
85 86  
  87 +/**
  88 + * AP reset flag states
  89 + */
  90 +#define AP_RESET_IGNORE 0 /* request timeout will be ignored */
  91 +#define AP_RESET_ARMED 1 /* request timeout timer is active */
  92 +#define AP_RESET_DO 2 /* AP reset required */
  93 +
86 94 struct ap_device;
87 95 struct ap_message;
88 96  
... ... @@ -95,6 +103,7 @@
95 103 /* receive is called from tasklet context */
96 104 void (*receive)(struct ap_device *, struct ap_message *,
97 105 struct ap_message *);
  106 + int request_timeout; /* request timeout in jiffies */
98 107 };
99 108  
100 109 #define to_ap_drv(x) container_of((x), struct ap_driver, driver)
... ... @@ -112,6 +121,8 @@
112 121 int queue_depth; /* AP queue depth.*/
113 122 int device_type; /* AP device type. */
114 123 int unregistered; /* marks AP device as unregistered */
  124 + struct timer_list timeout; /* Timer for request timeouts. */
  125 + int reset; /* Reset required after req. timeout. */
115 126  
116 127 int queue_count; /* # messages currently on AP queue. */
117 128  
drivers/s390/crypto/zcrypt_cex2a.c
... ... @@ -70,6 +70,7 @@
70 70 .remove = zcrypt_cex2a_remove,
71 71 .receive = zcrypt_cex2a_receive,
72 72 .ids = zcrypt_cex2a_ids,
  73 + .request_timeout = CEX2A_CLEANUP_TIME,
73 74 };
74 75  
75 76 /**
76 77  
77 78  
... ... @@ -306,18 +307,13 @@
306 307 goto out_free;
307 308 init_completion(&work);
308 309 ap_queue_message(zdev->ap_dev, &ap_msg);
309   - rc = wait_for_completion_interruptible_timeout(
310   - &work, CEX2A_CLEANUP_TIME);
311   - if (rc > 0)
  310 + rc = wait_for_completion_interruptible(&work);
  311 + if (rc == 0)
312 312 rc = convert_response(zdev, &ap_msg, mex->outputdata,
313 313 mex->outputdatalength);
314   - else {
315   - /* Signal pending or message timed out. */
  314 + else
  315 + /* Signal pending. */
316 316 ap_cancel_message(zdev->ap_dev, &ap_msg);
317   - if (rc == 0)
318   - /* Message timed out. */
319   - rc = -ETIME;
320   - }
321 317 out_free:
322 318 kfree(ap_msg.message);
323 319 return rc;
324 320  
325 321  
... ... @@ -348,18 +344,13 @@
348 344 goto out_free;
349 345 init_completion(&work);
350 346 ap_queue_message(zdev->ap_dev, &ap_msg);
351   - rc = wait_for_completion_interruptible_timeout(
352   - &work, CEX2A_CLEANUP_TIME);
353   - if (rc > 0)
  347 + rc = wait_for_completion_interruptible(&work);
  348 + if (rc == 0)
354 349 rc = convert_response(zdev, &ap_msg, crt->outputdata,
355 350 crt->outputdatalength);
356   - else {
357   - /* Signal pending or message timed out. */
  351 + else
  352 + /* Signal pending. */
358 353 ap_cancel_message(zdev->ap_dev, &ap_msg);
359   - if (rc == 0)
360   - /* Message timed out. */
361   - rc = -ETIME;
362   - }
363 354 out_free:
364 355 kfree(ap_msg.message);
365 356 return rc;
drivers/s390/crypto/zcrypt_pcica.c
... ... @@ -70,6 +70,7 @@
70 70 .remove = zcrypt_pcica_remove,
71 71 .receive = zcrypt_pcica_receive,
72 72 .ids = zcrypt_pcica_ids,
  73 + .request_timeout = PCICA_CLEANUP_TIME,
73 74 };
74 75  
75 76 /**
76 77  
77 78  
... ... @@ -290,18 +291,13 @@
290 291 goto out_free;
291 292 init_completion(&work);
292 293 ap_queue_message(zdev->ap_dev, &ap_msg);
293   - rc = wait_for_completion_interruptible_timeout(
294   - &work, PCICA_CLEANUP_TIME);
295   - if (rc > 0)
  294 + rc = wait_for_completion_interruptible(&work);
  295 + if (rc == 0)
296 296 rc = convert_response(zdev, &ap_msg, mex->outputdata,
297 297 mex->outputdatalength);
298   - else {
299   - /* Signal pending or message timed out. */
  298 + else
  299 + /* Signal pending. */
300 300 ap_cancel_message(zdev->ap_dev, &ap_msg);
301   - if (rc == 0)
302   - /* Message timed out. */
303   - rc = -ETIME;
304   - }
305 301 out_free:
306 302 kfree(ap_msg.message);
307 303 return rc;
308 304  
309 305  
... ... @@ -332,18 +328,13 @@
332 328 goto out_free;
333 329 init_completion(&work);
334 330 ap_queue_message(zdev->ap_dev, &ap_msg);
335   - rc = wait_for_completion_interruptible_timeout(
336   - &work, PCICA_CLEANUP_TIME);
337   - if (rc > 0)
  331 + rc = wait_for_completion_interruptible(&work);
  332 + if (rc == 0)
338 333 rc = convert_response(zdev, &ap_msg, crt->outputdata,
339 334 crt->outputdatalength);
340   - else {
341   - /* Signal pending or message timed out. */
  335 + else
  336 + /* Signal pending. */
342 337 ap_cancel_message(zdev->ap_dev, &ap_msg);
343   - if (rc == 0)
344   - /* Message timed out. */
345   - rc = -ETIME;
346   - }
347 338 out_free:
348 339 kfree(ap_msg.message);
349 340 return rc;
drivers/s390/crypto/zcrypt_pcicc.c
... ... @@ -82,6 +82,7 @@
82 82 .remove = zcrypt_pcicc_remove,
83 83 .receive = zcrypt_pcicc_receive,
84 84 .ids = zcrypt_pcicc_ids,
  85 + .request_timeout = PCICC_CLEANUP_TIME,
85 86 };
86 87  
87 88 /**
88 89  
89 90  
... ... @@ -501,18 +502,13 @@
501 502 goto out_free;
502 503 init_completion(&work);
503 504 ap_queue_message(zdev->ap_dev, &ap_msg);
504   - rc = wait_for_completion_interruptible_timeout(
505   - &work, PCICC_CLEANUP_TIME);
506   - if (rc > 0)
  505 + rc = wait_for_completion_interruptible(&work);
  506 + if (rc == 0)
507 507 rc = convert_response(zdev, &ap_msg, mex->outputdata,
508 508 mex->outputdatalength);
509   - else {
510   - /* Signal pending or message timed out. */
  509 + else
  510 + /* Signal pending. */
511 511 ap_cancel_message(zdev->ap_dev, &ap_msg);
512   - if (rc == 0)
513   - /* Message timed out. */
514   - rc = -ETIME;
515   - }
516 512 out_free:
517 513 free_page((unsigned long) ap_msg.message);
518 514 return rc;
519 515  
520 516  
... ... @@ -544,18 +540,13 @@
544 540 goto out_free;
545 541 init_completion(&work);
546 542 ap_queue_message(zdev->ap_dev, &ap_msg);
547   - rc = wait_for_completion_interruptible_timeout(
548   - &work, PCICC_CLEANUP_TIME);
549   - if (rc > 0)
  543 + rc = wait_for_completion_interruptible(&work);
  544 + if (rc == 0)
550 545 rc = convert_response(zdev, &ap_msg, crt->outputdata,
551 546 crt->outputdatalength);
552   - else {
553   - /* Signal pending or message timed out. */
  547 + else
  548 + /* Signal pending. */
554 549 ap_cancel_message(zdev->ap_dev, &ap_msg);
555   - if (rc == 0)
556   - /* Message timed out. */
557   - rc = -ETIME;
558   - }
559 550 out_free:
560 551 free_page((unsigned long) ap_msg.message);
561 552 return rc;
drivers/s390/crypto/zcrypt_pcixcc.c
... ... @@ -93,6 +93,7 @@
93 93 .remove = zcrypt_pcixcc_remove,
94 94 .receive = zcrypt_pcixcc_receive,
95 95 .ids = zcrypt_pcixcc_ids,
  96 + .request_timeout = PCIXCC_CLEANUP_TIME,
96 97 };
97 98  
98 99 /**
99 100  
100 101  
... ... @@ -641,18 +642,13 @@
641 642 goto out_free;
642 643 init_completion(&resp_type.work);
643 644 ap_queue_message(zdev->ap_dev, &ap_msg);
644   - rc = wait_for_completion_interruptible_timeout(
645   - &resp_type.work, PCIXCC_CLEANUP_TIME);
646   - if (rc > 0)
  645 + rc = wait_for_completion_interruptible(&resp_type.work);
  646 + if (rc == 0)
647 647 rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
648 648 mex->outputdatalength);
649   - else {
650   - /* Signal pending or message timed out. */
  649 + else
  650 + /* Signal pending. */
651 651 ap_cancel_message(zdev->ap_dev, &ap_msg);
652   - if (rc == 0)
653   - /* Message timed out. */
654   - rc = -ETIME;
655   - }
656 652 out_free:
657 653 free_page((unsigned long) ap_msg.message);
658 654 return rc;
659 655  
660 656  
... ... @@ -685,18 +681,13 @@
685 681 goto out_free;
686 682 init_completion(&resp_type.work);
687 683 ap_queue_message(zdev->ap_dev, &ap_msg);
688   - rc = wait_for_completion_interruptible_timeout(
689   - &resp_type.work, PCIXCC_CLEANUP_TIME);
690   - if (rc > 0)
  684 + rc = wait_for_completion_interruptible(&resp_type.work);
  685 + if (rc == 0)
691 686 rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
692 687 crt->outputdatalength);
693   - else {
694   - /* Signal pending or message timed out. */
  688 + else
  689 + /* Signal pending. */
695 690 ap_cancel_message(zdev->ap_dev, &ap_msg);
696   - if (rc == 0)
697   - /* Message timed out. */
698   - rc = -ETIME;
699   - }
700 691 out_free:
701 692 free_page((unsigned long) ap_msg.message);
702 693 return rc;
703 694  
704 695  
... ... @@ -729,17 +720,12 @@
729 720 goto out_free;
730 721 init_completion(&resp_type.work);
731 722 ap_queue_message(zdev->ap_dev, &ap_msg);
732   - rc = wait_for_completion_interruptible_timeout(
733   - &resp_type.work, PCIXCC_CLEANUP_TIME);
734   - if (rc > 0)
  723 + rc = wait_for_completion_interruptible(&resp_type.work);
  724 + if (rc == 0)
735 725 rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
736   - else {
737   - /* Signal pending or message timed out. */
  726 + else
  727 + /* Signal pending. */
738 728 ap_cancel_message(zdev->ap_dev, &ap_msg);
739   - if (rc == 0)
740   - /* Message timed out. */
741   - rc = -ETIME;
742   - }
743 729 out_free:
744 730 memset(ap_msg.message, 0x0, ap_msg.length);
745 731 kfree(ap_msg.message);