4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2012, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 #define DEBUG_SUBSYSTEM S_CLASS
38 #include <asm/statfs.h>
39 #include "../include/obd_cksum.h"
40 #include "../include/obd_class.h"
41 #include "../include/lprocfs_status.h"
42 #include <linux/seq_file.h>
43 #include "osc_internal.h"
45 static int osc_active_seq_show(struct seq_file
*m
, void *v
)
47 struct obd_device
*dev
= m
->private;
50 LPROCFS_CLIMP_CHECK(dev
);
51 rc
= seq_printf(m
, "%d\n", !dev
->u
.cli
.cl_import
->imp_deactive
);
52 LPROCFS_CLIMP_EXIT(dev
);
56 static ssize_t
osc_active_seq_write(struct file
*file
, const char *buffer
,
57 size_t count
, loff_t
*off
)
59 struct obd_device
*dev
= ((struct seq_file
*)file
->private_data
)->private;
62 rc
= lprocfs_write_helper(buffer
, count
, &val
);
65 if (val
< 0 || val
> 1)
69 if (dev
->u
.cli
.cl_import
->imp_deactive
== val
)
70 rc
= ptlrpc_set_import_active(dev
->u
.cli
.cl_import
, val
);
72 CDEBUG(D_CONFIG
, "activate %d: ignoring repeat request\n", val
);
76 LPROC_SEQ_FOPS(osc_active
);
78 static int osc_max_rpcs_in_flight_seq_show(struct seq_file
*m
, void *v
)
80 struct obd_device
*dev
= m
->private;
81 struct client_obd
*cli
= &dev
->u
.cli
;
84 client_obd_list_lock(&cli
->cl_loi_list_lock
);
85 rc
= seq_printf(m
, "%u\n", cli
->cl_max_rpcs_in_flight
);
86 client_obd_list_unlock(&cli
->cl_loi_list_lock
);
90 static ssize_t
osc_max_rpcs_in_flight_seq_write(struct file
*file
,
91 const char *buffer
, size_t count
, loff_t
*off
)
93 struct obd_device
*dev
= ((struct seq_file
*)file
->private_data
)->private;
94 struct client_obd
*cli
= &dev
->u
.cli
;
95 struct ptlrpc_request_pool
*pool
= cli
->cl_import
->imp_rq_pool
;
98 rc
= lprocfs_write_helper(buffer
, count
, &val
);
102 if (val
< 1 || val
> OSC_MAX_RIF_MAX
)
105 LPROCFS_CLIMP_CHECK(dev
);
106 if (pool
&& val
> cli
->cl_max_rpcs_in_flight
)
107 pool
->prp_populate(pool
, val
-cli
->cl_max_rpcs_in_flight
);
109 client_obd_list_lock(&cli
->cl_loi_list_lock
);
110 cli
->cl_max_rpcs_in_flight
= val
;
111 client_obd_list_unlock(&cli
->cl_loi_list_lock
);
113 LPROCFS_CLIMP_EXIT(dev
);
116 LPROC_SEQ_FOPS(osc_max_rpcs_in_flight
);
118 static int osc_max_dirty_mb_seq_show(struct seq_file
*m
, void *v
)
120 struct obd_device
*dev
= m
->private;
121 struct client_obd
*cli
= &dev
->u
.cli
;
125 client_obd_list_lock(&cli
->cl_loi_list_lock
);
126 val
= cli
->cl_dirty_max
;
127 client_obd_list_unlock(&cli
->cl_loi_list_lock
);
130 return lprocfs_seq_read_frac_helper(m
, val
, mult
);
133 static ssize_t
osc_max_dirty_mb_seq_write(struct file
*file
, const char *buffer
,
134 size_t count
, loff_t
*off
)
136 struct obd_device
*dev
= ((struct seq_file
*)file
->private_data
)->private;
137 struct client_obd
*cli
= &dev
->u
.cli
;
138 int pages_number
, mult
, rc
;
140 mult
= 1 << (20 - PAGE_CACHE_SHIFT
);
141 rc
= lprocfs_write_frac_helper(buffer
, count
, &pages_number
, mult
);
145 if (pages_number
<= 0 ||
146 pages_number
> OSC_MAX_DIRTY_MB_MAX
<< (20 - PAGE_CACHE_SHIFT
) ||
147 pages_number
> totalram_pages
/ 4) /* 1/4 of RAM */
150 client_obd_list_lock(&cli
->cl_loi_list_lock
);
151 cli
->cl_dirty_max
= (u32
)(pages_number
<< PAGE_CACHE_SHIFT
);
152 osc_wake_cache_waiters(cli
);
153 client_obd_list_unlock(&cli
->cl_loi_list_lock
);
157 LPROC_SEQ_FOPS(osc_max_dirty_mb
);
159 static int osc_cached_mb_seq_show(struct seq_file
*m
, void *v
)
161 struct obd_device
*dev
= m
->private;
162 struct client_obd
*cli
= &dev
->u
.cli
;
163 int shift
= 20 - PAGE_CACHE_SHIFT
;
169 (atomic_read(&cli
->cl_lru_in_list
) +
170 atomic_read(&cli
->cl_lru_busy
)) >> shift
,
171 atomic_read(&cli
->cl_lru_busy
));
176 /* shrink the number of caching pages to a specific number */
177 static ssize_t
osc_cached_mb_seq_write(struct file
*file
,
178 const char __user
*buffer
,
179 size_t count
, loff_t
*off
)
181 struct obd_device
*dev
= ((struct seq_file
*)file
->private_data
)->private;
182 struct client_obd
*cli
= &dev
->u
.cli
;
183 int pages_number
, mult
, rc
;
186 if (count
>= sizeof(kernbuf
))
189 if (copy_from_user(kernbuf
, buffer
, count
))
193 mult
= 1 << (20 - PAGE_CACHE_SHIFT
);
194 buffer
+= lprocfs_find_named_value(kernbuf
, "used_mb:", &count
) -
196 rc
= lprocfs_write_frac_helper(buffer
, count
, &pages_number
, mult
);
200 if (pages_number
< 0)
203 rc
= atomic_read(&cli
->cl_lru_in_list
) - pages_number
;
205 (void)osc_lru_shrink(cli
, rc
);
209 LPROC_SEQ_FOPS(osc_cached_mb
);
211 static int osc_cur_dirty_bytes_seq_show(struct seq_file
*m
, void *v
)
213 struct obd_device
*dev
= m
->private;
214 struct client_obd
*cli
= &dev
->u
.cli
;
217 client_obd_list_lock(&cli
->cl_loi_list_lock
);
218 rc
= seq_printf(m
, "%lu\n", cli
->cl_dirty
);
219 client_obd_list_unlock(&cli
->cl_loi_list_lock
);
222 LPROC_SEQ_FOPS_RO(osc_cur_dirty_bytes
);
224 static int osc_cur_grant_bytes_seq_show(struct seq_file
*m
, void *v
)
226 struct obd_device
*dev
= m
->private;
227 struct client_obd
*cli
= &dev
->u
.cli
;
230 client_obd_list_lock(&cli
->cl_loi_list_lock
);
231 rc
= seq_printf(m
, "%lu\n", cli
->cl_avail_grant
);
232 client_obd_list_unlock(&cli
->cl_loi_list_lock
);
236 static ssize_t
osc_cur_grant_bytes_seq_write(struct file
*file
, const char *buffer
,
237 size_t count
, loff_t
*off
)
239 struct obd_device
*obd
= ((struct seq_file
*)file
->private_data
)->private;
240 struct client_obd
*cli
= &obd
->u
.cli
;
247 rc
= lprocfs_write_u64_helper(buffer
, count
, &val
);
251 /* this is only for shrinking grant */
252 client_obd_list_lock(&cli
->cl_loi_list_lock
);
253 if (val
>= cli
->cl_avail_grant
) {
254 client_obd_list_unlock(&cli
->cl_loi_list_lock
);
257 client_obd_list_unlock(&cli
->cl_loi_list_lock
);
259 LPROCFS_CLIMP_CHECK(obd
);
260 if (cli
->cl_import
->imp_state
== LUSTRE_IMP_FULL
)
261 rc
= osc_shrink_grant_to_target(cli
, val
);
262 LPROCFS_CLIMP_EXIT(obd
);
267 LPROC_SEQ_FOPS(osc_cur_grant_bytes
);
269 static int osc_cur_lost_grant_bytes_seq_show(struct seq_file
*m
, void *v
)
271 struct obd_device
*dev
= m
->private;
272 struct client_obd
*cli
= &dev
->u
.cli
;
275 client_obd_list_lock(&cli
->cl_loi_list_lock
);
276 rc
= seq_printf(m
, "%lu\n", cli
->cl_lost_grant
);
277 client_obd_list_unlock(&cli
->cl_loi_list_lock
);
280 LPROC_SEQ_FOPS_RO(osc_cur_lost_grant_bytes
);
282 static int osc_grant_shrink_interval_seq_show(struct seq_file
*m
, void *v
)
284 struct obd_device
*obd
= m
->private;
288 return seq_printf(m
, "%d\n",
289 obd
->u
.cli
.cl_grant_shrink_interval
);
292 static ssize_t
osc_grant_shrink_interval_seq_write(struct file
*file
,
293 const char *buffer
, size_t count
, loff_t
*off
)
295 struct obd_device
*obd
= ((struct seq_file
*)file
->private_data
)->private;
301 rc
= lprocfs_write_helper(buffer
, count
, &val
);
308 obd
->u
.cli
.cl_grant_shrink_interval
= val
;
312 LPROC_SEQ_FOPS(osc_grant_shrink_interval
);
314 static int osc_checksum_seq_show(struct seq_file
*m
, void *v
)
316 struct obd_device
*obd
= m
->private;
321 return seq_printf(m
, "%d\n",
322 obd
->u
.cli
.cl_checksum
? 1 : 0);
325 static ssize_t
osc_checksum_seq_write(struct file
*file
, const char *buffer
,
326 size_t count
, loff_t
*off
)
328 struct obd_device
*obd
= ((struct seq_file
*)file
->private_data
)->private;
334 rc
= lprocfs_write_helper(buffer
, count
, &val
);
338 obd
->u
.cli
.cl_checksum
= (val
? 1 : 0);
342 LPROC_SEQ_FOPS(osc_checksum
);
344 static int osc_checksum_type_seq_show(struct seq_file
*m
, void *v
)
346 struct obd_device
*obd
= m
->private;
353 for (i
= 0; i
< ARRAY_SIZE(cksum_name
); i
++) {
354 if (((1 << i
) & obd
->u
.cli
.cl_supp_cksum_types
) == 0)
356 if (obd
->u
.cli
.cl_cksum_type
== (1 << i
))
357 seq_printf(m
, "[%s] ", cksum_name
[i
]);
359 seq_printf(m
, "%s ", cksum_name
[i
]);
365 static ssize_t
osc_checksum_type_seq_write(struct file
*file
, const char *buffer
,
366 size_t count
, loff_t
*off
)
368 struct obd_device
*obd
= ((struct seq_file
*)file
->private_data
)->private;
376 if (count
> sizeof(kernbuf
) - 1)
378 if (copy_from_user(kernbuf
, buffer
, count
))
380 if (count
> 0 && kernbuf
[count
- 1] == '\n')
381 kernbuf
[count
- 1] = '\0';
383 kernbuf
[count
] = '\0';
385 for (i
= 0; i
< ARRAY_SIZE(cksum_name
); i
++) {
386 if (((1 << i
) & obd
->u
.cli
.cl_supp_cksum_types
) == 0)
388 if (!strcmp(kernbuf
, cksum_name
[i
])) {
389 obd
->u
.cli
.cl_cksum_type
= 1 << i
;
395 LPROC_SEQ_FOPS(osc_checksum_type
);
397 static int osc_resend_count_seq_show(struct seq_file
*m
, void *v
)
399 struct obd_device
*obd
= m
->private;
401 return seq_printf(m
, "%u\n", atomic_read(&obd
->u
.cli
.cl_resends
));
404 static ssize_t
osc_resend_count_seq_write(struct file
*file
, const char *buffer
,
405 size_t count
, loff_t
*off
)
407 struct obd_device
*obd
= ((struct seq_file
*)file
->private_data
)->private;
410 rc
= lprocfs_write_helper(buffer
, count
, &val
);
417 atomic_set(&obd
->u
.cli
.cl_resends
, val
);
421 LPROC_SEQ_FOPS(osc_resend_count
);
423 static int osc_contention_seconds_seq_show(struct seq_file
*m
, void *v
)
425 struct obd_device
*obd
= m
->private;
426 struct osc_device
*od
= obd2osc_dev(obd
);
428 return seq_printf(m
, "%u\n", od
->od_contention_time
);
431 static ssize_t
osc_contention_seconds_seq_write(struct file
*file
, const char *buffer
,
432 size_t count
, loff_t
*off
)
434 struct obd_device
*obd
= ((struct seq_file
*)file
->private_data
)->private;
435 struct osc_device
*od
= obd2osc_dev(obd
);
437 return lprocfs_write_helper(buffer
, count
, &od
->od_contention_time
) ?:
440 LPROC_SEQ_FOPS(osc_contention_seconds
);
442 static int osc_lockless_truncate_seq_show(struct seq_file
*m
, void *v
)
444 struct obd_device
*obd
= m
->private;
445 struct osc_device
*od
= obd2osc_dev(obd
);
447 return seq_printf(m
, "%u\n", od
->od_lockless_truncate
);
450 static ssize_t
osc_lockless_truncate_seq_write(struct file
*file
, const char *buffer
,
451 size_t count
, loff_t
*off
)
453 struct obd_device
*obd
= ((struct seq_file
*)file
->private_data
)->private;
454 struct osc_device
*od
= obd2osc_dev(obd
);
456 return lprocfs_write_helper(buffer
, count
, &od
->od_lockless_truncate
) ?:
459 LPROC_SEQ_FOPS(osc_lockless_truncate
);
461 static int osc_destroys_in_flight_seq_show(struct seq_file
*m
, void *v
)
463 struct obd_device
*obd
= m
->private;
464 return seq_printf(m
, "%u\n",
465 atomic_read(&obd
->u
.cli
.cl_destroy_in_flight
));
467 LPROC_SEQ_FOPS_RO(osc_destroys_in_flight
);
469 static int osc_obd_max_pages_per_rpc_seq_show(struct seq_file
*m
, void *v
)
471 return lprocfs_obd_rd_max_pages_per_rpc(m
, m
->private);
474 static ssize_t
osc_obd_max_pages_per_rpc_seq_write(struct file
*file
,
475 const char *buffer
, size_t count
, loff_t
*off
)
477 struct obd_device
*dev
= ((struct seq_file
*)file
->private_data
)->private;
478 struct client_obd
*cli
= &dev
->u
.cli
;
479 struct obd_connect_data
*ocd
= &cli
->cl_import
->imp_connect_data
;
483 rc
= lprocfs_write_u64_helper(buffer
, count
, &val
);
487 /* if the max_pages is specified in bytes, convert to pages */
488 if (val
>= ONE_MB_BRW_SIZE
)
489 val
>>= PAGE_CACHE_SHIFT
;
491 LPROCFS_CLIMP_CHECK(dev
);
493 chunk_mask
= ~((1 << (cli
->cl_chunkbits
- PAGE_CACHE_SHIFT
)) - 1);
494 /* max_pages_per_rpc must be chunk aligned */
495 val
= (val
+ ~chunk_mask
) & chunk_mask
;
496 if (val
== 0 || val
> ocd
->ocd_brw_size
>> PAGE_CACHE_SHIFT
) {
497 LPROCFS_CLIMP_EXIT(dev
);
500 client_obd_list_lock(&cli
->cl_loi_list_lock
);
501 cli
->cl_max_pages_per_rpc
= val
;
502 client_obd_list_unlock(&cli
->cl_loi_list_lock
);
504 LPROCFS_CLIMP_EXIT(dev
);
507 LPROC_SEQ_FOPS(osc_obd_max_pages_per_rpc
);
509 LPROC_SEQ_FOPS_RO_TYPE(osc
, uuid
);
510 LPROC_SEQ_FOPS_RO_TYPE(osc
, connect_flags
);
511 LPROC_SEQ_FOPS_RO_TYPE(osc
, blksize
);
512 LPROC_SEQ_FOPS_RO_TYPE(osc
, kbytestotal
);
513 LPROC_SEQ_FOPS_RO_TYPE(osc
, kbytesfree
);
514 LPROC_SEQ_FOPS_RO_TYPE(osc
, kbytesavail
);
515 LPROC_SEQ_FOPS_RO_TYPE(osc
, filestotal
);
516 LPROC_SEQ_FOPS_RO_TYPE(osc
, filesfree
);
517 LPROC_SEQ_FOPS_RO_TYPE(osc
, server_uuid
);
518 LPROC_SEQ_FOPS_RO_TYPE(osc
, conn_uuid
);
519 LPROC_SEQ_FOPS_RO_TYPE(osc
, timeouts
);
520 LPROC_SEQ_FOPS_RO_TYPE(osc
, state
);
522 LPROC_SEQ_FOPS_WR_ONLY(osc
, ping
);
524 LPROC_SEQ_FOPS_RW_TYPE(osc
, import
);
525 LPROC_SEQ_FOPS_RW_TYPE(osc
, pinger_recov
);
527 static struct lprocfs_vars lprocfs_osc_obd_vars
[] = {
528 { "uuid", &osc_uuid_fops
, NULL
, 0 },
529 { "ping", &osc_ping_fops
, NULL
, 0222 },
530 { "connect_flags", &osc_connect_flags_fops
, NULL
, 0 },
531 { "blocksize", &osc_blksize_fops
, NULL
, 0 },
532 { "kbytestotal", &osc_kbytestotal_fops
, NULL
, 0 },
533 { "kbytesfree", &osc_kbytesfree_fops
, NULL
, 0 },
534 { "kbytesavail", &osc_kbytesavail_fops
, NULL
, 0 },
535 { "filestotal", &osc_filestotal_fops
, NULL
, 0 },
536 { "filesfree", &osc_filesfree_fops
, NULL
, 0 },
537 /*{ "filegroups", lprocfs_rd_filegroups, NULL, 0 },*/
538 { "ost_server_uuid", &osc_server_uuid_fops
, NULL
, 0 },
539 { "ost_conn_uuid", &osc_conn_uuid_fops
, NULL
, 0 },
540 { "active", &osc_active_fops
, NULL
},
541 { "max_pages_per_rpc", &osc_obd_max_pages_per_rpc_fops
, NULL
},
542 { "max_rpcs_in_flight", &osc_max_rpcs_in_flight_fops
, NULL
},
543 { "destroys_in_flight", &osc_destroys_in_flight_fops
, NULL
, 0 },
544 { "max_dirty_mb", &osc_max_dirty_mb_fops
, NULL
},
545 { "osc_cached_mb", &osc_cached_mb_fops
, NULL
},
546 { "cur_dirty_bytes", &osc_cur_dirty_bytes_fops
, NULL
, 0 },
547 { "cur_grant_bytes", &osc_cur_grant_bytes_fops
, NULL
},
548 { "cur_lost_grant_bytes", &osc_cur_lost_grant_bytes_fops
, NULL
, 0},
549 { "grant_shrink_interval", &osc_grant_shrink_interval_fops
, NULL
},
550 { "checksums", &osc_checksum_fops
, NULL
},
551 { "checksum_type", &osc_checksum_type_fops
, NULL
},
552 { "resend_count", &osc_resend_count_fops
, NULL
},
553 { "timeouts", &osc_timeouts_fops
, NULL
, 0 },
554 { "contention_seconds", &osc_contention_seconds_fops
, NULL
},
555 { "lockless_truncate", &osc_lockless_truncate_fops
, NULL
},
556 { "import", &osc_import_fops
, NULL
},
557 { "state", &osc_state_fops
, NULL
, 0 },
558 { "pinger_recov", &osc_pinger_recov_fops
, NULL
},
562 LPROC_SEQ_FOPS_RO_TYPE(osc
, numrefs
);
563 static struct lprocfs_vars lprocfs_osc_module_vars
[] = {
564 { "num_refs", &osc_numrefs_fops
, NULL
, 0 },
568 #define pct(a,b) (b ? a * 100 / b : 0)
570 static int osc_rpc_stats_seq_show(struct seq_file
*seq
, void *v
)
573 struct obd_device
*dev
= seq
->private;
574 struct client_obd
*cli
= &dev
->u
.cli
;
575 unsigned long read_tot
= 0, write_tot
= 0, read_cum
, write_cum
;
578 do_gettimeofday(&now
);
580 client_obd_list_lock(&cli
->cl_loi_list_lock
);
582 seq_printf(seq
, "snapshot_time: %lu.%lu (secs.usecs)\n",
583 now
.tv_sec
, (unsigned long)now
.tv_usec
);
584 seq_printf(seq
, "read RPCs in flight: %d\n",
585 cli
->cl_r_in_flight
);
586 seq_printf(seq
, "write RPCs in flight: %d\n",
587 cli
->cl_w_in_flight
);
588 seq_printf(seq
, "pending write pages: %d\n",
589 atomic_read(&cli
->cl_pending_w_pages
));
590 seq_printf(seq
, "pending read pages: %d\n",
591 atomic_read(&cli
->cl_pending_r_pages
));
593 seq_printf(seq
, "\n\t\t\tread\t\t\twrite\n");
594 seq_printf(seq
, "pages per rpc rpcs %% cum %% |");
595 seq_printf(seq
, " rpcs %% cum %%\n");
597 read_tot
= lprocfs_oh_sum(&cli
->cl_read_page_hist
);
598 write_tot
= lprocfs_oh_sum(&cli
->cl_write_page_hist
);
602 for (i
= 0; i
< OBD_HIST_MAX
; i
++) {
603 unsigned long r
= cli
->cl_read_page_hist
.oh_buckets
[i
];
604 unsigned long w
= cli
->cl_write_page_hist
.oh_buckets
[i
];
607 seq_printf(seq
, "%d:\t\t%10lu %3lu %3lu | %10lu %3lu %3lu\n",
608 1 << i
, r
, pct(r
, read_tot
),
609 pct(read_cum
, read_tot
), w
,
611 pct(write_cum
, write_tot
));
612 if (read_cum
== read_tot
&& write_cum
== write_tot
)
616 seq_printf(seq
, "\n\t\t\tread\t\t\twrite\n");
617 seq_printf(seq
, "rpcs in flight rpcs %% cum %% |");
618 seq_printf(seq
, " rpcs %% cum %%\n");
620 read_tot
= lprocfs_oh_sum(&cli
->cl_read_rpc_hist
);
621 write_tot
= lprocfs_oh_sum(&cli
->cl_write_rpc_hist
);
625 for (i
= 0; i
< OBD_HIST_MAX
; i
++) {
626 unsigned long r
= cli
->cl_read_rpc_hist
.oh_buckets
[i
];
627 unsigned long w
= cli
->cl_write_rpc_hist
.oh_buckets
[i
];
630 seq_printf(seq
, "%d:\t\t%10lu %3lu %3lu | %10lu %3lu %3lu\n",
631 i
, r
, pct(r
, read_tot
),
632 pct(read_cum
, read_tot
), w
,
634 pct(write_cum
, write_tot
));
635 if (read_cum
== read_tot
&& write_cum
== write_tot
)
639 seq_printf(seq
, "\n\t\t\tread\t\t\twrite\n");
640 seq_printf(seq
, "offset rpcs %% cum %% |");
641 seq_printf(seq
, " rpcs %% cum %%\n");
643 read_tot
= lprocfs_oh_sum(&cli
->cl_read_offset_hist
);
644 write_tot
= lprocfs_oh_sum(&cli
->cl_write_offset_hist
);
648 for (i
= 0; i
< OBD_HIST_MAX
; i
++) {
649 unsigned long r
= cli
->cl_read_offset_hist
.oh_buckets
[i
];
650 unsigned long w
= cli
->cl_write_offset_hist
.oh_buckets
[i
];
653 seq_printf(seq
, "%d:\t\t%10lu %3lu %3lu | %10lu %3lu %3lu\n",
654 (i
== 0) ? 0 : 1 << (i
- 1),
655 r
, pct(r
, read_tot
), pct(read_cum
, read_tot
),
656 w
, pct(w
, write_tot
), pct(write_cum
, write_tot
));
657 if (read_cum
== read_tot
&& write_cum
== write_tot
)
661 client_obd_list_unlock(&cli
->cl_loi_list_lock
);
667 static ssize_t
osc_rpc_stats_seq_write(struct file
*file
, const char *buf
,
668 size_t len
, loff_t
*off
)
670 struct seq_file
*seq
= file
->private_data
;
671 struct obd_device
*dev
= seq
->private;
672 struct client_obd
*cli
= &dev
->u
.cli
;
674 lprocfs_oh_clear(&cli
->cl_read_rpc_hist
);
675 lprocfs_oh_clear(&cli
->cl_write_rpc_hist
);
676 lprocfs_oh_clear(&cli
->cl_read_page_hist
);
677 lprocfs_oh_clear(&cli
->cl_write_page_hist
);
678 lprocfs_oh_clear(&cli
->cl_read_offset_hist
);
679 lprocfs_oh_clear(&cli
->cl_write_offset_hist
);
684 LPROC_SEQ_FOPS(osc_rpc_stats
);
686 static int osc_stats_seq_show(struct seq_file
*seq
, void *v
)
689 struct obd_device
*dev
= seq
->private;
690 struct osc_stats
*stats
= &obd2osc_dev(dev
)->od_stats
;
692 do_gettimeofday(&now
);
694 seq_printf(seq
, "snapshot_time: %lu.%lu (secs.usecs)\n",
695 now
.tv_sec
, (unsigned long)now
.tv_usec
);
696 seq_printf(seq
, "lockless_write_bytes\t\t%llu\n",
697 stats
->os_lockless_writes
);
698 seq_printf(seq
, "lockless_read_bytes\t\t%llu\n",
699 stats
->os_lockless_reads
);
700 seq_printf(seq
, "lockless_truncate\t\t%llu\n",
701 stats
->os_lockless_truncates
);
705 static ssize_t
osc_stats_seq_write(struct file
*file
, const char *buf
,
706 size_t len
, loff_t
*off
)
708 struct seq_file
*seq
= file
->private_data
;
709 struct obd_device
*dev
= seq
->private;
710 struct osc_stats
*stats
= &obd2osc_dev(dev
)->od_stats
;
712 memset(stats
, 0, sizeof(*stats
));
716 LPROC_SEQ_FOPS(osc_stats
);
718 int lproc_osc_attach_seqstat(struct obd_device
*dev
)
722 rc
= lprocfs_seq_create(dev
->obd_proc_entry
, "osc_stats", 0644,
723 &osc_stats_fops
, dev
);
725 rc
= lprocfs_obd_seq_create(dev
, "rpc_stats", 0644,
726 &osc_rpc_stats_fops
, dev
);
731 void lprocfs_osc_init_vars(struct lprocfs_static_vars
*lvars
)
733 lvars
->module_vars
= lprocfs_osc_module_vars
;
734 lvars
->obd_vars
= lprocfs_osc_obd_vars
;