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) |
