diff options
-rw-r--r-- | arch/s390/Kconfig | 8 | ||||
-rw-r--r-- | arch/s390/defconfig | 1 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.c | 226 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.h | 28 |
4 files changed, 135 insertions, 128 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 583d9ff0a571..a08e9100e7e4 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -258,14 +258,6 @@ config QDIO | |||
258 | 258 | ||
259 | If unsure, say Y. | 259 | If unsure, say Y. |
260 | 260 | ||
261 | config QDIO_PERF_STATS | ||
262 | bool "Performance statistics in /proc" | ||
263 | depends on QDIO | ||
264 | help | ||
265 | Say Y here to get performance statistics in /proc/qdio_perf | ||
266 | |||
267 | If unsure, say N. | ||
268 | |||
269 | config QDIO_DEBUG | 261 | config QDIO_DEBUG |
270 | bool "Extended debugging information" | 262 | bool "Extended debugging information" |
271 | depends on QDIO | 263 | depends on QDIO |
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 7cd51e73e274..a6ec919ba83f 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -134,7 +134,6 @@ CONFIG_RESOURCES_64BIT=y | |||
134 | # | 134 | # |
135 | CONFIG_MACHCHK_WARNING=y | 135 | CONFIG_MACHCHK_WARNING=y |
136 | CONFIG_QDIO=y | 136 | CONFIG_QDIO=y |
137 | # CONFIG_QDIO_PERF_STATS is not set | ||
138 | # CONFIG_QDIO_DEBUG is not set | 137 | # CONFIG_QDIO_DEBUG is not set |
139 | 138 | ||
140 | # | 139 | # |
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index d066dbf2c65d..9d4ea449a608 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" |
@@ -65,12 +66,12 @@ MODULE_LICENSE("GPL"); | |||
65 | /******************** HERE WE GO ***********************************/ | 66 | /******************** HERE WE GO ***********************************/ |
66 | 67 | ||
67 | static const char version[] = "QDIO base support version 2"; | 68 | static const char version[] = "QDIO base support version 2"; |
69 | extern struct bus_type ccw_bus_type; | ||
68 | 70 | ||
69 | #ifdef QDIO_PERFORMANCE_STATS | 71 | static int qdio_performance_stats = 0; |
70 | static int proc_perf_file_registration; | 72 | 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; | 73 | 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; | 74 | static struct qdio_perf_stats perf_stats; |
73 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
74 | 75 | ||
75 | static int hydra_thinints; | 76 | static int hydra_thinints; |
76 | static int is_passthrough = 0; | 77 | static int is_passthrough = 0; |
@@ -275,9 +276,8 @@ qdio_siga_sync(struct qdio_q *q, unsigned int gpr2, | |||
275 | QDIO_DBF_TEXT4(0,trace,"sigasync"); | 276 | QDIO_DBF_TEXT4(0,trace,"sigasync"); |
276 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); | 277 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); |
277 | 278 | ||
278 | #ifdef QDIO_PERFORMANCE_STATS | 279 | if (qdio_performance_stats) |
279 | perf_stats.siga_syncs++; | 280 | perf_stats.siga_syncs++; |
280 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
281 | 281 | ||
282 | cc = do_siga_sync(q->schid, gpr2, gpr3); | 282 | cc = do_siga_sync(q->schid, gpr2, gpr3); |
283 | if (cc) | 283 | if (cc) |
@@ -322,9 +322,8 @@ qdio_siga_output(struct qdio_q *q) | |||
322 | __u32 busy_bit; | 322 | __u32 busy_bit; |
323 | __u64 start_time=0; | 323 | __u64 start_time=0; |
324 | 324 | ||
325 | #ifdef QDIO_PERFORMANCE_STATS | 325 | if (qdio_performance_stats) |
326 | perf_stats.siga_outs++; | 326 | perf_stats.siga_outs++; |
327 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
328 | 327 | ||
329 | QDIO_DBF_TEXT4(0,trace,"sigaout"); | 328 | QDIO_DBF_TEXT4(0,trace,"sigaout"); |
330 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); | 329 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); |
@@ -358,9 +357,8 @@ qdio_siga_input(struct qdio_q *q) | |||
358 | QDIO_DBF_TEXT4(0,trace,"sigain"); | 357 | QDIO_DBF_TEXT4(0,trace,"sigain"); |
359 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); | 358 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); |
360 | 359 | ||
361 | #ifdef QDIO_PERFORMANCE_STATS | 360 | if (qdio_performance_stats) |
362 | perf_stats.siga_ins++; | 361 | perf_stats.siga_ins++; |
363 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
364 | 362 | ||
365 | cc = do_siga_input(q->schid, q->mask); | 363 | cc = do_siga_input(q->schid, q->mask); |
366 | 364 | ||
@@ -954,9 +952,8 @@ __qdio_outbound_processing(struct qdio_q *q) | |||
954 | 952 | ||
955 | if (unlikely(qdio_reserve_q(q))) { | 953 | if (unlikely(qdio_reserve_q(q))) { |
956 | qdio_release_q(q); | 954 | qdio_release_q(q); |
957 | #ifdef QDIO_PERFORMANCE_STATS | 955 | if (qdio_performance_stats) |
958 | o_p_c++; | 956 | o_p_c++; |
959 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
960 | /* as we're sissies, we'll check next time */ | 957 | /* as we're sissies, we'll check next time */ |
961 | if (likely(!atomic_read(&q->is_in_shutdown))) { | 958 | if (likely(!atomic_read(&q->is_in_shutdown))) { |
962 | qdio_mark_q(q); | 959 | qdio_mark_q(q); |
@@ -964,10 +961,10 @@ __qdio_outbound_processing(struct qdio_q *q) | |||
964 | } | 961 | } |
965 | return; | 962 | return; |
966 | } | 963 | } |
967 | #ifdef QDIO_PERFORMANCE_STATS | 964 | if (qdio_performance_stats) { |
968 | o_p_nc++; | 965 | o_p_nc++; |
969 | perf_stats.tl_runs++; | 966 | perf_stats.tl_runs++; |
970 | #endif /* QDIO_PERFORMANCE_STATS */ | 967 | } |
971 | 968 | ||
972 | /* see comment in qdio_kick_outbound_q */ | 969 | /* see comment in qdio_kick_outbound_q */ |
973 | siga_attempts=atomic_read(&q->busy_siga_counter); | 970 | siga_attempts=atomic_read(&q->busy_siga_counter); |
@@ -1142,15 +1139,16 @@ qdio_has_inbound_q_moved(struct qdio_q *q) | |||
1142 | { | 1139 | { |
1143 | int i; | 1140 | int i; |
1144 | 1141 | ||
1145 | #ifdef QDIO_PERFORMANCE_STATS | ||
1146 | static int old_pcis=0; | 1142 | static int old_pcis=0; |
1147 | static int old_thinints=0; | 1143 | static int old_thinints=0; |
1148 | 1144 | ||
1149 | if ((old_pcis==perf_stats.pcis)&&(old_thinints==perf_stats.thinints)) | 1145 | if (qdio_performance_stats) { |
1150 | perf_stats.start_time_inbound=NOW; | 1146 | if ((old_pcis==perf_stats.pcis)&& |
1151 | else | 1147 | (old_thinints==perf_stats.thinints)) |
1152 | old_pcis=perf_stats.pcis; | 1148 | perf_stats.start_time_inbound=NOW; |
1153 | #endif /* QDIO_PERFORMANCE_STATS */ | 1149 | else |
1150 | old_pcis=perf_stats.pcis; | ||
1151 | } | ||
1154 | 1152 | ||
1155 | i=qdio_get_inbound_buffer_frontier(q); | 1153 | i=qdio_get_inbound_buffer_frontier(q); |
1156 | if ( (i!=GET_SAVED_FRONTIER(q)) || | 1154 | if ( (i!=GET_SAVED_FRONTIER(q)) || |
@@ -1340,10 +1338,10 @@ qdio_kick_inbound_handler(struct qdio_q *q) | |||
1340 | q->siga_error=0; | 1338 | q->siga_error=0; |
1341 | q->error_status_flags=0; | 1339 | q->error_status_flags=0; |
1342 | 1340 | ||
1343 | #ifdef QDIO_PERFORMANCE_STATS | 1341 | if (qdio_performance_stats) { |
1344 | perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound; | 1342 | perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound; |
1345 | perf_stats.inbound_cnt++; | 1343 | perf_stats.inbound_cnt++; |
1346 | #endif /* QDIO_PERFORMANCE_STATS */ | 1344 | } |
1347 | } | 1345 | } |
1348 | 1346 | ||
1349 | static inline void | 1347 | static inline void |
@@ -1363,9 +1361,8 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) | |||
1363 | */ | 1361 | */ |
1364 | if (unlikely(qdio_reserve_q(q))) { | 1362 | if (unlikely(qdio_reserve_q(q))) { |
1365 | qdio_release_q(q); | 1363 | qdio_release_q(q); |
1366 | #ifdef QDIO_PERFORMANCE_STATS | 1364 | if (qdio_performance_stats) |
1367 | ii_p_c++; | 1365 | ii_p_c++; |
1368 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
1369 | /* | 1366 | /* |
1370 | * as we might just be about to stop polling, we make | 1367 | * as we might just be about to stop polling, we make |
1371 | * sure that we check again at least once more | 1368 | * sure that we check again at least once more |
@@ -1373,9 +1370,8 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) | |||
1373 | tiqdio_sched_tl(); | 1370 | tiqdio_sched_tl(); |
1374 | return; | 1371 | return; |
1375 | } | 1372 | } |
1376 | #ifdef QDIO_PERFORMANCE_STATS | 1373 | if (qdio_performance_stats) |
1377 | ii_p_nc++; | 1374 | ii_p_nc++; |
1378 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
1379 | if (unlikely(atomic_read(&q->is_in_shutdown))) { | 1375 | if (unlikely(atomic_read(&q->is_in_shutdown))) { |
1380 | qdio_unmark_q(q); | 1376 | qdio_unmark_q(q); |
1381 | goto out; | 1377 | goto out; |
@@ -1416,11 +1412,11 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) | |||
1416 | irq_ptr = (struct qdio_irq*)q->irq_ptr; | 1412 | irq_ptr = (struct qdio_irq*)q->irq_ptr; |
1417 | for (i=0;i<irq_ptr->no_output_qs;i++) { | 1413 | for (i=0;i<irq_ptr->no_output_qs;i++) { |
1418 | oq = irq_ptr->output_qs[i]; | 1414 | oq = irq_ptr->output_qs[i]; |
1419 | #ifdef QDIO_PERFORMANCE_STATS | 1415 | if (!qdio_is_outbound_q_done(oq)) { |
1420 | perf_stats.tl_runs--; | 1416 | if (qdio_performance_stats) |
1421 | #endif /* QDIO_PERFORMANCE_STATS */ | 1417 | perf_stats.tl_runs--; |
1422 | if (!qdio_is_outbound_q_done(oq)) | ||
1423 | __qdio_outbound_processing(oq); | 1418 | __qdio_outbound_processing(oq); |
1419 | } | ||
1424 | } | 1420 | } |
1425 | } | 1421 | } |
1426 | 1422 | ||
@@ -1457,9 +1453,8 @@ __qdio_inbound_processing(struct qdio_q *q) | |||
1457 | 1453 | ||
1458 | if (unlikely(qdio_reserve_q(q))) { | 1454 | if (unlikely(qdio_reserve_q(q))) { |
1459 | qdio_release_q(q); | 1455 | qdio_release_q(q); |
1460 | #ifdef QDIO_PERFORMANCE_STATS | 1456 | if (qdio_performance_stats) |
1461 | i_p_c++; | 1457 | i_p_c++; |
1462 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
1463 | /* as we're sissies, we'll check next time */ | 1458 | /* as we're sissies, we'll check next time */ |
1464 | if (likely(!atomic_read(&q->is_in_shutdown))) { | 1459 | if (likely(!atomic_read(&q->is_in_shutdown))) { |
1465 | qdio_mark_q(q); | 1460 | qdio_mark_q(q); |
@@ -1467,10 +1462,10 @@ __qdio_inbound_processing(struct qdio_q *q) | |||
1467 | } | 1462 | } |
1468 | return; | 1463 | return; |
1469 | } | 1464 | } |
1470 | #ifdef QDIO_PERFORMANCE_STATS | 1465 | if (qdio_performance_stats) { |
1471 | i_p_nc++; | 1466 | i_p_nc++; |
1472 | perf_stats.tl_runs++; | 1467 | perf_stats.tl_runs++; |
1473 | #endif /* QDIO_PERFORMANCE_STATS */ | 1468 | } |
1474 | 1469 | ||
1475 | again: | 1470 | again: |
1476 | if (qdio_has_inbound_q_moved(q)) { | 1471 | if (qdio_has_inbound_q_moved(q)) { |
@@ -1516,9 +1511,8 @@ tiqdio_reset_processing_state(struct qdio_q *q, int q_laps) | |||
1516 | 1511 | ||
1517 | if (unlikely(qdio_reserve_q(q))) { | 1512 | if (unlikely(qdio_reserve_q(q))) { |
1518 | qdio_release_q(q); | 1513 | qdio_release_q(q); |
1519 | #ifdef QDIO_PERFORMANCE_STATS | 1514 | if (qdio_performance_stats) |
1520 | ii_p_c++; | 1515 | ii_p_c++; |
1521 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
1522 | /* | 1516 | /* |
1523 | * as we might just be about to stop polling, we make | 1517 | * as we might just be about to stop polling, we make |
1524 | * sure that we check again at least once more | 1518 | * sure that we check again at least once more |
@@ -1609,9 +1603,8 @@ tiqdio_tl(unsigned long data) | |||
1609 | { | 1603 | { |
1610 | QDIO_DBF_TEXT4(0,trace,"iqdio_tl"); | 1604 | QDIO_DBF_TEXT4(0,trace,"iqdio_tl"); |
1611 | 1605 | ||
1612 | #ifdef QDIO_PERFORMANCE_STATS | 1606 | if (qdio_performance_stats) |
1613 | perf_stats.tl_runs++; | 1607 | perf_stats.tl_runs++; |
1614 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
1615 | 1608 | ||
1616 | tiqdio_inbound_checks(); | 1609 | tiqdio_inbound_checks(); |
1617 | } | 1610 | } |
@@ -1918,10 +1911,10 @@ tiqdio_thinint_handler(void) | |||
1918 | { | 1911 | { |
1919 | QDIO_DBF_TEXT4(0,trace,"thin_int"); | 1912 | QDIO_DBF_TEXT4(0,trace,"thin_int"); |
1920 | 1913 | ||
1921 | #ifdef QDIO_PERFORMANCE_STATS | 1914 | if (qdio_performance_stats) { |
1922 | perf_stats.thinints++; | 1915 | perf_stats.thinints++; |
1923 | perf_stats.start_time_inbound=NOW; | 1916 | perf_stats.start_time_inbound=NOW; |
1924 | #endif /* QDIO_PERFORMANCE_STATS */ | 1917 | } |
1925 | 1918 | ||
1926 | /* SVS only when needed: | 1919 | /* SVS only when needed: |
1927 | * issue SVS to benefit from iqdio interrupt avoidance | 1920 | * issue SVS to benefit from iqdio interrupt avoidance |
@@ -1976,18 +1969,17 @@ qdio_handle_pci(struct qdio_irq *irq_ptr) | |||
1976 | int i; | 1969 | int i; |
1977 | struct qdio_q *q; | 1970 | struct qdio_q *q; |
1978 | 1971 | ||
1979 | #ifdef QDIO_PERFORMANCE_STATS | 1972 | if (qdio_performance_stats) { |
1980 | perf_stats.pcis++; | 1973 | perf_stats.pcis++; |
1981 | perf_stats.start_time_inbound=NOW; | 1974 | perf_stats.start_time_inbound=NOW; |
1982 | #endif /* QDIO_PERFORMANCE_STATS */ | 1975 | } |
1983 | for (i=0;i<irq_ptr->no_input_qs;i++) { | 1976 | for (i=0;i<irq_ptr->no_input_qs;i++) { |
1984 | q=irq_ptr->input_qs[i]; | 1977 | q=irq_ptr->input_qs[i]; |
1985 | if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) | 1978 | if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) |
1986 | qdio_mark_q(q); | 1979 | qdio_mark_q(q); |
1987 | else { | 1980 | else { |
1988 | #ifdef QDIO_PERFORMANCE_STATS | 1981 | if (qdio_performance_stats) |
1989 | perf_stats.tl_runs--; | 1982 | perf_stats.tl_runs--; |
1990 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
1991 | __qdio_inbound_processing(q); | 1983 | __qdio_inbound_processing(q); |
1992 | } | 1984 | } |
1993 | } | 1985 | } |
@@ -1995,11 +1987,10 @@ qdio_handle_pci(struct qdio_irq *irq_ptr) | |||
1995 | return; | 1987 | return; |
1996 | for (i=0;i<irq_ptr->no_output_qs;i++) { | 1988 | for (i=0;i<irq_ptr->no_output_qs;i++) { |
1997 | q=irq_ptr->output_qs[i]; | 1989 | 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)) | 1990 | if (qdio_is_outbound_q_done(q)) |
2002 | continue; | 1991 | continue; |
1992 | if (qdio_performance_stats) | ||
1993 | perf_stats.tl_runs--; | ||
2003 | if (!irq_ptr->sync_done_on_outb_pcis) | 1994 | if (!irq_ptr->sync_done_on_outb_pcis) |
2004 | SYNC_MEMORY; | 1995 | SYNC_MEMORY; |
2005 | __qdio_outbound_processing(q); | 1996 | __qdio_outbound_processing(q); |
@@ -3460,19 +3451,18 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, | |||
3460 | struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; | 3451 | struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; |
3461 | 3452 | ||
3462 | /* This is the outbound handling of queues */ | 3453 | /* This is the outbound handling of queues */ |
3463 | #ifdef QDIO_PERFORMANCE_STATS | 3454 | if (qdio_performance_stats) |
3464 | perf_stats.start_time_outbound=NOW; | 3455 | perf_stats.start_time_outbound=NOW; |
3465 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
3466 | 3456 | ||
3467 | qdio_do_qdio_fill_output(q,qidx,count,buffers); | 3457 | qdio_do_qdio_fill_output(q,qidx,count,buffers); |
3468 | 3458 | ||
3469 | used_elements=atomic_add_return(count, &q->number_of_buffers_used) - count; | 3459 | used_elements=atomic_add_return(count, &q->number_of_buffers_used) - count; |
3470 | 3460 | ||
3471 | if (callflags&QDIO_FLAG_DONT_SIGA) { | 3461 | if (callflags&QDIO_FLAG_DONT_SIGA) { |
3472 | #ifdef QDIO_PERFORMANCE_STATS | 3462 | if (qdio_performance_stats) { |
3473 | perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; | 3463 | perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; |
3474 | perf_stats.outbound_cnt++; | 3464 | perf_stats.outbound_cnt++; |
3475 | #endif /* QDIO_PERFORMANCE_STATS */ | 3465 | } |
3476 | return; | 3466 | return; |
3477 | } | 3467 | } |
3478 | if (q->is_iqdio_q) { | 3468 | if (q->is_iqdio_q) { |
@@ -3502,9 +3492,8 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, | |||
3502 | qdio_kick_outbound_q(q); | 3492 | qdio_kick_outbound_q(q); |
3503 | } else { | 3493 | } else { |
3504 | QDIO_DBF_TEXT3(0,trace, "fast-req"); | 3494 | QDIO_DBF_TEXT3(0,trace, "fast-req"); |
3505 | #ifdef QDIO_PERFORMANCE_STATS | 3495 | if (qdio_performance_stats) |
3506 | perf_stats.fast_reqs++; | 3496 | perf_stats.fast_reqs++; |
3507 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
3508 | } | 3497 | } |
3509 | } | 3498 | } |
3510 | /* | 3499 | /* |
@@ -3515,10 +3504,10 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, | |||
3515 | __qdio_outbound_processing(q); | 3504 | __qdio_outbound_processing(q); |
3516 | } | 3505 | } |
3517 | 3506 | ||
3518 | #ifdef QDIO_PERFORMANCE_STATS | 3507 | if (qdio_performance_stats) { |
3519 | perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; | 3508 | perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; |
3520 | perf_stats.outbound_cnt++; | 3509 | perf_stats.outbound_cnt++; |
3521 | #endif /* QDIO_PERFORMANCE_STATS */ | 3510 | } |
3522 | } | 3511 | } |
3523 | 3512 | ||
3524 | /* count must be 1 in iqdio */ | 3513 | /* count must be 1 in iqdio */ |
@@ -3576,7 +3565,6 @@ do_QDIO(struct ccw_device *cdev,unsigned int callflags, | |||
3576 | return 0; | 3565 | return 0; |
3577 | } | 3566 | } |
3578 | 3567 | ||
3579 | #ifdef QDIO_PERFORMANCE_STATS | ||
3580 | static int | 3568 | static int |
3581 | qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, | 3569 | qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, |
3582 | int buffer_length, int *eof, void *data) | 3570 | int buffer_length, int *eof, void *data) |
@@ -3592,29 +3580,29 @@ qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, | |||
3592 | _OUTP_IT("i_p_nc/c=%lu/%lu\n",i_p_nc,i_p_c); | 3580 | _OUTP_IT("i_p_nc/c=%lu/%lu\n",i_p_nc,i_p_c); |
3593 | _OUTP_IT("ii_p_nc/c=%lu/%lu\n",ii_p_nc,ii_p_c); | 3581 | _OUTP_IT("ii_p_nc/c=%lu/%lu\n",ii_p_nc,ii_p_c); |
3594 | _OUTP_IT("o_p_nc/c=%lu/%lu\n",o_p_nc,o_p_c); | 3582 | _OUTP_IT("o_p_nc/c=%lu/%lu\n",o_p_nc,o_p_c); |
3595 | _OUTP_IT("Number of tasklet runs (total) : %u\n", | 3583 | _OUTP_IT("Number of tasklet runs (total) : %lu\n", |
3596 | perf_stats.tl_runs); | 3584 | perf_stats.tl_runs); |
3597 | _OUTP_IT("\n"); | 3585 | _OUTP_IT("\n"); |
3598 | _OUTP_IT("Number of SIGA sync's issued : %u\n", | 3586 | _OUTP_IT("Number of SIGA sync's issued : %lu\n", |
3599 | perf_stats.siga_syncs); | 3587 | perf_stats.siga_syncs); |
3600 | _OUTP_IT("Number of SIGA in's issued : %u\n", | 3588 | _OUTP_IT("Number of SIGA in's issued : %lu\n", |
3601 | perf_stats.siga_ins); | 3589 | perf_stats.siga_ins); |
3602 | _OUTP_IT("Number of SIGA out's issued : %u\n", | 3590 | _OUTP_IT("Number of SIGA out's issued : %lu\n", |
3603 | perf_stats.siga_outs); | 3591 | perf_stats.siga_outs); |
3604 | _OUTP_IT("Number of PCIs caught : %u\n", | 3592 | _OUTP_IT("Number of PCIs caught : %lu\n", |
3605 | perf_stats.pcis); | 3593 | perf_stats.pcis); |
3606 | _OUTP_IT("Number of adapter interrupts caught : %u\n", | 3594 | _OUTP_IT("Number of adapter interrupts caught : %lu\n", |
3607 | perf_stats.thinints); | 3595 | perf_stats.thinints); |
3608 | _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %u\n", | 3596 | _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %lu\n", |
3609 | perf_stats.fast_reqs); | 3597 | perf_stats.fast_reqs); |
3610 | _OUTP_IT("\n"); | 3598 | _OUTP_IT("\n"); |
3611 | _OUTP_IT("Total time of all inbound actions (us) incl. UL : %u\n", | 3599 | _OUTP_IT("Total time of all inbound actions (us) incl. UL : %lu\n", |
3612 | perf_stats.inbound_time); | 3600 | perf_stats.inbound_time); |
3613 | _OUTP_IT("Number of inbound transfers : %u\n", | 3601 | _OUTP_IT("Number of inbound transfers : %lu\n", |
3614 | perf_stats.inbound_cnt); | 3602 | perf_stats.inbound_cnt); |
3615 | _OUTP_IT("Total time of all outbound do_QDIOs (us) : %u\n", | 3603 | _OUTP_IT("Total time of all outbound do_QDIOs (us) : %lu\n", |
3616 | perf_stats.outbound_time); | 3604 | perf_stats.outbound_time); |
3617 | _OUTP_IT("Number of do_QDIOs outbound : %u\n", | 3605 | _OUTP_IT("Number of do_QDIOs outbound : %lu\n", |
3618 | perf_stats.outbound_cnt); | 3606 | perf_stats.outbound_cnt); |
3619 | _OUTP_IT("\n"); | 3607 | _OUTP_IT("\n"); |
3620 | 3608 | ||
@@ -3622,12 +3610,10 @@ qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, | |||
3622 | } | 3610 | } |
3623 | 3611 | ||
3624 | static struct proc_dir_entry *qdio_perf_proc_file; | 3612 | static struct proc_dir_entry *qdio_perf_proc_file; |
3625 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
3626 | 3613 | ||
3627 | static void | 3614 | static void |
3628 | qdio_add_procfs_entry(void) | 3615 | qdio_add_procfs_entry(void) |
3629 | { | 3616 | { |
3630 | #ifdef QDIO_PERFORMANCE_STATS | ||
3631 | proc_perf_file_registration=0; | 3617 | proc_perf_file_registration=0; |
3632 | qdio_perf_proc_file=create_proc_entry(QDIO_PERF, | 3618 | qdio_perf_proc_file=create_proc_entry(QDIO_PERF, |
3633 | S_IFREG|0444,&proc_root); | 3619 | S_IFREG|0444,&proc_root); |
@@ -3639,20 +3625,58 @@ qdio_add_procfs_entry(void) | |||
3639 | QDIO_PRINT_WARN("was not able to register perf. " \ | 3625 | QDIO_PRINT_WARN("was not able to register perf. " \ |
3640 | "proc-file (%i).\n", | 3626 | "proc-file (%i).\n", |
3641 | proc_perf_file_registration); | 3627 | proc_perf_file_registration); |
3642 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
3643 | } | 3628 | } |
3644 | 3629 | ||
3645 | static void | 3630 | static void |
3646 | qdio_remove_procfs_entry(void) | 3631 | qdio_remove_procfs_entry(void) |
3647 | { | 3632 | { |
3648 | #ifdef QDIO_PERFORMANCE_STATS | ||
3649 | perf_stats.tl_runs=0; | 3633 | perf_stats.tl_runs=0; |
3650 | 3634 | ||
3651 | if (!proc_perf_file_registration) /* means if it went ok earlier */ | 3635 | if (!proc_perf_file_registration) /* means if it went ok earlier */ |
3652 | remove_proc_entry(QDIO_PERF,&proc_root); | 3636 | remove_proc_entry(QDIO_PERF,&proc_root); |
3653 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
3654 | } | 3637 | } |
3655 | 3638 | ||
3639 | /** | ||
3640 | * attributes in sysfs | ||
3641 | *****************************************************************************/ | ||
3642 | |||
3643 | static ssize_t | ||
3644 | qdio_performance_stats_show(struct bus_type *bus, char *buf) | ||
3645 | { | ||
3646 | return sprintf(buf, "%i\n", qdio_performance_stats ? 1 : 0); | ||
3647 | } | ||
3648 | |||
3649 | static ssize_t | ||
3650 | qdio_performance_stats_store(struct bus_type *bus, const char *buf, size_t count) | ||
3651 | { | ||
3652 | char *tmp; | ||
3653 | int i; | ||
3654 | |||
3655 | i = simple_strtoul(buf, &tmp, 16); | ||
3656 | if ((i == 0) || (i == 1)) { | ||
3657 | if (i == qdio_performance_stats) | ||
3658 | return count; | ||
3659 | qdio_performance_stats = i; | ||
3660 | if (i==0) { | ||
3661 | /* reset perf. stat. info */ | ||
3662 | i_p_nc = 0; | ||
3663 | i_p_c = 0; | ||
3664 | ii_p_nc = 0; | ||
3665 | ii_p_c = 0; | ||
3666 | o_p_nc = 0; | ||
3667 | o_p_c = 0; | ||
3668 | memset(&perf_stats, 0, sizeof(struct qdio_perf_stats)); | ||
3669 | } | ||
3670 | } else { | ||
3671 | QDIO_PRINT_WARN("QDIO performance_stats: write 0 or 1 to this file!\n"); | ||
3672 | return -EINVAL; | ||
3673 | } | ||
3674 | return count; | ||
3675 | } | ||
3676 | |||
3677 | static BUS_ATTR(qdio_performance_stats, 0644, qdio_performance_stats_show, | ||
3678 | qdio_performance_stats_store); | ||
3679 | |||
3656 | static void | 3680 | static void |
3657 | tiqdio_register_thinints(void) | 3681 | tiqdio_register_thinints(void) |
3658 | { | 3682 | { |
@@ -3697,6 +3721,7 @@ qdio_release_qdio_memory(void) | |||
3697 | kfree(indicators); | 3721 | kfree(indicators); |
3698 | } | 3722 | } |
3699 | 3723 | ||
3724 | |||
3700 | static void | 3725 | static void |
3701 | qdio_unregister_dbf_views(void) | 3726 | qdio_unregister_dbf_views(void) |
3702 | { | 3727 | { |
@@ -3798,9 +3823,7 @@ static int __init | |||
3798 | init_QDIO(void) | 3823 | init_QDIO(void) |
3799 | { | 3824 | { |
3800 | int res; | 3825 | int res; |
3801 | #ifdef QDIO_PERFORMANCE_STATS | ||
3802 | void *ptr; | 3826 | void *ptr; |
3803 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
3804 | 3827 | ||
3805 | printk("qdio: loading %s\n",version); | 3828 | printk("qdio: loading %s\n",version); |
3806 | 3829 | ||
@@ -3813,13 +3836,12 @@ init_QDIO(void) | |||
3813 | return res; | 3836 | return res; |
3814 | 3837 | ||
3815 | QDIO_DBF_TEXT0(0,setup,"initQDIO"); | 3838 | QDIO_DBF_TEXT0(0,setup,"initQDIO"); |
3839 | res = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); | ||
3816 | 3840 | ||
3817 | #ifdef QDIO_PERFORMANCE_STATS | 3841 | memset((void*)&perf_stats,0,sizeof(perf_stats)); |
3818 | memset((void*)&perf_stats,0,sizeof(perf_stats)); | ||
3819 | QDIO_DBF_TEXT0(0,setup,"perfstat"); | 3842 | QDIO_DBF_TEXT0(0,setup,"perfstat"); |
3820 | ptr=&perf_stats; | 3843 | ptr=&perf_stats; |
3821 | QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*)); | 3844 | QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*)); |
3822 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
3823 | 3845 | ||
3824 | qdio_add_procfs_entry(); | 3846 | qdio_add_procfs_entry(); |
3825 | 3847 | ||
@@ -3843,7 +3865,7 @@ cleanup_QDIO(void) | |||
3843 | qdio_release_qdio_memory(); | 3865 | qdio_release_qdio_memory(); |
3844 | qdio_unregister_dbf_views(); | 3866 | qdio_unregister_dbf_views(); |
3845 | mempool_destroy(qdio_mempool_scssc); | 3867 | mempool_destroy(qdio_mempool_scssc); |
3846 | 3868 | bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); | |
3847 | printk("qdio: %s: module removed\n",version); | 3869 | printk("qdio: %s: module removed\n",version); |
3848 | } | 3870 | } |
3849 | 3871 | ||
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 42927c1b7451..ec9af72b2afc 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
@@ -12,10 +12,6 @@ | |||
12 | #endif /* CONFIG_QDIO_DEBUG */ | 12 | #endif /* CONFIG_QDIO_DEBUG */ |
13 | #define QDIO_USE_PROCESSING_STATE | 13 | #define QDIO_USE_PROCESSING_STATE |
14 | 14 | ||
15 | #ifdef CONFIG_QDIO_PERF_STATS | ||
16 | #define QDIO_PERFORMANCE_STATS | ||
17 | #endif /* CONFIG_QDIO_PERF_STATS */ | ||
18 | |||
19 | #define QDIO_MINIMAL_BH_RELIEF_TIME 16 | 15 | #define QDIO_MINIMAL_BH_RELIEF_TIME 16 |
20 | #define QDIO_TIMER_POLL_VALUE 1 | 16 | #define QDIO_TIMER_POLL_VALUE 1 |
21 | #define IQDIO_TIMER_POLL_VALUE 1 | 17 | #define IQDIO_TIMER_POLL_VALUE 1 |
@@ -409,25 +405,23 @@ do_clear_global_summary(void) | |||
409 | #define CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS 0x08 | 405 | #define CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS 0x08 |
410 | #define CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS 0x04 | 406 | #define CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS 0x04 |
411 | 407 | ||
412 | #ifdef QDIO_PERFORMANCE_STATS | ||
413 | struct qdio_perf_stats { | 408 | struct qdio_perf_stats { |
414 | unsigned int tl_runs; | 409 | unsigned long tl_runs; |
415 | 410 | ||
416 | unsigned int siga_outs; | 411 | unsigned long siga_outs; |
417 | unsigned int siga_ins; | 412 | unsigned long siga_ins; |
418 | unsigned int siga_syncs; | 413 | unsigned long siga_syncs; |
419 | unsigned int pcis; | 414 | unsigned long pcis; |
420 | unsigned int thinints; | 415 | unsigned long thinints; |
421 | unsigned int fast_reqs; | 416 | unsigned long fast_reqs; |
422 | 417 | ||
423 | __u64 start_time_outbound; | 418 | __u64 start_time_outbound; |
424 | unsigned int outbound_cnt; | 419 | unsigned long outbound_cnt; |
425 | unsigned int outbound_time; | 420 | unsigned long outbound_time; |
426 | __u64 start_time_inbound; | 421 | __u64 start_time_inbound; |
427 | unsigned int inbound_cnt; | 422 | unsigned long inbound_cnt; |
428 | unsigned int inbound_time; | 423 | unsigned long inbound_time; |
429 | }; | 424 | }; |
430 | #endif /* QDIO_PERFORMANCE_STATS */ | ||
431 | 425 | ||
432 | /* unlikely as the later the better */ | 426 | /* unlikely as the later the better */ |
433 | #define SYNC_MEMORY if (unlikely(q->siga_sync)) qdio_siga_sync_q(q) | 427 | #define SYNC_MEMORY if (unlikely(q->siga_sync)) qdio_siga_sync_q(q) |