diff options
Diffstat (limited to 'drivers/s390/cio/qdio.c')
-rw-r--r-- | drivers/s390/cio/qdio.c | 322 |
1 files changed, 174 insertions, 148 deletions
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 8d5fa1b4d11f..d726cd5777de 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <asm/timex.h> | 46 | #include <asm/timex.h> |
47 | 47 | ||
48 | #include <asm/debug.h> | 48 | #include <asm/debug.h> |
49 | #include <asm/s390_rdev.h> | ||
49 | #include <asm/qdio.h> | 50 | #include <asm/qdio.h> |
50 | 51 | ||
51 | #include "cio.h" | 52 | #include "cio.h" |
@@ -66,11 +67,10 @@ MODULE_LICENSE("GPL"); | |||
66 | 67 | ||
67 | static const char version[] = "QDIO base support version 2"; | 68 | static const char version[] = "QDIO base support version 2"; |
68 | 69 | ||
69 | #ifdef QDIO_PERFORMANCE_STATS | 70 | static int qdio_performance_stats = 0; |
70 | static int proc_perf_file_registration; | 71 | static int proc_perf_file_registration; |
71 | static unsigned long i_p_c, i_p_nc, o_p_c, o_p_nc, ii_p_c, ii_p_nc; | 72 | static unsigned long i_p_c, i_p_nc, o_p_c, o_p_nc, ii_p_c, ii_p_nc; |
72 | static struct qdio_perf_stats perf_stats; | 73 | static struct qdio_perf_stats perf_stats; |
73 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
74 | 74 | ||
75 | static int hydra_thinints; | 75 | static int hydra_thinints; |
76 | static int is_passthrough = 0; | 76 | static int is_passthrough = 0; |
@@ -137,7 +137,7 @@ qdio_release_q(struct qdio_q *q) | |||
137 | } | 137 | } |
138 | 138 | ||
139 | /*check ccq */ | 139 | /*check ccq */ |
140 | static inline int | 140 | static int |
141 | qdio_check_ccq(struct qdio_q *q, unsigned int ccq) | 141 | qdio_check_ccq(struct qdio_q *q, unsigned int ccq) |
142 | { | 142 | { |
143 | char dbf_text[15]; | 143 | char dbf_text[15]; |
@@ -152,7 +152,7 @@ qdio_check_ccq(struct qdio_q *q, unsigned int ccq) | |||
152 | return -EIO; | 152 | return -EIO; |
153 | } | 153 | } |
154 | /* EQBS: extract buffer states */ | 154 | /* EQBS: extract buffer states */ |
155 | static inline int | 155 | static int |
156 | qdio_do_eqbs(struct qdio_q *q, unsigned char *state, | 156 | qdio_do_eqbs(struct qdio_q *q, unsigned char *state, |
157 | unsigned int *start, unsigned int *cnt) | 157 | unsigned int *start, unsigned int *cnt) |
158 | { | 158 | { |
@@ -187,7 +187,7 @@ again: | |||
187 | } | 187 | } |
188 | 188 | ||
189 | /* SQBS: set buffer states */ | 189 | /* SQBS: set buffer states */ |
190 | static inline int | 190 | static int |
191 | qdio_do_sqbs(struct qdio_q *q, unsigned char state, | 191 | qdio_do_sqbs(struct qdio_q *q, unsigned char state, |
192 | unsigned int *start, unsigned int *cnt) | 192 | unsigned int *start, unsigned int *cnt) |
193 | { | 193 | { |
@@ -275,9 +275,8 @@ qdio_siga_sync(struct qdio_q *q, unsigned int gpr2, | |||
275 | QDIO_DBF_TEXT4(0,trace,"sigasync"); | 275 | QDIO_DBF_TEXT4(0,trace,"sigasync"); |
276 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); | 276 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); |
277 | 277 | ||
278 | #ifdef QDIO_PERFORMANCE_STATS | 278 | if (qdio_performance_stats) |
279 | perf_stats.siga_syncs++; | 279 | perf_stats.siga_syncs++; |
280 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
281 | 280 | ||
282 | cc = do_siga_sync(q->schid, gpr2, gpr3); | 281 | cc = do_siga_sync(q->schid, gpr2, gpr3); |
283 | if (cc) | 282 | if (cc) |
@@ -315,16 +314,15 @@ __do_siga_output(struct qdio_q *q, unsigned int *busy_bit) | |||
315 | * returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns | 314 | * returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns |
316 | * an access exception | 315 | * an access exception |
317 | */ | 316 | */ |
318 | static inline int | 317 | static int |
319 | qdio_siga_output(struct qdio_q *q) | 318 | qdio_siga_output(struct qdio_q *q) |
320 | { | 319 | { |
321 | int cc; | 320 | int cc; |
322 | __u32 busy_bit; | 321 | __u32 busy_bit; |
323 | __u64 start_time=0; | 322 | __u64 start_time=0; |
324 | 323 | ||
325 | #ifdef QDIO_PERFORMANCE_STATS | 324 | if (qdio_performance_stats) |
326 | perf_stats.siga_outs++; | 325 | perf_stats.siga_outs++; |
327 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
328 | 326 | ||
329 | QDIO_DBF_TEXT4(0,trace,"sigaout"); | 327 | QDIO_DBF_TEXT4(0,trace,"sigaout"); |
330 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); | 328 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); |
@@ -350,7 +348,7 @@ qdio_siga_output(struct qdio_q *q) | |||
350 | return cc; | 348 | return cc; |
351 | } | 349 | } |
352 | 350 | ||
353 | static inline int | 351 | static int |
354 | qdio_siga_input(struct qdio_q *q) | 352 | qdio_siga_input(struct qdio_q *q) |
355 | { | 353 | { |
356 | int cc; | 354 | int cc; |
@@ -358,9 +356,8 @@ qdio_siga_input(struct qdio_q *q) | |||
358 | QDIO_DBF_TEXT4(0,trace,"sigain"); | 356 | QDIO_DBF_TEXT4(0,trace,"sigain"); |
359 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); | 357 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); |
360 | 358 | ||
361 | #ifdef QDIO_PERFORMANCE_STATS | 359 | if (qdio_performance_stats) |
362 | perf_stats.siga_ins++; | 360 | perf_stats.siga_ins++; |
363 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
364 | 361 | ||
365 | cc = do_siga_input(q->schid, q->mask); | 362 | cc = do_siga_input(q->schid, q->mask); |
366 | 363 | ||
@@ -423,7 +420,7 @@ tiqdio_sched_tl(void) | |||
423 | tasklet_hi_schedule(&tiqdio_tasklet); | 420 | tasklet_hi_schedule(&tiqdio_tasklet); |
424 | } | 421 | } |
425 | 422 | ||
426 | static inline void | 423 | static void |
427 | qdio_mark_tiq(struct qdio_q *q) | 424 | qdio_mark_tiq(struct qdio_q *q) |
428 | { | 425 | { |
429 | unsigned long flags; | 426 | unsigned long flags; |
@@ -473,7 +470,7 @@ qdio_mark_q(struct qdio_q *q) | |||
473 | tasklet_schedule(&q->tasklet); | 470 | tasklet_schedule(&q->tasklet); |
474 | } | 471 | } |
475 | 472 | ||
476 | static inline int | 473 | static int |
477 | qdio_stop_polling(struct qdio_q *q) | 474 | qdio_stop_polling(struct qdio_q *q) |
478 | { | 475 | { |
479 | #ifdef QDIO_USE_PROCESSING_STATE | 476 | #ifdef QDIO_USE_PROCESSING_STATE |
@@ -527,7 +524,7 @@ qdio_stop_polling(struct qdio_q *q) | |||
527 | * sophisticated locking outside of unmark_q, so that we don't need to | 524 | * sophisticated locking outside of unmark_q, so that we don't need to |
528 | * disable the interrupts :-) | 525 | * disable the interrupts :-) |
529 | */ | 526 | */ |
530 | static inline void | 527 | static void |
531 | qdio_unmark_q(struct qdio_q *q) | 528 | qdio_unmark_q(struct qdio_q *q) |
532 | { | 529 | { |
533 | unsigned long flags; | 530 | unsigned long flags; |
@@ -693,7 +690,7 @@ qdio_qebsm_get_inbound_buffer_frontier(struct qdio_q *q) | |||
693 | return q->first_to_check; | 690 | return q->first_to_check; |
694 | } | 691 | } |
695 | 692 | ||
696 | static inline int | 693 | static int |
697 | qdio_get_outbound_buffer_frontier(struct qdio_q *q) | 694 | qdio_get_outbound_buffer_frontier(struct qdio_q *q) |
698 | { | 695 | { |
699 | struct qdio_irq *irq; | 696 | struct qdio_irq *irq; |
@@ -776,7 +773,7 @@ out: | |||
776 | } | 773 | } |
777 | 774 | ||
778 | /* all buffers are processed */ | 775 | /* all buffers are processed */ |
779 | static inline int | 776 | static int |
780 | qdio_is_outbound_q_done(struct qdio_q *q) | 777 | qdio_is_outbound_q_done(struct qdio_q *q) |
781 | { | 778 | { |
782 | int no_used; | 779 | int no_used; |
@@ -798,7 +795,7 @@ qdio_is_outbound_q_done(struct qdio_q *q) | |||
798 | return (no_used==0); | 795 | return (no_used==0); |
799 | } | 796 | } |
800 | 797 | ||
801 | static inline int | 798 | static int |
802 | qdio_has_outbound_q_moved(struct qdio_q *q) | 799 | qdio_has_outbound_q_moved(struct qdio_q *q) |
803 | { | 800 | { |
804 | int i; | 801 | int i; |
@@ -818,7 +815,7 @@ qdio_has_outbound_q_moved(struct qdio_q *q) | |||
818 | } | 815 | } |
819 | } | 816 | } |
820 | 817 | ||
821 | static inline void | 818 | static void |
822 | qdio_kick_outbound_q(struct qdio_q *q) | 819 | qdio_kick_outbound_q(struct qdio_q *q) |
823 | { | 820 | { |
824 | int result; | 821 | int result; |
@@ -907,7 +904,7 @@ qdio_kick_outbound_q(struct qdio_q *q) | |||
907 | } | 904 | } |
908 | } | 905 | } |
909 | 906 | ||
910 | static inline void | 907 | static void |
911 | qdio_kick_outbound_handler(struct qdio_q *q) | 908 | qdio_kick_outbound_handler(struct qdio_q *q) |
912 | { | 909 | { |
913 | int start, end, real_end, count; | 910 | int start, end, real_end, count; |
@@ -944,7 +941,7 @@ qdio_kick_outbound_handler(struct qdio_q *q) | |||
944 | q->error_status_flags=0; | 941 | q->error_status_flags=0; |
945 | } | 942 | } |
946 | 943 | ||
947 | static inline void | 944 | static void |
948 | __qdio_outbound_processing(struct qdio_q *q) | 945 | __qdio_outbound_processing(struct qdio_q *q) |
949 | { | 946 | { |
950 | int siga_attempts; | 947 | int siga_attempts; |
@@ -954,9 +951,8 @@ __qdio_outbound_processing(struct qdio_q *q) | |||
954 | 951 | ||
955 | if (unlikely(qdio_reserve_q(q))) { | 952 | if (unlikely(qdio_reserve_q(q))) { |
956 | qdio_release_q(q); | 953 | qdio_release_q(q); |
957 | #ifdef QDIO_PERFORMANCE_STATS | 954 | if (qdio_performance_stats) |
958 | o_p_c++; | 955 | o_p_c++; |
959 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
960 | /* as we're sissies, we'll check next time */ | 956 | /* as we're sissies, we'll check next time */ |
961 | if (likely(!atomic_read(&q->is_in_shutdown))) { | 957 | if (likely(!atomic_read(&q->is_in_shutdown))) { |
962 | qdio_mark_q(q); | 958 | qdio_mark_q(q); |
@@ -964,10 +960,10 @@ __qdio_outbound_processing(struct qdio_q *q) | |||
964 | } | 960 | } |
965 | return; | 961 | return; |
966 | } | 962 | } |
967 | #ifdef QDIO_PERFORMANCE_STATS | 963 | if (qdio_performance_stats) { |
968 | o_p_nc++; | 964 | o_p_nc++; |
969 | perf_stats.tl_runs++; | 965 | perf_stats.tl_runs++; |
970 | #endif /* QDIO_PERFORMANCE_STATS */ | 966 | } |
971 | 967 | ||
972 | /* see comment in qdio_kick_outbound_q */ | 968 | /* see comment in qdio_kick_outbound_q */ |
973 | siga_attempts=atomic_read(&q->busy_siga_counter); | 969 | siga_attempts=atomic_read(&q->busy_siga_counter); |
@@ -982,12 +978,11 @@ __qdio_outbound_processing(struct qdio_q *q) | |||
982 | 978 | ||
983 | if (q->is_iqdio_q) { | 979 | if (q->is_iqdio_q) { |
984 | /* | 980 | /* |
985 | * for asynchronous queues, we better check, if the fill | 981 | * for asynchronous queues, we better check, if the sent |
986 | * level is too high. for synchronous queues, the fill | 982 | * buffer is already switched from PRIMED to EMPTY. |
987 | * level will never be that high. | ||
988 | */ | 983 | */ |
989 | if (atomic_read(&q->number_of_buffers_used)> | 984 | if ((q->queue_type == QDIO_IQDIO_QFMT_ASYNCH) && |
990 | IQDIO_FILL_LEVEL_TO_POLL) | 985 | !qdio_is_outbound_q_done(q)) |
991 | qdio_mark_q(q); | 986 | qdio_mark_q(q); |
992 | 987 | ||
993 | } else if (!q->hydra_gives_outbound_pcis) | 988 | } else if (!q->hydra_gives_outbound_pcis) |
@@ -1006,7 +1001,7 @@ qdio_outbound_processing(struct qdio_q *q) | |||
1006 | /************************* INBOUND ROUTINES *******************************/ | 1001 | /************************* INBOUND ROUTINES *******************************/ |
1007 | 1002 | ||
1008 | 1003 | ||
1009 | static inline int | 1004 | static int |
1010 | qdio_get_inbound_buffer_frontier(struct qdio_q *q) | 1005 | qdio_get_inbound_buffer_frontier(struct qdio_q *q) |
1011 | { | 1006 | { |
1012 | struct qdio_irq *irq; | 1007 | struct qdio_irq *irq; |
@@ -1137,20 +1132,21 @@ out: | |||
1137 | return q->first_to_check; | 1132 | return q->first_to_check; |
1138 | } | 1133 | } |
1139 | 1134 | ||
1140 | static inline int | 1135 | static int |
1141 | qdio_has_inbound_q_moved(struct qdio_q *q) | 1136 | qdio_has_inbound_q_moved(struct qdio_q *q) |
1142 | { | 1137 | { |
1143 | int i; | 1138 | int i; |
1144 | 1139 | ||
1145 | #ifdef QDIO_PERFORMANCE_STATS | ||
1146 | static int old_pcis=0; | 1140 | static int old_pcis=0; |
1147 | static int old_thinints=0; | 1141 | static int old_thinints=0; |
1148 | 1142 | ||
1149 | if ((old_pcis==perf_stats.pcis)&&(old_thinints==perf_stats.thinints)) | 1143 | if (qdio_performance_stats) { |
1150 | perf_stats.start_time_inbound=NOW; | 1144 | if ((old_pcis==perf_stats.pcis)&& |
1151 | else | 1145 | (old_thinints==perf_stats.thinints)) |
1152 | old_pcis=perf_stats.pcis; | 1146 | perf_stats.start_time_inbound=NOW; |
1153 | #endif /* QDIO_PERFORMANCE_STATS */ | 1147 | else |
1148 | old_pcis=perf_stats.pcis; | ||
1149 | } | ||
1154 | 1150 | ||
1155 | i=qdio_get_inbound_buffer_frontier(q); | 1151 | i=qdio_get_inbound_buffer_frontier(q); |
1156 | if ( (i!=GET_SAVED_FRONTIER(q)) || | 1152 | if ( (i!=GET_SAVED_FRONTIER(q)) || |
@@ -1170,7 +1166,7 @@ qdio_has_inbound_q_moved(struct qdio_q *q) | |||
1170 | } | 1166 | } |
1171 | 1167 | ||
1172 | /* means, no more buffers to be filled */ | 1168 | /* means, no more buffers to be filled */ |
1173 | static inline int | 1169 | static int |
1174 | tiqdio_is_inbound_q_done(struct qdio_q *q) | 1170 | tiqdio_is_inbound_q_done(struct qdio_q *q) |
1175 | { | 1171 | { |
1176 | int no_used; | 1172 | int no_used; |
@@ -1231,7 +1227,7 @@ tiqdio_is_inbound_q_done(struct qdio_q *q) | |||
1231 | return 0; | 1227 | return 0; |
1232 | } | 1228 | } |
1233 | 1229 | ||
1234 | static inline int | 1230 | static int |
1235 | qdio_is_inbound_q_done(struct qdio_q *q) | 1231 | qdio_is_inbound_q_done(struct qdio_q *q) |
1236 | { | 1232 | { |
1237 | int no_used; | 1233 | int no_used; |
@@ -1299,7 +1295,7 @@ qdio_is_inbound_q_done(struct qdio_q *q) | |||
1299 | } | 1295 | } |
1300 | } | 1296 | } |
1301 | 1297 | ||
1302 | static inline void | 1298 | static void |
1303 | qdio_kick_inbound_handler(struct qdio_q *q) | 1299 | qdio_kick_inbound_handler(struct qdio_q *q) |
1304 | { | 1300 | { |
1305 | int count, start, end, real_end, i; | 1301 | int count, start, end, real_end, i; |
@@ -1340,13 +1336,13 @@ qdio_kick_inbound_handler(struct qdio_q *q) | |||
1340 | q->siga_error=0; | 1336 | q->siga_error=0; |
1341 | q->error_status_flags=0; | 1337 | q->error_status_flags=0; |
1342 | 1338 | ||
1343 | #ifdef QDIO_PERFORMANCE_STATS | 1339 | if (qdio_performance_stats) { |
1344 | perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound; | 1340 | perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound; |
1345 | perf_stats.inbound_cnt++; | 1341 | perf_stats.inbound_cnt++; |
1346 | #endif /* QDIO_PERFORMANCE_STATS */ | 1342 | } |
1347 | } | 1343 | } |
1348 | 1344 | ||
1349 | static inline void | 1345 | static void |
1350 | __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) | 1346 | __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) |
1351 | { | 1347 | { |
1352 | struct qdio_irq *irq_ptr; | 1348 | struct qdio_irq *irq_ptr; |
@@ -1363,9 +1359,8 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) | |||
1363 | */ | 1359 | */ |
1364 | if (unlikely(qdio_reserve_q(q))) { | 1360 | if (unlikely(qdio_reserve_q(q))) { |
1365 | qdio_release_q(q); | 1361 | qdio_release_q(q); |
1366 | #ifdef QDIO_PERFORMANCE_STATS | 1362 | if (qdio_performance_stats) |
1367 | ii_p_c++; | 1363 | ii_p_c++; |
1368 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
1369 | /* | 1364 | /* |
1370 | * as we might just be about to stop polling, we make | 1365 | * as we might just be about to stop polling, we make |
1371 | * sure that we check again at least once more | 1366 | * sure that we check again at least once more |
@@ -1373,9 +1368,8 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) | |||
1373 | tiqdio_sched_tl(); | 1368 | tiqdio_sched_tl(); |
1374 | return; | 1369 | return; |
1375 | } | 1370 | } |
1376 | #ifdef QDIO_PERFORMANCE_STATS | 1371 | if (qdio_performance_stats) |
1377 | ii_p_nc++; | 1372 | ii_p_nc++; |
1378 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
1379 | if (unlikely(atomic_read(&q->is_in_shutdown))) { | 1373 | if (unlikely(atomic_read(&q->is_in_shutdown))) { |
1380 | qdio_unmark_q(q); | 1374 | qdio_unmark_q(q); |
1381 | goto out; | 1375 | goto out; |
@@ -1416,11 +1410,11 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) | |||
1416 | irq_ptr = (struct qdio_irq*)q->irq_ptr; | 1410 | irq_ptr = (struct qdio_irq*)q->irq_ptr; |
1417 | for (i=0;i<irq_ptr->no_output_qs;i++) { | 1411 | for (i=0;i<irq_ptr->no_output_qs;i++) { |
1418 | oq = irq_ptr->output_qs[i]; | 1412 | oq = irq_ptr->output_qs[i]; |
1419 | #ifdef QDIO_PERFORMANCE_STATS | 1413 | if (!qdio_is_outbound_q_done(oq)) { |
1420 | perf_stats.tl_runs--; | 1414 | if (qdio_performance_stats) |
1421 | #endif /* QDIO_PERFORMANCE_STATS */ | 1415 | perf_stats.tl_runs--; |
1422 | if (!qdio_is_outbound_q_done(oq)) | ||
1423 | __qdio_outbound_processing(oq); | 1416 | __qdio_outbound_processing(oq); |
1417 | } | ||
1424 | } | 1418 | } |
1425 | } | 1419 | } |
1426 | 1420 | ||
@@ -1447,7 +1441,7 @@ tiqdio_inbound_processing(struct qdio_q *q) | |||
1447 | __tiqdio_inbound_processing(q, atomic_read(&spare_indicator_usecount)); | 1441 | __tiqdio_inbound_processing(q, atomic_read(&spare_indicator_usecount)); |
1448 | } | 1442 | } |
1449 | 1443 | ||
1450 | static inline void | 1444 | static void |
1451 | __qdio_inbound_processing(struct qdio_q *q) | 1445 | __qdio_inbound_processing(struct qdio_q *q) |
1452 | { | 1446 | { |
1453 | int q_laps=0; | 1447 | int q_laps=0; |
@@ -1457,9 +1451,8 @@ __qdio_inbound_processing(struct qdio_q *q) | |||
1457 | 1451 | ||
1458 | if (unlikely(qdio_reserve_q(q))) { | 1452 | if (unlikely(qdio_reserve_q(q))) { |
1459 | qdio_release_q(q); | 1453 | qdio_release_q(q); |
1460 | #ifdef QDIO_PERFORMANCE_STATS | 1454 | if (qdio_performance_stats) |
1461 | i_p_c++; | 1455 | i_p_c++; |
1462 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
1463 | /* as we're sissies, we'll check next time */ | 1456 | /* as we're sissies, we'll check next time */ |
1464 | if (likely(!atomic_read(&q->is_in_shutdown))) { | 1457 | if (likely(!atomic_read(&q->is_in_shutdown))) { |
1465 | qdio_mark_q(q); | 1458 | qdio_mark_q(q); |
@@ -1467,10 +1460,10 @@ __qdio_inbound_processing(struct qdio_q *q) | |||
1467 | } | 1460 | } |
1468 | return; | 1461 | return; |
1469 | } | 1462 | } |
1470 | #ifdef QDIO_PERFORMANCE_STATS | 1463 | if (qdio_performance_stats) { |
1471 | i_p_nc++; | 1464 | i_p_nc++; |
1472 | perf_stats.tl_runs++; | 1465 | perf_stats.tl_runs++; |
1473 | #endif /* QDIO_PERFORMANCE_STATS */ | 1466 | } |
1474 | 1467 | ||
1475 | again: | 1468 | again: |
1476 | if (qdio_has_inbound_q_moved(q)) { | 1469 | if (qdio_has_inbound_q_moved(q)) { |
@@ -1499,7 +1492,7 @@ qdio_inbound_processing(struct qdio_q *q) | |||
1499 | /************************* MAIN ROUTINES *******************************/ | 1492 | /************************* MAIN ROUTINES *******************************/ |
1500 | 1493 | ||
1501 | #ifdef QDIO_USE_PROCESSING_STATE | 1494 | #ifdef QDIO_USE_PROCESSING_STATE |
1502 | static inline int | 1495 | static int |
1503 | tiqdio_reset_processing_state(struct qdio_q *q, int q_laps) | 1496 | tiqdio_reset_processing_state(struct qdio_q *q, int q_laps) |
1504 | { | 1497 | { |
1505 | if (!q) { | 1498 | if (!q) { |
@@ -1516,9 +1509,8 @@ tiqdio_reset_processing_state(struct qdio_q *q, int q_laps) | |||
1516 | 1509 | ||
1517 | if (unlikely(qdio_reserve_q(q))) { | 1510 | if (unlikely(qdio_reserve_q(q))) { |
1518 | qdio_release_q(q); | 1511 | qdio_release_q(q); |
1519 | #ifdef QDIO_PERFORMANCE_STATS | 1512 | if (qdio_performance_stats) |
1520 | ii_p_c++; | 1513 | ii_p_c++; |
1521 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
1522 | /* | 1514 | /* |
1523 | * as we might just be about to stop polling, we make | 1515 | * as we might just be about to stop polling, we make |
1524 | * sure that we check again at least once more | 1516 | * sure that we check again at least once more |
@@ -1552,7 +1544,7 @@ tiqdio_reset_processing_state(struct qdio_q *q, int q_laps) | |||
1552 | } | 1544 | } |
1553 | #endif /* QDIO_USE_PROCESSING_STATE */ | 1545 | #endif /* QDIO_USE_PROCESSING_STATE */ |
1554 | 1546 | ||
1555 | static inline void | 1547 | static void |
1556 | tiqdio_inbound_checks(void) | 1548 | tiqdio_inbound_checks(void) |
1557 | { | 1549 | { |
1558 | struct qdio_q *q; | 1550 | struct qdio_q *q; |
@@ -1609,9 +1601,8 @@ tiqdio_tl(unsigned long data) | |||
1609 | { | 1601 | { |
1610 | QDIO_DBF_TEXT4(0,trace,"iqdio_tl"); | 1602 | QDIO_DBF_TEXT4(0,trace,"iqdio_tl"); |
1611 | 1603 | ||
1612 | #ifdef QDIO_PERFORMANCE_STATS | 1604 | if (qdio_performance_stats) |
1613 | perf_stats.tl_runs++; | 1605 | perf_stats.tl_runs++; |
1614 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
1615 | 1606 | ||
1616 | tiqdio_inbound_checks(); | 1607 | tiqdio_inbound_checks(); |
1617 | } | 1608 | } |
@@ -1832,6 +1823,10 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, | |||
1832 | q->sbal[j]=*(outbound_sbals_array++); | 1823 | q->sbal[j]=*(outbound_sbals_array++); |
1833 | 1824 | ||
1834 | q->queue_type=q_format; | 1825 | q->queue_type=q_format; |
1826 | if ((q->queue_type == QDIO_IQDIO_QFMT) && | ||
1827 | (no_output_qs > 1) && | ||
1828 | (i == no_output_qs-1)) | ||
1829 | q->queue_type = QDIO_IQDIO_QFMT_ASYNCH; | ||
1835 | q->int_parm=int_parm; | 1830 | q->int_parm=int_parm; |
1836 | q->is_input_q=0; | 1831 | q->is_input_q=0; |
1837 | q->schid = irq_ptr->schid; | 1832 | q->schid = irq_ptr->schid; |
@@ -1918,10 +1913,10 @@ tiqdio_thinint_handler(void) | |||
1918 | { | 1913 | { |
1919 | QDIO_DBF_TEXT4(0,trace,"thin_int"); | 1914 | QDIO_DBF_TEXT4(0,trace,"thin_int"); |
1920 | 1915 | ||
1921 | #ifdef QDIO_PERFORMANCE_STATS | 1916 | if (qdio_performance_stats) { |
1922 | perf_stats.thinints++; | 1917 | perf_stats.thinints++; |
1923 | perf_stats.start_time_inbound=NOW; | 1918 | perf_stats.start_time_inbound=NOW; |
1924 | #endif /* QDIO_PERFORMANCE_STATS */ | 1919 | } |
1925 | 1920 | ||
1926 | /* SVS only when needed: | 1921 | /* SVS only when needed: |
1927 | * issue SVS to benefit from iqdio interrupt avoidance | 1922 | * issue SVS to benefit from iqdio interrupt avoidance |
@@ -1953,7 +1948,7 @@ qdio_set_state(struct qdio_irq *irq_ptr, enum qdio_irq_states state) | |||
1953 | mb(); | 1948 | mb(); |
1954 | } | 1949 | } |
1955 | 1950 | ||
1956 | static inline void | 1951 | static void |
1957 | qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb) | 1952 | qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb) |
1958 | { | 1953 | { |
1959 | char dbf_text[15]; | 1954 | char dbf_text[15]; |
@@ -1970,24 +1965,23 @@ qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb) | |||
1970 | 1965 | ||
1971 | } | 1966 | } |
1972 | 1967 | ||
1973 | static inline void | 1968 | static void |
1974 | qdio_handle_pci(struct qdio_irq *irq_ptr) | 1969 | qdio_handle_pci(struct qdio_irq *irq_ptr) |
1975 | { | 1970 | { |
1976 | int i; | 1971 | int i; |
1977 | struct qdio_q *q; | 1972 | struct qdio_q *q; |
1978 | 1973 | ||
1979 | #ifdef QDIO_PERFORMANCE_STATS | 1974 | if (qdio_performance_stats) { |
1980 | perf_stats.pcis++; | 1975 | perf_stats.pcis++; |
1981 | perf_stats.start_time_inbound=NOW; | 1976 | perf_stats.start_time_inbound=NOW; |
1982 | #endif /* QDIO_PERFORMANCE_STATS */ | 1977 | } |
1983 | for (i=0;i<irq_ptr->no_input_qs;i++) { | 1978 | for (i=0;i<irq_ptr->no_input_qs;i++) { |
1984 | q=irq_ptr->input_qs[i]; | 1979 | q=irq_ptr->input_qs[i]; |
1985 | if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) | 1980 | if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) |
1986 | qdio_mark_q(q); | 1981 | qdio_mark_q(q); |
1987 | else { | 1982 | else { |
1988 | #ifdef QDIO_PERFORMANCE_STATS | 1983 | if (qdio_performance_stats) |
1989 | perf_stats.tl_runs--; | 1984 | perf_stats.tl_runs--; |
1990 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
1991 | __qdio_inbound_processing(q); | 1985 | __qdio_inbound_processing(q); |
1992 | } | 1986 | } |
1993 | } | 1987 | } |
@@ -1995,11 +1989,10 @@ qdio_handle_pci(struct qdio_irq *irq_ptr) | |||
1995 | return; | 1989 | return; |
1996 | for (i=0;i<irq_ptr->no_output_qs;i++) { | 1990 | for (i=0;i<irq_ptr->no_output_qs;i++) { |
1997 | q=irq_ptr->output_qs[i]; | 1991 | q=irq_ptr->output_qs[i]; |
1998 | #ifdef QDIO_PERFORMANCE_STATS | ||
1999 | perf_stats.tl_runs--; | ||
2000 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
2001 | if (qdio_is_outbound_q_done(q)) | 1992 | if (qdio_is_outbound_q_done(q)) |
2002 | continue; | 1993 | continue; |
1994 | if (qdio_performance_stats) | ||
1995 | perf_stats.tl_runs--; | ||
2003 | if (!irq_ptr->sync_done_on_outb_pcis) | 1996 | if (!irq_ptr->sync_done_on_outb_pcis) |
2004 | SYNC_MEMORY; | 1997 | SYNC_MEMORY; |
2005 | __qdio_outbound_processing(q); | 1998 | __qdio_outbound_processing(q); |
@@ -2008,7 +2001,7 @@ qdio_handle_pci(struct qdio_irq *irq_ptr) | |||
2008 | 2001 | ||
2009 | static void qdio_establish_handle_irq(struct ccw_device*, int, int); | 2002 | static void qdio_establish_handle_irq(struct ccw_device*, int, int); |
2010 | 2003 | ||
2011 | static inline void | 2004 | static void |
2012 | qdio_handle_activate_check(struct ccw_device *cdev, unsigned long intparm, | 2005 | qdio_handle_activate_check(struct ccw_device *cdev, unsigned long intparm, |
2013 | int cstat, int dstat) | 2006 | int cstat, int dstat) |
2014 | { | 2007 | { |
@@ -2045,11 +2038,13 @@ omit_handler_call: | |||
2045 | } | 2038 | } |
2046 | 2039 | ||
2047 | static void | 2040 | static void |
2048 | qdio_call_shutdown(void *data) | 2041 | qdio_call_shutdown(struct work_struct *work) |
2049 | { | 2042 | { |
2043 | struct ccw_device_private *priv; | ||
2050 | struct ccw_device *cdev; | 2044 | struct ccw_device *cdev; |
2051 | 2045 | ||
2052 | cdev = (struct ccw_device *)data; | 2046 | priv = container_of(work, struct ccw_device_private, kick_work); |
2047 | cdev = priv->cdev; | ||
2053 | qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); | 2048 | qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); |
2054 | put_device(&cdev->dev); | 2049 | put_device(&cdev->dev); |
2055 | } | 2050 | } |
@@ -2091,7 +2086,7 @@ qdio_timeout_handler(struct ccw_device *cdev) | |||
2091 | if (get_device(&cdev->dev)) { | 2086 | if (get_device(&cdev->dev)) { |
2092 | /* Can't call shutdown from interrupt context. */ | 2087 | /* Can't call shutdown from interrupt context. */ |
2093 | PREPARE_WORK(&cdev->private->kick_work, | 2088 | PREPARE_WORK(&cdev->private->kick_work, |
2094 | qdio_call_shutdown, (void *)cdev); | 2089 | qdio_call_shutdown); |
2095 | queue_work(ccw_device_work, &cdev->private->kick_work); | 2090 | queue_work(ccw_device_work, &cdev->private->kick_work); |
2096 | } | 2091 | } |
2097 | break; | 2092 | break; |
@@ -2233,7 +2228,7 @@ qdio_synchronize(struct ccw_device *cdev, unsigned int flags, | |||
2233 | return cc; | 2228 | return cc; |
2234 | } | 2229 | } |
2235 | 2230 | ||
2236 | static inline void | 2231 | static void |
2237 | qdio_check_subchannel_qebsm(struct qdio_irq *irq_ptr, unsigned char qdioac, | 2232 | qdio_check_subchannel_qebsm(struct qdio_irq *irq_ptr, unsigned char qdioac, |
2238 | unsigned long token) | 2233 | unsigned long token) |
2239 | { | 2234 | { |
@@ -2744,7 +2739,7 @@ qdio_free(struct ccw_device *cdev) | |||
2744 | return 0; | 2739 | return 0; |
2745 | } | 2740 | } |
2746 | 2741 | ||
2747 | static inline void | 2742 | static void |
2748 | qdio_allocate_do_dbf(struct qdio_initialize *init_data) | 2743 | qdio_allocate_do_dbf(struct qdio_initialize *init_data) |
2749 | { | 2744 | { |
2750 | char dbf_text[20]; /* if a printf printed out more than 8 chars */ | 2745 | char dbf_text[20]; /* if a printf printed out more than 8 chars */ |
@@ -2777,7 +2772,7 @@ qdio_allocate_do_dbf(struct qdio_initialize *init_data) | |||
2777 | QDIO_DBF_HEX0(0,setup,&init_data->output_sbal_addr_array,sizeof(void*)); | 2772 | QDIO_DBF_HEX0(0,setup,&init_data->output_sbal_addr_array,sizeof(void*)); |
2778 | } | 2773 | } |
2779 | 2774 | ||
2780 | static inline void | 2775 | static void |
2781 | qdio_allocate_fill_input_desc(struct qdio_irq *irq_ptr, int i, int iqfmt) | 2776 | qdio_allocate_fill_input_desc(struct qdio_irq *irq_ptr, int i, int iqfmt) |
2782 | { | 2777 | { |
2783 | irq_ptr->input_qs[i]->is_iqdio_q = iqfmt; | 2778 | irq_ptr->input_qs[i]->is_iqdio_q = iqfmt; |
@@ -2796,7 +2791,7 @@ qdio_allocate_fill_input_desc(struct qdio_irq *irq_ptr, int i, int iqfmt) | |||
2796 | irq_ptr->qdr->qdf0[i].dkey=QDIO_STORAGE_KEY; | 2791 | irq_ptr->qdr->qdf0[i].dkey=QDIO_STORAGE_KEY; |
2797 | } | 2792 | } |
2798 | 2793 | ||
2799 | static inline void | 2794 | static void |
2800 | qdio_allocate_fill_output_desc(struct qdio_irq *irq_ptr, int i, | 2795 | qdio_allocate_fill_output_desc(struct qdio_irq *irq_ptr, int i, |
2801 | int j, int iqfmt) | 2796 | int j, int iqfmt) |
2802 | { | 2797 | { |
@@ -2817,7 +2812,7 @@ qdio_allocate_fill_output_desc(struct qdio_irq *irq_ptr, int i, | |||
2817 | } | 2812 | } |
2818 | 2813 | ||
2819 | 2814 | ||
2820 | static inline void | 2815 | static void |
2821 | qdio_initialize_set_siga_flags_input(struct qdio_irq *irq_ptr) | 2816 | qdio_initialize_set_siga_flags_input(struct qdio_irq *irq_ptr) |
2822 | { | 2817 | { |
2823 | int i; | 2818 | int i; |
@@ -2843,7 +2838,7 @@ qdio_initialize_set_siga_flags_input(struct qdio_irq *irq_ptr) | |||
2843 | } | 2838 | } |
2844 | } | 2839 | } |
2845 | 2840 | ||
2846 | static inline void | 2841 | static void |
2847 | qdio_initialize_set_siga_flags_output(struct qdio_irq *irq_ptr) | 2842 | qdio_initialize_set_siga_flags_output(struct qdio_irq *irq_ptr) |
2848 | { | 2843 | { |
2849 | int i; | 2844 | int i; |
@@ -2869,7 +2864,7 @@ qdio_initialize_set_siga_flags_output(struct qdio_irq *irq_ptr) | |||
2869 | } | 2864 | } |
2870 | } | 2865 | } |
2871 | 2866 | ||
2872 | static inline int | 2867 | static int |
2873 | qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat, | 2868 | qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat, |
2874 | int dstat) | 2869 | int dstat) |
2875 | { | 2870 | { |
@@ -3018,7 +3013,7 @@ qdio_allocate(struct qdio_initialize *init_data) | |||
3018 | return 0; | 3013 | return 0; |
3019 | } | 3014 | } |
3020 | 3015 | ||
3021 | int qdio_fill_irq(struct qdio_initialize *init_data) | 3016 | static int qdio_fill_irq(struct qdio_initialize *init_data) |
3022 | { | 3017 | { |
3023 | int i; | 3018 | int i; |
3024 | char dbf_text[15]; | 3019 | char dbf_text[15]; |
@@ -3371,7 +3366,7 @@ qdio_activate(struct ccw_device *cdev, int flags) | |||
3371 | } | 3366 | } |
3372 | 3367 | ||
3373 | /* buffers filled forwards again to make Rick happy */ | 3368 | /* buffers filled forwards again to make Rick happy */ |
3374 | static inline void | 3369 | static void |
3375 | qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx, | 3370 | qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx, |
3376 | unsigned int count, struct qdio_buffer *buffers) | 3371 | unsigned int count, struct qdio_buffer *buffers) |
3377 | { | 3372 | { |
@@ -3390,7 +3385,7 @@ qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx, | |||
3390 | } | 3385 | } |
3391 | } | 3386 | } |
3392 | 3387 | ||
3393 | static inline void | 3388 | static void |
3394 | qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx, | 3389 | qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx, |
3395 | unsigned int count, struct qdio_buffer *buffers) | 3390 | unsigned int count, struct qdio_buffer *buffers) |
3396 | { | 3391 | { |
@@ -3411,7 +3406,7 @@ qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx, | |||
3411 | } | 3406 | } |
3412 | } | 3407 | } |
3413 | 3408 | ||
3414 | static inline void | 3409 | static void |
3415 | do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags, | 3410 | do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags, |
3416 | unsigned int qidx, unsigned int count, | 3411 | unsigned int qidx, unsigned int count, |
3417 | struct qdio_buffer *buffers) | 3412 | struct qdio_buffer *buffers) |
@@ -3447,7 +3442,7 @@ do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags, | |||
3447 | qdio_mark_q(q); | 3442 | qdio_mark_q(q); |
3448 | } | 3443 | } |
3449 | 3444 | ||
3450 | static inline void | 3445 | static void |
3451 | do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, | 3446 | do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, |
3452 | unsigned int qidx, unsigned int count, | 3447 | unsigned int qidx, unsigned int count, |
3453 | struct qdio_buffer *buffers) | 3448 | struct qdio_buffer *buffers) |
@@ -3458,19 +3453,18 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, | |||
3458 | struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; | 3453 | struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; |
3459 | 3454 | ||
3460 | /* This is the outbound handling of queues */ | 3455 | /* This is the outbound handling of queues */ |
3461 | #ifdef QDIO_PERFORMANCE_STATS | 3456 | if (qdio_performance_stats) |
3462 | perf_stats.start_time_outbound=NOW; | 3457 | perf_stats.start_time_outbound=NOW; |
3463 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
3464 | 3458 | ||
3465 | qdio_do_qdio_fill_output(q,qidx,count,buffers); | 3459 | qdio_do_qdio_fill_output(q,qidx,count,buffers); |
3466 | 3460 | ||
3467 | used_elements=atomic_add_return(count, &q->number_of_buffers_used) - count; | 3461 | used_elements=atomic_add_return(count, &q->number_of_buffers_used) - count; |
3468 | 3462 | ||
3469 | if (callflags&QDIO_FLAG_DONT_SIGA) { | 3463 | if (callflags&QDIO_FLAG_DONT_SIGA) { |
3470 | #ifdef QDIO_PERFORMANCE_STATS | 3464 | if (qdio_performance_stats) { |
3471 | perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; | 3465 | perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; |
3472 | perf_stats.outbound_cnt++; | 3466 | perf_stats.outbound_cnt++; |
3473 | #endif /* QDIO_PERFORMANCE_STATS */ | 3467 | } |
3474 | return; | 3468 | return; |
3475 | } | 3469 | } |
3476 | if (q->is_iqdio_q) { | 3470 | if (q->is_iqdio_q) { |
@@ -3500,9 +3494,8 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, | |||
3500 | qdio_kick_outbound_q(q); | 3494 | qdio_kick_outbound_q(q); |
3501 | } else { | 3495 | } else { |
3502 | QDIO_DBF_TEXT3(0,trace, "fast-req"); | 3496 | QDIO_DBF_TEXT3(0,trace, "fast-req"); |
3503 | #ifdef QDIO_PERFORMANCE_STATS | 3497 | if (qdio_performance_stats) |
3504 | perf_stats.fast_reqs++; | 3498 | perf_stats.fast_reqs++; |
3505 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
3506 | } | 3499 | } |
3507 | } | 3500 | } |
3508 | /* | 3501 | /* |
@@ -3513,10 +3506,10 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, | |||
3513 | __qdio_outbound_processing(q); | 3506 | __qdio_outbound_processing(q); |
3514 | } | 3507 | } |
3515 | 3508 | ||
3516 | #ifdef QDIO_PERFORMANCE_STATS | 3509 | if (qdio_performance_stats) { |
3517 | perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; | 3510 | perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; |
3518 | perf_stats.outbound_cnt++; | 3511 | perf_stats.outbound_cnt++; |
3519 | #endif /* QDIO_PERFORMANCE_STATS */ | 3512 | } |
3520 | } | 3513 | } |
3521 | 3514 | ||
3522 | /* count must be 1 in iqdio */ | 3515 | /* count must be 1 in iqdio */ |
@@ -3574,7 +3567,6 @@ do_QDIO(struct ccw_device *cdev,unsigned int callflags, | |||
3574 | return 0; | 3567 | return 0; |
3575 | } | 3568 | } |
3576 | 3569 | ||
3577 | #ifdef QDIO_PERFORMANCE_STATS | ||
3578 | static int | 3570 | static int |
3579 | qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, | 3571 | qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, |
3580 | int buffer_length, int *eof, void *data) | 3572 | int buffer_length, int *eof, void *data) |
@@ -3590,29 +3582,29 @@ qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, | |||
3590 | _OUTP_IT("i_p_nc/c=%lu/%lu\n",i_p_nc,i_p_c); | 3582 | _OUTP_IT("i_p_nc/c=%lu/%lu\n",i_p_nc,i_p_c); |
3591 | _OUTP_IT("ii_p_nc/c=%lu/%lu\n",ii_p_nc,ii_p_c); | 3583 | _OUTP_IT("ii_p_nc/c=%lu/%lu\n",ii_p_nc,ii_p_c); |
3592 | _OUTP_IT("o_p_nc/c=%lu/%lu\n",o_p_nc,o_p_c); | 3584 | _OUTP_IT("o_p_nc/c=%lu/%lu\n",o_p_nc,o_p_c); |
3593 | _OUTP_IT("Number of tasklet runs (total) : %u\n", | 3585 | _OUTP_IT("Number of tasklet runs (total) : %lu\n", |
3594 | perf_stats.tl_runs); | 3586 | perf_stats.tl_runs); |
3595 | _OUTP_IT("\n"); | 3587 | _OUTP_IT("\n"); |
3596 | _OUTP_IT("Number of SIGA sync's issued : %u\n", | 3588 | _OUTP_IT("Number of SIGA sync's issued : %lu\n", |
3597 | perf_stats.siga_syncs); | 3589 | perf_stats.siga_syncs); |
3598 | _OUTP_IT("Number of SIGA in's issued : %u\n", | 3590 | _OUTP_IT("Number of SIGA in's issued : %lu\n", |
3599 | perf_stats.siga_ins); | 3591 | perf_stats.siga_ins); |
3600 | _OUTP_IT("Number of SIGA out's issued : %u\n", | 3592 | _OUTP_IT("Number of SIGA out's issued : %lu\n", |
3601 | perf_stats.siga_outs); | 3593 | perf_stats.siga_outs); |
3602 | _OUTP_IT("Number of PCIs caught : %u\n", | 3594 | _OUTP_IT("Number of PCIs caught : %lu\n", |
3603 | perf_stats.pcis); | 3595 | perf_stats.pcis); |
3604 | _OUTP_IT("Number of adapter interrupts caught : %u\n", | 3596 | _OUTP_IT("Number of adapter interrupts caught : %lu\n", |
3605 | perf_stats.thinints); | 3597 | perf_stats.thinints); |
3606 | _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %u\n", | 3598 | _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %lu\n", |
3607 | perf_stats.fast_reqs); | 3599 | perf_stats.fast_reqs); |
3608 | _OUTP_IT("\n"); | 3600 | _OUTP_IT("\n"); |
3609 | _OUTP_IT("Total time of all inbound actions (us) incl. UL : %u\n", | 3601 | _OUTP_IT("Total time of all inbound actions (us) incl. UL : %lu\n", |
3610 | perf_stats.inbound_time); | 3602 | perf_stats.inbound_time); |
3611 | _OUTP_IT("Number of inbound transfers : %u\n", | 3603 | _OUTP_IT("Number of inbound transfers : %lu\n", |
3612 | perf_stats.inbound_cnt); | 3604 | perf_stats.inbound_cnt); |
3613 | _OUTP_IT("Total time of all outbound do_QDIOs (us) : %u\n", | 3605 | _OUTP_IT("Total time of all outbound do_QDIOs (us) : %lu\n", |
3614 | perf_stats.outbound_time); | 3606 | perf_stats.outbound_time); |
3615 | _OUTP_IT("Number of do_QDIOs outbound : %u\n", | 3607 | _OUTP_IT("Number of do_QDIOs outbound : %lu\n", |
3616 | perf_stats.outbound_cnt); | 3608 | perf_stats.outbound_cnt); |
3617 | _OUTP_IT("\n"); | 3609 | _OUTP_IT("\n"); |
3618 | 3610 | ||
@@ -3620,12 +3612,10 @@ qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, | |||
3620 | } | 3612 | } |
3621 | 3613 | ||
3622 | static struct proc_dir_entry *qdio_perf_proc_file; | 3614 | static struct proc_dir_entry *qdio_perf_proc_file; |
3623 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
3624 | 3615 | ||
3625 | static void | 3616 | static void |
3626 | qdio_add_procfs_entry(void) | 3617 | qdio_add_procfs_entry(void) |
3627 | { | 3618 | { |
3628 | #ifdef QDIO_PERFORMANCE_STATS | ||
3629 | proc_perf_file_registration=0; | 3619 | proc_perf_file_registration=0; |
3630 | qdio_perf_proc_file=create_proc_entry(QDIO_PERF, | 3620 | qdio_perf_proc_file=create_proc_entry(QDIO_PERF, |
3631 | S_IFREG|0444,&proc_root); | 3621 | S_IFREG|0444,&proc_root); |
@@ -3637,20 +3627,58 @@ qdio_add_procfs_entry(void) | |||
3637 | QDIO_PRINT_WARN("was not able to register perf. " \ | 3627 | QDIO_PRINT_WARN("was not able to register perf. " \ |
3638 | "proc-file (%i).\n", | 3628 | "proc-file (%i).\n", |
3639 | proc_perf_file_registration); | 3629 | proc_perf_file_registration); |
3640 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
3641 | } | 3630 | } |
3642 | 3631 | ||
3643 | static void | 3632 | static void |
3644 | qdio_remove_procfs_entry(void) | 3633 | qdio_remove_procfs_entry(void) |
3645 | { | 3634 | { |
3646 | #ifdef QDIO_PERFORMANCE_STATS | ||
3647 | perf_stats.tl_runs=0; | 3635 | perf_stats.tl_runs=0; |
3648 | 3636 | ||
3649 | if (!proc_perf_file_registration) /* means if it went ok earlier */ | 3637 | if (!proc_perf_file_registration) /* means if it went ok earlier */ |
3650 | remove_proc_entry(QDIO_PERF,&proc_root); | 3638 | remove_proc_entry(QDIO_PERF,&proc_root); |
3651 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
3652 | } | 3639 | } |
3653 | 3640 | ||
3641 | /** | ||
3642 | * attributes in sysfs | ||
3643 | *****************************************************************************/ | ||
3644 | |||
3645 | static ssize_t | ||
3646 | qdio_performance_stats_show(struct bus_type *bus, char *buf) | ||
3647 | { | ||
3648 | return sprintf(buf, "%i\n", qdio_performance_stats ? 1 : 0); | ||
3649 | } | ||
3650 | |||
3651 | static ssize_t | ||
3652 | qdio_performance_stats_store(struct bus_type *bus, const char *buf, size_t count) | ||
3653 | { | ||
3654 | char *tmp; | ||
3655 | int i; | ||
3656 | |||
3657 | i = simple_strtoul(buf, &tmp, 16); | ||
3658 | if ((i == 0) || (i == 1)) { | ||
3659 | if (i == qdio_performance_stats) | ||
3660 | return count; | ||
3661 | qdio_performance_stats = i; | ||
3662 | if (i==0) { | ||
3663 | /* reset perf. stat. info */ | ||
3664 | i_p_nc = 0; | ||
3665 | i_p_c = 0; | ||
3666 | ii_p_nc = 0; | ||
3667 | ii_p_c = 0; | ||
3668 | o_p_nc = 0; | ||
3669 | o_p_c = 0; | ||
3670 | memset(&perf_stats, 0, sizeof(struct qdio_perf_stats)); | ||
3671 | } | ||
3672 | } else { | ||
3673 | QDIO_PRINT_WARN("QDIO performance_stats: write 0 or 1 to this file!\n"); | ||
3674 | return -EINVAL; | ||
3675 | } | ||
3676 | return count; | ||
3677 | } | ||
3678 | |||
3679 | static BUS_ATTR(qdio_performance_stats, 0644, qdio_performance_stats_show, | ||
3680 | qdio_performance_stats_store); | ||
3681 | |||
3654 | static void | 3682 | static void |
3655 | tiqdio_register_thinints(void) | 3683 | tiqdio_register_thinints(void) |
3656 | { | 3684 | { |
@@ -3695,6 +3723,7 @@ qdio_release_qdio_memory(void) | |||
3695 | kfree(indicators); | 3723 | kfree(indicators); |
3696 | } | 3724 | } |
3697 | 3725 | ||
3726 | |||
3698 | static void | 3727 | static void |
3699 | qdio_unregister_dbf_views(void) | 3728 | qdio_unregister_dbf_views(void) |
3700 | { | 3729 | { |
@@ -3796,9 +3825,7 @@ static int __init | |||
3796 | init_QDIO(void) | 3825 | init_QDIO(void) |
3797 | { | 3826 | { |
3798 | int res; | 3827 | int res; |
3799 | #ifdef QDIO_PERFORMANCE_STATS | ||
3800 | void *ptr; | 3828 | void *ptr; |
3801 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
3802 | 3829 | ||
3803 | printk("qdio: loading %s\n",version); | 3830 | printk("qdio: loading %s\n",version); |
3804 | 3831 | ||
@@ -3811,13 +3838,12 @@ init_QDIO(void) | |||
3811 | return res; | 3838 | return res; |
3812 | 3839 | ||
3813 | QDIO_DBF_TEXT0(0,setup,"initQDIO"); | 3840 | QDIO_DBF_TEXT0(0,setup,"initQDIO"); |
3841 | res = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); | ||
3814 | 3842 | ||
3815 | #ifdef QDIO_PERFORMANCE_STATS | 3843 | memset((void*)&perf_stats,0,sizeof(perf_stats)); |
3816 | memset((void*)&perf_stats,0,sizeof(perf_stats)); | ||
3817 | QDIO_DBF_TEXT0(0,setup,"perfstat"); | 3844 | QDIO_DBF_TEXT0(0,setup,"perfstat"); |
3818 | ptr=&perf_stats; | 3845 | ptr=&perf_stats; |
3819 | QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*)); | 3846 | QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*)); |
3820 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
3821 | 3847 | ||
3822 | qdio_add_procfs_entry(); | 3848 | qdio_add_procfs_entry(); |
3823 | 3849 | ||
@@ -3841,7 +3867,7 @@ cleanup_QDIO(void) | |||
3841 | qdio_release_qdio_memory(); | 3867 | qdio_release_qdio_memory(); |
3842 | qdio_unregister_dbf_views(); | 3868 | qdio_unregister_dbf_views(); |
3843 | mempool_destroy(qdio_mempool_scssc); | 3869 | mempool_destroy(qdio_mempool_scssc); |
3844 | 3870 | bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); | |
3845 | printk("qdio: %s: module removed\n",version); | 3871 | printk("qdio: %s: module removed\n",version); |
3846 | } | 3872 | } |
3847 | 3873 | ||