aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/qdio.c
diff options
context:
space:
mode:
authorUrsula Braun <braunu@de.ibm.com>2006-12-08 09:54:18 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-12-08 09:54:18 -0500
commit34249d0f9243fce773c2fa352934ba108320e234 (patch)
treec6042a85a2bdd434e04d0d3c0b83861cec5835f2 /drivers/s390/cio/qdio.c
parent9575bf265711cabe7147a68003a56a9f19f034da (diff)
[S390] runtime switch for qdio performance statistics
Remove CONFIG_QETH_PERF_STATS and use a sysfs attribute instead. We want to have the ability to turn the statistics on/off at runtime. Signed-off-by: Ursula Braun <braunu@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/qdio.c')
-rw-r--r--drivers/s390/cio/qdio.c226
1 files changed, 124 insertions, 102 deletions
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
67static const char version[] = "QDIO base support version 2"; 68static const char version[] = "QDIO base support version 2";
69extern struct bus_type ccw_bus_type;
68 70
69#ifdef QDIO_PERFORMANCE_STATS 71static int qdio_performance_stats = 0;
70static int proc_perf_file_registration; 72static int proc_perf_file_registration;
71static unsigned long i_p_c, i_p_nc, o_p_c, o_p_nc, ii_p_c, ii_p_nc; 73static unsigned long i_p_c, i_p_nc, o_p_c, o_p_nc, ii_p_c, ii_p_nc;
72static struct qdio_perf_stats perf_stats; 74static struct qdio_perf_stats perf_stats;
73#endif /* QDIO_PERFORMANCE_STATS */
74 75
75static int hydra_thinints; 76static int hydra_thinints;
76static int is_passthrough = 0; 77static 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
1349static inline void 1347static 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
1475again: 1470again:
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
3580static int 3568static int
3581qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, 3569qdio_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
3624static struct proc_dir_entry *qdio_perf_proc_file; 3612static struct proc_dir_entry *qdio_perf_proc_file;
3625#endif /* QDIO_PERFORMANCE_STATS */
3626 3613
3627static void 3614static void
3628qdio_add_procfs_entry(void) 3615qdio_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
3645static void 3630static void
3646qdio_remove_procfs_entry(void) 3631qdio_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
3643static ssize_t
3644qdio_performance_stats_show(struct bus_type *bus, char *buf)
3645{
3646 return sprintf(buf, "%i\n", qdio_performance_stats ? 1 : 0);
3647}
3648
3649static ssize_t
3650qdio_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
3677static BUS_ATTR(qdio_performance_stats, 0644, qdio_performance_stats_show,
3678 qdio_performance_stats_store);
3679
3656static void 3680static void
3657tiqdio_register_thinints(void) 3681tiqdio_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
3700static void 3725static void
3701qdio_unregister_dbf_views(void) 3726qdio_unregister_dbf_views(void)
3702{ 3727{
@@ -3798,9 +3823,7 @@ static int __init
3798init_QDIO(void) 3823init_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