aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/cluster/netdebug.c
diff options
context:
space:
mode:
authorSunil Mushran <sunil.mushran@oracle.com>2010-12-22 15:39:42 -0500
committerJoel Becker <joel.becker@oracle.com>2010-12-22 21:40:38 -0500
commitdb02754c8a1205b24beac70562c45ca5d671151f (patch)
tree320bf20f6940f4967388c56ca0fee576571eb005 /fs/ocfs2/cluster/netdebug.c
parente453039f8bf44abf82f3ecfb34177e0cb04bce12 (diff)
ocfs2/cluster: Show o2net timing statistics
Adds debugfs dentry o2net/stats to show the o2net timing statistics. Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com> Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/cluster/netdebug.c')
-rw-r--r--fs/ocfs2/cluster/netdebug.c211
1 files changed, 157 insertions, 54 deletions
diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c
index 536a93d13a06..61df89cedded 100644
--- a/fs/ocfs2/cluster/netdebug.c
+++ b/fs/ocfs2/cluster/netdebug.c
@@ -46,10 +46,15 @@
46#define O2NET_DEBUG_DIR "o2net" 46#define O2NET_DEBUG_DIR "o2net"
47#define SC_DEBUG_NAME "sock_containers" 47#define SC_DEBUG_NAME "sock_containers"
48#define NST_DEBUG_NAME "send_tracking" 48#define NST_DEBUG_NAME "send_tracking"
49#define STATS_DEBUG_NAME "stats"
50
51#define SHOW_SOCK_CONTAINERS 0
52#define SHOW_SOCK_STATS 1
49 53
50static struct dentry *o2net_dentry; 54static struct dentry *o2net_dentry;
51static struct dentry *sc_dentry; 55static struct dentry *sc_dentry;
52static struct dentry *nst_dentry; 56static struct dentry *nst_dentry;
57static struct dentry *stats_dentry;
53 58
54static DEFINE_SPINLOCK(o2net_debug_lock); 59static DEFINE_SPINLOCK(o2net_debug_lock);
55 60
@@ -232,6 +237,11 @@ void o2net_debug_del_sc(struct o2net_sock_container *sc)
232 spin_unlock(&o2net_debug_lock); 237 spin_unlock(&o2net_debug_lock);
233} 238}
234 239
240struct o2net_sock_debug {
241 int dbg_ctxt;
242 struct o2net_sock_container *dbg_sock;
243};
244
235static struct o2net_sock_container 245static struct o2net_sock_container
236 *next_sc(struct o2net_sock_container *sc_start) 246 *next_sc(struct o2net_sock_container *sc_start)
237{ 247{
@@ -257,7 +267,8 @@ static struct o2net_sock_container
257 267
258static void *sc_seq_start(struct seq_file *seq, loff_t *pos) 268static void *sc_seq_start(struct seq_file *seq, loff_t *pos)
259{ 269{
260 struct o2net_sock_container *sc, *dummy_sc = seq->private; 270 struct o2net_sock_debug *sd = seq->private;
271 struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock;
261 272
262 spin_lock(&o2net_debug_lock); 273 spin_lock(&o2net_debug_lock);
263 sc = next_sc(dummy_sc); 274 sc = next_sc(dummy_sc);
@@ -268,7 +279,8 @@ static void *sc_seq_start(struct seq_file *seq, loff_t *pos)
268 279
269static void *sc_seq_next(struct seq_file *seq, void *v, loff_t *pos) 280static void *sc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
270{ 281{
271 struct o2net_sock_container *sc, *dummy_sc = seq->private; 282 struct o2net_sock_debug *sd = seq->private;
283 struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock;
272 284
273 spin_lock(&o2net_debug_lock); 285 spin_lock(&o2net_debug_lock);
274 sc = next_sc(dummy_sc); 286 sc = next_sc(dummy_sc);
@@ -280,63 +292,107 @@ static void *sc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
280 return sc; /* unused, just needs to be null when done */ 292 return sc; /* unused, just needs to be null when done */
281} 293}
282 294
283static int sc_seq_show(struct seq_file *seq, void *v) 295#ifdef CONFIG_OCFS2_FS_STATS
296# define sc_send_count(_s) ((_s)->sc_send_count)
297# define sc_recv_count(_s) ((_s)->sc_recv_count)
298# define sc_tv_acquiry_total_ns(_s) (ktime_to_ns((_s)->sc_tv_acquiry_total))
299# define sc_tv_send_total_ns(_s) (ktime_to_ns((_s)->sc_tv_send_total))
300# define sc_tv_status_total_ns(_s) (ktime_to_ns((_s)->sc_tv_status_total))
301# define sc_tv_process_total_ns(_s) (ktime_to_ns((_s)->sc_tv_process_total))
302#else
303# define sc_send_count(_s) (0U)
304# define sc_recv_count(_s) (0U)
305# define sc_tv_acquiry_total_ns(_s) (0LL)
306# define sc_tv_send_total_ns(_s) (0LL)
307# define sc_tv_status_total_ns(_s) (0LL)
308# define sc_tv_process_total_ns(_s) (0LL)
309#endif
310
311/* So that debugfs.ocfs2 can determine which format is being used */
312#define O2NET_STATS_STR_VERSION 1
313static void sc_show_sock_stats(struct seq_file *seq,
314 struct o2net_sock_container *sc)
284{ 315{
285 struct o2net_sock_container *sc, *dummy_sc = seq->private; 316 if (!sc)
317 return;
318
319 seq_printf(seq, "%d,%u,%lu,%lld,%lld,%lld,%lu,%lld\n", O2NET_STATS_STR_VERSION,
320 sc->sc_node->nd_num, (unsigned long)sc_send_count(sc),
321 (long long)sc_tv_acquiry_total_ns(sc),
322 (long long)sc_tv_send_total_ns(sc),
323 (long long)sc_tv_status_total_ns(sc),
324 (unsigned long)sc_recv_count(sc),
325 (long long)sc_tv_process_total_ns(sc));
326}
286 327
287 spin_lock(&o2net_debug_lock); 328static void sc_show_sock_container(struct seq_file *seq,
288 sc = next_sc(dummy_sc); 329 struct o2net_sock_container *sc)
330{
331 struct inet_sock *inet = NULL;
332 __be32 saddr = 0, daddr = 0;
333 __be16 sport = 0, dport = 0;
334
335 if (!sc)
336 return;
337
338 if (sc->sc_sock) {
339 inet = inet_sk(sc->sc_sock->sk);
340 /* the stack's structs aren't sparse endian clean */
341 saddr = (__force __be32)inet->inet_saddr;
342 daddr = (__force __be32)inet->inet_daddr;
343 sport = (__force __be16)inet->inet_sport;
344 dport = (__force __be16)inet->inet_dport;
345 }
289 346
290 if (sc != NULL) { 347 /* XXX sigh, inet-> doesn't have sparse annotation so any
291 struct inet_sock *inet = NULL; 348 * use of it here generates a warning with -Wbitwise */
349 seq_printf(seq, "%p:\n"
350 " krefs: %d\n"
351 " sock: %pI4:%u -> "
352 "%pI4:%u\n"
353 " remote node: %s\n"
354 " page off: %zu\n"
355 " handshake ok: %u\n"
356 " timer: %lld usecs\n"
357 " data ready: %lld usecs\n"
358 " advance start: %lld usecs\n"
359 " advance stop: %lld usecs\n"
360 " func start: %lld usecs\n"
361 " func stop: %lld usecs\n"
362 " func key: 0x%08x\n"
363 " func type: %u\n",
364 sc,
365 atomic_read(&sc->sc_kref.refcount),
366 &saddr, inet ? ntohs(sport) : 0,
367 &daddr, inet ? ntohs(dport) : 0,
368 sc->sc_node->nd_name,
369 sc->sc_page_off,
370 sc->sc_handshake_ok,
371 (long long)ktime_to_us(sc->sc_tv_timer),
372 (long long)ktime_to_us(sc->sc_tv_data_ready),
373 (long long)ktime_to_us(sc->sc_tv_advance_start),
374 (long long)ktime_to_us(sc->sc_tv_advance_stop),
375 (long long)ktime_to_us(sc->sc_tv_func_start),
376 (long long)ktime_to_us(sc->sc_tv_func_stop),
377 sc->sc_msg_key,
378 sc->sc_msg_type);
379}
292 380
293 __be32 saddr = 0, daddr = 0; 381static int sc_seq_show(struct seq_file *seq, void *v)
294 __be16 sport = 0, dport = 0; 382{
383 struct o2net_sock_debug *sd = seq->private;
384 struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock;
295 385
296 if (sc->sc_sock) { 386 spin_lock(&o2net_debug_lock);
297 inet = inet_sk(sc->sc_sock->sk); 387 sc = next_sc(dummy_sc);
298 /* the stack's structs aren't sparse endian clean */
299 saddr = (__force __be32)inet->inet_saddr;
300 daddr = (__force __be32)inet->inet_daddr;
301 sport = (__force __be16)inet->inet_sport;
302 dport = (__force __be16)inet->inet_dport;
303 }
304 388
305 /* XXX sigh, inet-> doesn't have sparse annotation so any 389 if (sc) {
306 * use of it here generates a warning with -Wbitwise */ 390 if (sd->dbg_ctxt == SHOW_SOCK_CONTAINERS)
307 seq_printf(seq, "%p:\n" 391 sc_show_sock_container(seq, sc);
308 " krefs: %d\n" 392 else
309 " sock: %pI4:%u -> " 393 sc_show_sock_stats(seq, sc);
310 "%pI4:%u\n"
311 " remote node: %s\n"
312 " page off: %zu\n"
313 " handshake ok: %u\n"
314 " timer: %lld usecs\n"
315 " data ready: %lld usecs\n"
316 " advance start: %lld usecs\n"
317 " advance stop: %lld usecs\n"
318 " func start: %lld usecs\n"
319 " func stop: %lld usecs\n"
320 " func key: 0x%08x\n"
321 " func type: %u\n",
322 sc,
323 atomic_read(&sc->sc_kref.refcount),
324 &saddr, inet ? ntohs(sport) : 0,
325 &daddr, inet ? ntohs(dport) : 0,
326 sc->sc_node->nd_name,
327 sc->sc_page_off,
328 sc->sc_handshake_ok,
329 (long long)ktime_to_us(sc->sc_tv_timer),
330 (long long)ktime_to_us(sc->sc_tv_data_ready),
331 (long long)ktime_to_us(sc->sc_tv_advance_start),
332 (long long)ktime_to_us(sc->sc_tv_advance_stop),
333 (long long)ktime_to_us(sc->sc_tv_func_start),
334 (long long)ktime_to_us(sc->sc_tv_func_stop),
335 sc->sc_msg_key,
336 sc->sc_msg_type);
337 } 394 }
338 395
339
340 spin_unlock(&o2net_debug_lock); 396 spin_unlock(&o2net_debug_lock);
341 397
342 return 0; 398 return 0;
@@ -353,7 +409,7 @@ static const struct seq_operations sc_seq_ops = {
353 .show = sc_seq_show, 409 .show = sc_seq_show,
354}; 410};
355 411
356static int sc_fop_open(struct inode *inode, struct file *file) 412static int sc_common_open(struct file *file, struct o2net_sock_debug *sd)
357{ 413{
358 struct o2net_sock_container *dummy_sc; 414 struct o2net_sock_container *dummy_sc;
359 struct seq_file *seq; 415 struct seq_file *seq;
@@ -371,7 +427,8 @@ static int sc_fop_open(struct inode *inode, struct file *file)
371 goto out; 427 goto out;
372 428
373 seq = file->private_data; 429 seq = file->private_data;
374 seq->private = dummy_sc; 430 seq->private = sd;
431 sd->dbg_sock = dummy_sc;
375 o2net_debug_add_sc(dummy_sc); 432 o2net_debug_add_sc(dummy_sc);
376 433
377 dummy_sc = NULL; 434 dummy_sc = NULL;
@@ -384,12 +441,48 @@ out:
384static int sc_fop_release(struct inode *inode, struct file *file) 441static int sc_fop_release(struct inode *inode, struct file *file)
385{ 442{
386 struct seq_file *seq = file->private_data; 443 struct seq_file *seq = file->private_data;
387 struct o2net_sock_container *dummy_sc = seq->private; 444 struct o2net_sock_debug *sd = seq->private;
445 struct o2net_sock_container *dummy_sc = sd->dbg_sock;
388 446
389 o2net_debug_del_sc(dummy_sc); 447 o2net_debug_del_sc(dummy_sc);
390 return seq_release_private(inode, file); 448 return seq_release_private(inode, file);
391} 449}
392 450
451static int stats_fop_open(struct inode *inode, struct file *file)
452{
453 struct o2net_sock_debug *sd;
454
455 sd = kmalloc(sizeof(struct o2net_sock_debug), GFP_KERNEL);
456 if (sd == NULL)
457 return -ENOMEM;
458
459 sd->dbg_ctxt = SHOW_SOCK_STATS;
460 sd->dbg_sock = NULL;
461
462 return sc_common_open(file, sd);
463}
464
465static const struct file_operations stats_seq_fops = {
466 .open = stats_fop_open,
467 .read = seq_read,
468 .llseek = seq_lseek,
469 .release = sc_fop_release,
470};
471
472static int sc_fop_open(struct inode *inode, struct file *file)
473{
474 struct o2net_sock_debug *sd;
475
476 sd = kmalloc(sizeof(struct o2net_sock_debug), GFP_KERNEL);
477 if (sd == NULL)
478 return -ENOMEM;
479
480 sd->dbg_ctxt = SHOW_SOCK_CONTAINERS;
481 sd->dbg_sock = NULL;
482
483 return sc_common_open(file, sd);
484}
485
393static const struct file_operations sc_seq_fops = { 486static const struct file_operations sc_seq_fops = {
394 .open = sc_fop_open, 487 .open = sc_fop_open,
395 .read = seq_read, 488 .read = seq_read,
@@ -421,8 +514,17 @@ int o2net_debugfs_init(void)
421 goto bail; 514 goto bail;
422 } 515 }
423 516
517 stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, S_IFREG|S_IRUSR,
518 o2net_dentry, NULL,
519 &stats_seq_fops);
520 if (!stats_dentry) {
521 mlog_errno(-ENOMEM);
522 goto bail;
523 }
524
424 return 0; 525 return 0;
425bail: 526bail:
527 debugfs_remove(stats_dentry);
426 debugfs_remove(sc_dentry); 528 debugfs_remove(sc_dentry);
427 debugfs_remove(nst_dentry); 529 debugfs_remove(nst_dentry);
428 debugfs_remove(o2net_dentry); 530 debugfs_remove(o2net_dentry);
@@ -431,6 +533,7 @@ bail:
431 533
432void o2net_debugfs_exit(void) 534void o2net_debugfs_exit(void)
433{ 535{
536 debugfs_remove(stats_dentry);
434 debugfs_remove(sc_dentry); 537 debugfs_remove(sc_dentry);
435 debugfs_remove(nst_dentry); 538 debugfs_remove(nst_dentry);
436 debugfs_remove(o2net_dentry); 539 debugfs_remove(o2net_dentry);