aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/qdio_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/qdio_main.c')
-rw-r--r--drivers/s390/cio/qdio_main.c108
1 files changed, 67 insertions, 41 deletions
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 4be6e84b9599..88be7b9ea6e1 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -13,6 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/timer.h> 14#include <linux/timer.h>
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/gfp.h>
16#include <asm/atomic.h> 17#include <asm/atomic.h>
17#include <asm/debug.h> 18#include <asm/debug.h>
18#include <asm/qdio.h> 19#include <asm/qdio.h>
@@ -22,7 +23,6 @@
22#include "device.h" 23#include "device.h"
23#include "qdio.h" 24#include "qdio.h"
24#include "qdio_debug.h" 25#include "qdio_debug.h"
25#include "qdio_perf.h"
26 26
27MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>,"\ 27MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>,"\
28 "Jan Glauber <jang@linux.vnet.ibm.com>"); 28 "Jan Glauber <jang@linux.vnet.ibm.com>");
@@ -126,7 +126,7 @@ static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
126 int rc; 126 int rc;
127 127
128 BUG_ON(!q->irq_ptr->sch_token); 128 BUG_ON(!q->irq_ptr->sch_token);
129 qdio_perf_stat_inc(&perf_stats.debug_eqbs_all); 129 qperf_inc(q, eqbs);
130 130
131 if (!q->is_input_q) 131 if (!q->is_input_q)
132 nr += q->irq_ptr->nr_input_qs; 132 nr += q->irq_ptr->nr_input_qs;
@@ -139,7 +139,7 @@ again:
139 * buffers later. 139 * buffers later.
140 */ 140 */
141 if ((ccq == 96) && (count != tmp_count)) { 141 if ((ccq == 96) && (count != tmp_count)) {
142 qdio_perf_stat_inc(&perf_stats.debug_eqbs_incomplete); 142 qperf_inc(q, eqbs_partial);
143 return (count - tmp_count); 143 return (count - tmp_count);
144 } 144 }
145 145
@@ -182,7 +182,7 @@ static int qdio_do_sqbs(struct qdio_q *q, unsigned char state, int start,
182 return 0; 182 return 0;
183 183
184 BUG_ON(!q->irq_ptr->sch_token); 184 BUG_ON(!q->irq_ptr->sch_token);
185 qdio_perf_stat_inc(&perf_stats.debug_sqbs_all); 185 qperf_inc(q, sqbs);
186 186
187 if (!q->is_input_q) 187 if (!q->is_input_q)
188 nr += q->irq_ptr->nr_input_qs; 188 nr += q->irq_ptr->nr_input_qs;
@@ -191,7 +191,7 @@ again:
191 rc = qdio_check_ccq(q, ccq); 191 rc = qdio_check_ccq(q, ccq);
192 if (rc == 1) { 192 if (rc == 1) {
193 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "SQBS again:%2d", ccq); 193 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "SQBS again:%2d", ccq);
194 qdio_perf_stat_inc(&perf_stats.debug_sqbs_incomplete); 194 qperf_inc(q, sqbs_partial);
195 goto again; 195 goto again;
196 } 196 }
197 if (rc < 0) { 197 if (rc < 0) {
@@ -285,7 +285,7 @@ static inline int qdio_siga_sync(struct qdio_q *q, unsigned int output,
285 return 0; 285 return 0;
286 286
287 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-s:%1d", q->nr); 287 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-s:%1d", q->nr);
288 qdio_perf_stat_inc(&perf_stats.siga_sync); 288 qperf_inc(q, siga_sync);
289 289
290 cc = do_siga_sync(q->irq_ptr->schid, output, input); 290 cc = do_siga_sync(q->irq_ptr->schid, output, input);
291 if (cc) 291 if (cc)
@@ -350,7 +350,7 @@ static inline int qdio_siga_input(struct qdio_q *q)
350 int cc; 350 int cc;
351 351
352 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-r:%1d", q->nr); 352 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-r:%1d", q->nr);
353 qdio_perf_stat_inc(&perf_stats.siga_in); 353 qperf_inc(q, siga_read);
354 354
355 cc = do_siga_input(q->irq_ptr->schid, q->mask); 355 cc = do_siga_input(q->irq_ptr->schid, q->mask);
356 if (cc) 356 if (cc)
@@ -382,7 +382,7 @@ static inline void qdio_stop_polling(struct qdio_q *q)
382 return; 382 return;
383 383
384 q->u.in.polling = 0; 384 q->u.in.polling = 0;
385 qdio_perf_stat_inc(&perf_stats.debug_stop_polling); 385 qperf_inc(q, stop_polling);
386 386
387 /* show the card that we are not polling anymore */ 387 /* show the card that we are not polling anymore */
388 if (is_qebsm(q)) { 388 if (is_qebsm(q)) {
@@ -393,6 +393,20 @@ static inline void qdio_stop_polling(struct qdio_q *q)
393 set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT); 393 set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
394} 394}
395 395
396static inline void account_sbals(struct qdio_q *q, int count)
397{
398 int pos = 0;
399
400 q->q_stats.nr_sbal_total += count;
401 if (count == QDIO_MAX_BUFFERS_MASK) {
402 q->q_stats.nr_sbals[7]++;
403 return;
404 }
405 while (count >>= 1)
406 pos++;
407 q->q_stats.nr_sbals[pos]++;
408}
409
396static void announce_buffer_error(struct qdio_q *q, int count) 410static void announce_buffer_error(struct qdio_q *q, int count)
397{ 411{
398 q->qdio_error |= QDIO_ERROR_SLSB_STATE; 412 q->qdio_error |= QDIO_ERROR_SLSB_STATE;
@@ -400,7 +414,7 @@ static void announce_buffer_error(struct qdio_q *q, int count)
400 /* special handling for no target buffer empty */ 414 /* special handling for no target buffer empty */
401 if ((!q->is_input_q && 415 if ((!q->is_input_q &&
402 (q->sbal[q->first_to_check]->element[15].flags & 0xff) == 0x10)) { 416 (q->sbal[q->first_to_check]->element[15].flags & 0xff) == 0x10)) {
403 qdio_perf_stat_inc(&perf_stats.outbound_target_full); 417 qperf_inc(q, target_full);
404 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x", 418 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x",
405 q->first_to_check); 419 q->first_to_check);
406 return; 420 return;
@@ -486,17 +500,24 @@ static int get_inbound_buffer_frontier(struct qdio_q *q)
486 case SLSB_P_INPUT_PRIMED: 500 case SLSB_P_INPUT_PRIMED:
487 inbound_primed(q, count); 501 inbound_primed(q, count);
488 q->first_to_check = add_buf(q->first_to_check, count); 502 q->first_to_check = add_buf(q->first_to_check, count);
489 atomic_sub(count, &q->nr_buf_used); 503 if (atomic_sub(count, &q->nr_buf_used) == 0)
504 qperf_inc(q, inbound_queue_full);
505 if (q->irq_ptr->perf_stat_enabled)
506 account_sbals(q, count);
490 break; 507 break;
491 case SLSB_P_INPUT_ERROR: 508 case SLSB_P_INPUT_ERROR:
492 announce_buffer_error(q, count); 509 announce_buffer_error(q, count);
493 /* process the buffer, the upper layer will take care of it */ 510 /* process the buffer, the upper layer will take care of it */
494 q->first_to_check = add_buf(q->first_to_check, count); 511 q->first_to_check = add_buf(q->first_to_check, count);
495 atomic_sub(count, &q->nr_buf_used); 512 atomic_sub(count, &q->nr_buf_used);
513 if (q->irq_ptr->perf_stat_enabled)
514 account_sbals_error(q, count);
496 break; 515 break;
497 case SLSB_CU_INPUT_EMPTY: 516 case SLSB_CU_INPUT_EMPTY:
498 case SLSB_P_INPUT_NOT_INIT: 517 case SLSB_P_INPUT_NOT_INIT:
499 case SLSB_P_INPUT_ACK: 518 case SLSB_P_INPUT_ACK:
519 if (q->irq_ptr->perf_stat_enabled)
520 q->q_stats.nr_sbal_nop++;
500 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop"); 521 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop");
501 break; 522 break;
502 default: 523 default:
@@ -514,7 +535,7 @@ static int qdio_inbound_q_moved(struct qdio_q *q)
514 535
515 if ((bufnr != q->last_move) || q->qdio_error) { 536 if ((bufnr != q->last_move) || q->qdio_error) {
516 q->last_move = bufnr; 537 q->last_move = bufnr;
517 if (!is_thinint_irq(q->irq_ptr) && !MACHINE_IS_VM) 538 if (!is_thinint_irq(q->irq_ptr) && MACHINE_IS_LPAR)
518 q->u.in.timestamp = get_usecs(); 539 q->u.in.timestamp = get_usecs();
519 return 1; 540 return 1;
520 } else 541 } else
@@ -531,7 +552,7 @@ static inline int qdio_inbound_q_done(struct qdio_q *q)
531 qdio_siga_sync_q(q); 552 qdio_siga_sync_q(q);
532 get_buf_state(q, q->first_to_check, &state, 0); 553 get_buf_state(q, q->first_to_check, &state, 0);
533 554
534 if (state == SLSB_P_INPUT_PRIMED) 555 if (state == SLSB_P_INPUT_PRIMED || state == SLSB_P_INPUT_ERROR)
535 /* more work coming */ 556 /* more work coming */
536 return 0; 557 return 0;
537 558
@@ -566,11 +587,13 @@ static void qdio_kick_handler(struct qdio_q *q)
566 count = sub_buf(end, start); 587 count = sub_buf(end, start);
567 588
568 if (q->is_input_q) { 589 if (q->is_input_q) {
569 qdio_perf_stat_inc(&perf_stats.inbound_handler); 590 qperf_inc(q, inbound_handler);
570 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count); 591 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count);
571 } else 592 } else {
593 qperf_inc(q, outbound_handler);
572 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x", 594 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x",
573 start, count); 595 start, count);
596 }
574 597
575 q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count, 598 q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
576 q->irq_ptr->int_parm); 599 q->irq_ptr->int_parm);
@@ -582,24 +605,28 @@ static void qdio_kick_handler(struct qdio_q *q)
582 605
583static void __qdio_inbound_processing(struct qdio_q *q) 606static void __qdio_inbound_processing(struct qdio_q *q)
584{ 607{
585 qdio_perf_stat_inc(&perf_stats.tasklet_inbound); 608 qperf_inc(q, tasklet_inbound);
586again: 609again:
587 if (!qdio_inbound_q_moved(q)) 610 if (!qdio_inbound_q_moved(q))
588 return; 611 return;
589 612
590 qdio_kick_handler(q); 613 qdio_kick_handler(q);
591 614
592 if (!qdio_inbound_q_done(q)) 615 if (!qdio_inbound_q_done(q)) {
593 /* means poll time is not yet over */ 616 /* means poll time is not yet over */
617 qperf_inc(q, tasklet_inbound_resched);
594 goto again; 618 goto again;
619 }
595 620
596 qdio_stop_polling(q); 621 qdio_stop_polling(q);
597 /* 622 /*
598 * We need to check again to not lose initiative after 623 * We need to check again to not lose initiative after
599 * resetting the ACK state. 624 * resetting the ACK state.
600 */ 625 */
601 if (!qdio_inbound_q_done(q)) 626 if (!qdio_inbound_q_done(q)) {
627 qperf_inc(q, tasklet_inbound_resched2);
602 goto again; 628 goto again;
629 }
603} 630}
604 631
605void qdio_inbound_processing(unsigned long data) 632void qdio_inbound_processing(unsigned long data)
@@ -638,15 +665,21 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
638 665
639 atomic_sub(count, &q->nr_buf_used); 666 atomic_sub(count, &q->nr_buf_used);
640 q->first_to_check = add_buf(q->first_to_check, count); 667 q->first_to_check = add_buf(q->first_to_check, count);
668 if (q->irq_ptr->perf_stat_enabled)
669 account_sbals(q, count);
641 break; 670 break;
642 case SLSB_P_OUTPUT_ERROR: 671 case SLSB_P_OUTPUT_ERROR:
643 announce_buffer_error(q, count); 672 announce_buffer_error(q, count);
644 /* process the buffer, the upper layer will take care of it */ 673 /* process the buffer, the upper layer will take care of it */
645 q->first_to_check = add_buf(q->first_to_check, count); 674 q->first_to_check = add_buf(q->first_to_check, count);
646 atomic_sub(count, &q->nr_buf_used); 675 atomic_sub(count, &q->nr_buf_used);
676 if (q->irq_ptr->perf_stat_enabled)
677 account_sbals_error(q, count);
647 break; 678 break;
648 case SLSB_CU_OUTPUT_PRIMED: 679 case SLSB_CU_OUTPUT_PRIMED:
649 /* the adapter has not fetched the output yet */ 680 /* the adapter has not fetched the output yet */
681 if (q->irq_ptr->perf_stat_enabled)
682 q->q_stats.nr_sbal_nop++;
650 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out primed:%1d", q->nr); 683 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out primed:%1d", q->nr);
651 break; 684 break;
652 case SLSB_P_OUTPUT_NOT_INIT: 685 case SLSB_P_OUTPUT_NOT_INIT:
@@ -687,7 +720,7 @@ static int qdio_kick_outbound_q(struct qdio_q *q)
687 return 0; 720 return 0;
688 721
689 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr); 722 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr);
690 qdio_perf_stat_inc(&perf_stats.siga_out); 723 qperf_inc(q, siga_write);
691 724
692 cc = qdio_siga_output(q, &busy_bit); 725 cc = qdio_siga_output(q, &busy_bit);
693 switch (cc) { 726 switch (cc) {
@@ -710,7 +743,7 @@ static int qdio_kick_outbound_q(struct qdio_q *q)
710 743
711static void __qdio_outbound_processing(struct qdio_q *q) 744static void __qdio_outbound_processing(struct qdio_q *q)
712{ 745{
713 qdio_perf_stat_inc(&perf_stats.tasklet_outbound); 746 qperf_inc(q, tasklet_outbound);
714 BUG_ON(atomic_read(&q->nr_buf_used) < 0); 747 BUG_ON(atomic_read(&q->nr_buf_used) < 0);
715 748
716 if (qdio_outbound_q_moved(q)) 749 if (qdio_outbound_q_moved(q))
@@ -738,12 +771,9 @@ static void __qdio_outbound_processing(struct qdio_q *q)
738 */ 771 */
739 if (qdio_outbound_q_done(q)) 772 if (qdio_outbound_q_done(q))
740 del_timer(&q->u.out.timer); 773 del_timer(&q->u.out.timer);
741 else { 774 else
742 if (!timer_pending(&q->u.out.timer)) { 775 if (!timer_pending(&q->u.out.timer))
743 mod_timer(&q->u.out.timer, jiffies + 10 * HZ); 776 mod_timer(&q->u.out.timer, jiffies + 10 * HZ);
744 qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer);
745 }
746 }
747 return; 777 return;
748 778
749sched: 779sched:
@@ -783,7 +813,7 @@ static inline void qdio_check_outbound_after_thinint(struct qdio_q *q)
783 813
784static void __tiqdio_inbound_processing(struct qdio_q *q) 814static void __tiqdio_inbound_processing(struct qdio_q *q)
785{ 815{
786 qdio_perf_stat_inc(&perf_stats.thinint_inbound); 816 qperf_inc(q, tasklet_inbound);
787 qdio_sync_after_thinint(q); 817 qdio_sync_after_thinint(q);
788 818
789 /* 819 /*
@@ -798,7 +828,7 @@ static void __tiqdio_inbound_processing(struct qdio_q *q)
798 qdio_kick_handler(q); 828 qdio_kick_handler(q);
799 829
800 if (!qdio_inbound_q_done(q)) { 830 if (!qdio_inbound_q_done(q)) {
801 qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop); 831 qperf_inc(q, tasklet_inbound_resched);
802 if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) { 832 if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) {
803 tasklet_schedule(&q->tasklet); 833 tasklet_schedule(&q->tasklet);
804 return; 834 return;
@@ -811,7 +841,7 @@ static void __tiqdio_inbound_processing(struct qdio_q *q)
811 * resetting the ACK state. 841 * resetting the ACK state.
812 */ 842 */
813 if (!qdio_inbound_q_done(q)) { 843 if (!qdio_inbound_q_done(q)) {
814 qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2); 844 qperf_inc(q, tasklet_inbound_resched2);
815 if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) 845 if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
816 tasklet_schedule(&q->tasklet); 846 tasklet_schedule(&q->tasklet);
817 } 847 }
@@ -850,8 +880,6 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
850 if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED)) 880 if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
851 return; 881 return;
852 882
853 qdio_perf_stat_inc(&perf_stats.pci_int);
854
855 for_each_input_queue(irq_ptr, q, i) 883 for_each_input_queue(irq_ptr, q, i)
856 tasklet_schedule(&q->tasklet); 884 tasklet_schedule(&q->tasklet);
857 885
@@ -922,8 +950,6 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
922 struct qdio_irq *irq_ptr = cdev->private->qdio_data; 950 struct qdio_irq *irq_ptr = cdev->private->qdio_data;
923 int cstat, dstat; 951 int cstat, dstat;
924 952
925 qdio_perf_stat_inc(&perf_stats.qdio_int);
926
927 if (!intparm || !irq_ptr) { 953 if (!intparm || !irq_ptr) {
928 DBF_ERROR("qint:%4x", cdev->private->schid.sch_no); 954 DBF_ERROR("qint:%4x", cdev->private->schid.sch_no);
929 return; 955 return;
@@ -962,6 +988,8 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
962 qdio_handle_activate_check(cdev, intparm, cstat, 988 qdio_handle_activate_check(cdev, intparm, cstat,
963 dstat); 989 dstat);
964 break; 990 break;
991 case QDIO_IRQ_STATE_STOPPED:
992 break;
965 default: 993 default:
966 WARN_ON(1); 994 WARN_ON(1);
967 } 995 }
@@ -1382,6 +1410,8 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags,
1382{ 1410{
1383 int used, diff; 1411 int used, diff;
1384 1412
1413 qperf_inc(q, inbound_call);
1414
1385 if (!q->u.in.polling) 1415 if (!q->u.in.polling)
1386 goto set; 1416 goto set;
1387 1417
@@ -1437,14 +1467,16 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
1437 unsigned char state; 1467 unsigned char state;
1438 int used, rc = 0; 1468 int used, rc = 0;
1439 1469
1440 qdio_perf_stat_inc(&perf_stats.outbound_handler); 1470 qperf_inc(q, outbound_call);
1441 1471
1442 count = set_buf_states(q, bufnr, SLSB_CU_OUTPUT_PRIMED, count); 1472 count = set_buf_states(q, bufnr, SLSB_CU_OUTPUT_PRIMED, count);
1443 used = atomic_add_return(count, &q->nr_buf_used); 1473 used = atomic_add_return(count, &q->nr_buf_used);
1444 BUG_ON(used > QDIO_MAX_BUFFERS_PER_Q); 1474 BUG_ON(used > QDIO_MAX_BUFFERS_PER_Q);
1445 1475
1446 if (callflags & QDIO_FLAG_PCI_OUT) 1476 if (callflags & QDIO_FLAG_PCI_OUT) {
1447 q->u.out.pci_out_enabled = 1; 1477 q->u.out.pci_out_enabled = 1;
1478 qperf_inc(q, pci_request_int);
1479 }
1448 else 1480 else
1449 q->u.out.pci_out_enabled = 0; 1481 q->u.out.pci_out_enabled = 0;
1450 1482
@@ -1483,7 +1515,7 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
1483 if (state != SLSB_CU_OUTPUT_PRIMED) 1515 if (state != SLSB_CU_OUTPUT_PRIMED)
1484 rc = qdio_kick_outbound_q(q); 1516 rc = qdio_kick_outbound_q(q);
1485 else 1517 else
1486 qdio_perf_stat_inc(&perf_stats.fast_requeue); 1518 qperf_inc(q, fast_requeue);
1487 1519
1488out: 1520out:
1489 tasklet_schedule(&q->tasklet); 1521 tasklet_schedule(&q->tasklet);
@@ -1539,16 +1571,11 @@ static int __init init_QDIO(void)
1539 rc = qdio_debug_init(); 1571 rc = qdio_debug_init();
1540 if (rc) 1572 if (rc)
1541 goto out_ti; 1573 goto out_ti;
1542 rc = qdio_setup_perf_stats();
1543 if (rc)
1544 goto out_debug;
1545 rc = tiqdio_register_thinints(); 1574 rc = tiqdio_register_thinints();
1546 if (rc) 1575 if (rc)
1547 goto out_perf; 1576 goto out_debug;
1548 return 0; 1577 return 0;
1549 1578
1550out_perf:
1551 qdio_remove_perf_stats();
1552out_debug: 1579out_debug:
1553 qdio_debug_exit(); 1580 qdio_debug_exit();
1554out_ti: 1581out_ti:
@@ -1562,7 +1589,6 @@ static void __exit exit_QDIO(void)
1562{ 1589{
1563 tiqdio_unregister_thinints(); 1590 tiqdio_unregister_thinints();
1564 tiqdio_free_memory(); 1591 tiqdio_free_memory();
1565 qdio_remove_perf_stats();
1566 qdio_debug_exit(); 1592 qdio_debug_exit();
1567 qdio_setup_exit(); 1593 qdio_setup_exit();
1568} 1594}