diff options
| -rw-r--r-- | fs/jbd2/checkpoint.c | 7 | ||||
| -rw-r--r-- | fs/jbd2/commit.c | 59 | ||||
| -rw-r--r-- | fs/jbd2/journal.c | 187 | ||||
| -rw-r--r-- | include/linux/jbd2.h | 27 | ||||
| -rw-r--r-- | include/trace/events/jbd2.h | 78 |
5 files changed, 130 insertions, 228 deletions
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 5d70b3e6d49b..ca0f5eb62b20 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c | |||
| @@ -643,6 +643,7 @@ out: | |||
| 643 | 643 | ||
| 644 | int __jbd2_journal_remove_checkpoint(struct journal_head *jh) | 644 | int __jbd2_journal_remove_checkpoint(struct journal_head *jh) |
| 645 | { | 645 | { |
| 646 | struct transaction_chp_stats_s *stats; | ||
| 646 | transaction_t *transaction; | 647 | transaction_t *transaction; |
| 647 | journal_t *journal; | 648 | journal_t *journal; |
| 648 | int ret = 0; | 649 | int ret = 0; |
| @@ -679,6 +680,12 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh) | |||
| 679 | 680 | ||
| 680 | /* OK, that was the last buffer for the transaction: we can now | 681 | /* OK, that was the last buffer for the transaction: we can now |
| 681 | safely remove this transaction from the log */ | 682 | safely remove this transaction from the log */ |
| 683 | stats = &transaction->t_chp_stats; | ||
| 684 | if (stats->cs_chp_time) | ||
| 685 | stats->cs_chp_time = jbd2_time_diff(stats->cs_chp_time, | ||
| 686 | jiffies); | ||
| 687 | trace_jbd2_checkpoint_stats(journal->j_fs_dev->bd_dev, | ||
| 688 | transaction->t_tid, stats); | ||
| 682 | 689 | ||
| 683 | __jbd2_journal_drop_transaction(journal, transaction); | 690 | __jbd2_journal_drop_transaction(journal, transaction); |
| 684 | kfree(transaction); | 691 | kfree(transaction); |
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 26d991ddc1e6..d4cfd6d2779e 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
| @@ -410,10 +410,10 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
| 410 | if (commit_transaction->t_synchronous_commit) | 410 | if (commit_transaction->t_synchronous_commit) |
| 411 | write_op = WRITE_SYNC_PLUG; | 411 | write_op = WRITE_SYNC_PLUG; |
| 412 | trace_jbd2_commit_locking(journal, commit_transaction); | 412 | trace_jbd2_commit_locking(journal, commit_transaction); |
| 413 | stats.u.run.rs_wait = commit_transaction->t_max_wait; | 413 | stats.run.rs_wait = commit_transaction->t_max_wait; |
| 414 | stats.u.run.rs_locked = jiffies; | 414 | stats.run.rs_locked = jiffies; |
| 415 | stats.u.run.rs_running = jbd2_time_diff(commit_transaction->t_start, | 415 | stats.run.rs_running = jbd2_time_diff(commit_transaction->t_start, |
| 416 | stats.u.run.rs_locked); | 416 | stats.run.rs_locked); |
| 417 | 417 | ||
| 418 | spin_lock(&commit_transaction->t_handle_lock); | 418 | spin_lock(&commit_transaction->t_handle_lock); |
| 419 | while (commit_transaction->t_updates) { | 419 | while (commit_transaction->t_updates) { |
| @@ -486,9 +486,9 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
| 486 | jbd2_journal_switch_revoke_table(journal); | 486 | jbd2_journal_switch_revoke_table(journal); |
| 487 | 487 | ||
| 488 | trace_jbd2_commit_flushing(journal, commit_transaction); | 488 | trace_jbd2_commit_flushing(journal, commit_transaction); |
| 489 | stats.u.run.rs_flushing = jiffies; | 489 | stats.run.rs_flushing = jiffies; |
| 490 | stats.u.run.rs_locked = jbd2_time_diff(stats.u.run.rs_locked, | 490 | stats.run.rs_locked = jbd2_time_diff(stats.run.rs_locked, |
| 491 | stats.u.run.rs_flushing); | 491 | stats.run.rs_flushing); |
| 492 | 492 | ||
| 493 | commit_transaction->t_state = T_FLUSH; | 493 | commit_transaction->t_state = T_FLUSH; |
| 494 | journal->j_committing_transaction = commit_transaction; | 494 | journal->j_committing_transaction = commit_transaction; |
| @@ -523,11 +523,11 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
| 523 | spin_unlock(&journal->j_state_lock); | 523 | spin_unlock(&journal->j_state_lock); |
| 524 | 524 | ||
| 525 | trace_jbd2_commit_logging(journal, commit_transaction); | 525 | trace_jbd2_commit_logging(journal, commit_transaction); |
| 526 | stats.u.run.rs_logging = jiffies; | 526 | stats.run.rs_logging = jiffies; |
| 527 | stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing, | 527 | stats.run.rs_flushing = jbd2_time_diff(stats.run.rs_flushing, |
| 528 | stats.u.run.rs_logging); | 528 | stats.run.rs_logging); |
| 529 | stats.u.run.rs_blocks = commit_transaction->t_outstanding_credits; | 529 | stats.run.rs_blocks = commit_transaction->t_outstanding_credits; |
| 530 | stats.u.run.rs_blocks_logged = 0; | 530 | stats.run.rs_blocks_logged = 0; |
| 531 | 531 | ||
| 532 | J_ASSERT(commit_transaction->t_nr_buffers <= | 532 | J_ASSERT(commit_transaction->t_nr_buffers <= |
| 533 | commit_transaction->t_outstanding_credits); | 533 | commit_transaction->t_outstanding_credits); |
| @@ -695,7 +695,7 @@ start_journal_io: | |||
| 695 | submit_bh(write_op, bh); | 695 | submit_bh(write_op, bh); |
| 696 | } | 696 | } |
| 697 | cond_resched(); | 697 | cond_resched(); |
| 698 | stats.u.run.rs_blocks_logged += bufs; | 698 | stats.run.rs_blocks_logged += bufs; |
| 699 | 699 | ||
| 700 | /* Force a new descriptor to be generated next | 700 | /* Force a new descriptor to be generated next |
| 701 | time round the loop. */ | 701 | time round the loop. */ |
| @@ -988,33 +988,30 @@ restart_loop: | |||
| 988 | J_ASSERT(commit_transaction->t_state == T_COMMIT); | 988 | J_ASSERT(commit_transaction->t_state == T_COMMIT); |
| 989 | 989 | ||
| 990 | commit_transaction->t_start = jiffies; | 990 | commit_transaction->t_start = jiffies; |
| 991 | stats.u.run.rs_logging = jbd2_time_diff(stats.u.run.rs_logging, | 991 | stats.run.rs_logging = jbd2_time_diff(stats.run.rs_logging, |
| 992 | commit_transaction->t_start); | 992 | commit_transaction->t_start); |
| 993 | 993 | ||
| 994 | /* | 994 | /* |
| 995 | * File the transaction for history | 995 | * File the transaction statistics |
| 996 | */ | 996 | */ |
| 997 | stats.ts_type = JBD2_STATS_RUN; | ||
| 998 | stats.ts_tid = commit_transaction->t_tid; | 997 | stats.ts_tid = commit_transaction->t_tid; |
| 999 | stats.u.run.rs_handle_count = commit_transaction->t_handle_count; | 998 | stats.run.rs_handle_count = commit_transaction->t_handle_count; |
| 1000 | spin_lock(&journal->j_history_lock); | 999 | trace_jbd2_run_stats(journal->j_fs_dev->bd_dev, |
| 1001 | memcpy(journal->j_history + journal->j_history_cur, &stats, | 1000 | commit_transaction->t_tid, &stats.run); |
| 1002 | sizeof(stats)); | ||
| 1003 | if (++journal->j_history_cur == journal->j_history_max) | ||
| 1004 | journal->j_history_cur = 0; | ||
| 1005 | 1001 | ||
| 1006 | /* | 1002 | /* |
| 1007 | * Calculate overall stats | 1003 | * Calculate overall stats |
| 1008 | */ | 1004 | */ |
| 1005 | spin_lock(&journal->j_history_lock); | ||
| 1009 | journal->j_stats.ts_tid++; | 1006 | journal->j_stats.ts_tid++; |
| 1010 | journal->j_stats.u.run.rs_wait += stats.u.run.rs_wait; | 1007 | journal->j_stats.run.rs_wait += stats.run.rs_wait; |
| 1011 | journal->j_stats.u.run.rs_running += stats.u.run.rs_running; | 1008 | journal->j_stats.run.rs_running += stats.run.rs_running; |
| 1012 | journal->j_stats.u.run.rs_locked += stats.u.run.rs_locked; | 1009 | journal->j_stats.run.rs_locked += stats.run.rs_locked; |
| 1013 | journal->j_stats.u.run.rs_flushing += stats.u.run.rs_flushing; | 1010 | journal->j_stats.run.rs_flushing += stats.run.rs_flushing; |
| 1014 | journal->j_stats.u.run.rs_logging += stats.u.run.rs_logging; | 1011 | journal->j_stats.run.rs_logging += stats.run.rs_logging; |
| 1015 | journal->j_stats.u.run.rs_handle_count += stats.u.run.rs_handle_count; | 1012 | journal->j_stats.run.rs_handle_count += stats.run.rs_handle_count; |
| 1016 | journal->j_stats.u.run.rs_blocks += stats.u.run.rs_blocks; | 1013 | journal->j_stats.run.rs_blocks += stats.run.rs_blocks; |
| 1017 | journal->j_stats.u.run.rs_blocks_logged += stats.u.run.rs_blocks_logged; | 1014 | journal->j_stats.run.rs_blocks_logged += stats.run.rs_blocks_logged; |
| 1018 | spin_unlock(&journal->j_history_lock); | 1015 | spin_unlock(&journal->j_history_lock); |
| 1019 | 1016 | ||
| 1020 | commit_transaction->t_state = T_FINISHED; | 1017 | commit_transaction->t_state = T_FINISHED; |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 977a8dafb76d..761af77491f5 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
| @@ -676,153 +676,6 @@ struct jbd2_stats_proc_session { | |||
| 676 | int max; | 676 | int max; |
| 677 | }; | 677 | }; |
| 678 | 678 | ||
| 679 | static void *jbd2_history_skip_empty(struct jbd2_stats_proc_session *s, | ||
| 680 | struct transaction_stats_s *ts, | ||
| 681 | int first) | ||
| 682 | { | ||
| 683 | if (ts == s->stats + s->max) | ||
| 684 | ts = s->stats; | ||
| 685 | if (!first && ts == s->stats + s->start) | ||
| 686 | return NULL; | ||
| 687 | while (ts->ts_type == 0) { | ||
| 688 | ts++; | ||
| 689 | if (ts == s->stats + s->max) | ||
| 690 | ts = s->stats; | ||
| 691 | if (ts == s->stats + s->start) | ||
| 692 | return NULL; | ||
| 693 | } | ||
| 694 | return ts; | ||
| 695 | |||
| 696 | } | ||
| 697 | |||
| 698 | static void *jbd2_seq_history_start(struct seq_file *seq, loff_t *pos) | ||
| 699 | { | ||
| 700 | struct jbd2_stats_proc_session *s = seq->private; | ||
| 701 | struct transaction_stats_s *ts; | ||
| 702 | int l = *pos; | ||
| 703 | |||
| 704 | if (l == 0) | ||
| 705 | return SEQ_START_TOKEN; | ||
| 706 | ts = jbd2_history_skip_empty(s, s->stats + s->start, 1); | ||
| 707 | if (!ts) | ||
| 708 | return NULL; | ||
| 709 | l--; | ||
| 710 | while (l) { | ||
| 711 | ts = jbd2_history_skip_empty(s, ++ts, 0); | ||
| 712 | if (!ts) | ||
| 713 | break; | ||
| 714 | l--; | ||
| 715 | } | ||
| 716 | return ts; | ||
| 717 | } | ||
| 718 | |||
| 719 | static void *jbd2_seq_history_next(struct seq_file *seq, void *v, loff_t *pos) | ||
| 720 | { | ||
| 721 | struct jbd2_stats_proc_session *s = seq->private; | ||
| 722 | struct transaction_stats_s *ts = v; | ||
| 723 | |||
| 724 | ++*pos; | ||
| 725 | if (v == SEQ_START_TOKEN) | ||
| 726 | return jbd2_history_skip_empty(s, s->stats + s->start, 1); | ||
| 727 | else | ||
| 728 | return jbd2_history_skip_empty(s, ++ts, 0); | ||
| 729 | } | ||
| 730 | |||
| 731 | static int jbd2_seq_history_show(struct seq_file *seq, void *v) | ||
| 732 | { | ||
| 733 | struct transaction_stats_s *ts = v; | ||
| 734 | if (v == SEQ_START_TOKEN) { | ||
| 735 | seq_printf(seq, "%-4s %-5s %-5s %-5s %-5s %-5s %-5s %-6s %-5s " | ||
| 736 | "%-5s %-5s %-5s %-5s %-5s\n", "R/C", "tid", | ||
| 737 | "wait", "run", "lock", "flush", "log", "hndls", | ||
| 738 | "block", "inlog", "ctime", "write", "drop", | ||
| 739 | "close"); | ||
| 740 | return 0; | ||
| 741 | } | ||
| 742 | if (ts->ts_type == JBD2_STATS_RUN) | ||
| 743 | seq_printf(seq, "%-4s %-5lu %-5u %-5u %-5u %-5u %-5u " | ||
| 744 | "%-6lu %-5lu %-5lu\n", "R", ts->ts_tid, | ||
| 745 | jiffies_to_msecs(ts->u.run.rs_wait), | ||
| 746 | jiffies_to_msecs(ts->u.run.rs_running), | ||
| 747 | jiffies_to_msecs(ts->u.run.rs_locked), | ||
| 748 | jiffies_to_msecs(ts->u.run.rs_flushing), | ||
| 749 | jiffies_to_msecs(ts->u.run.rs_logging), | ||
| 750 | ts->u.run.rs_handle_count, | ||
| 751 | ts->u.run.rs_blocks, | ||
| 752 | ts->u.run.rs_blocks_logged); | ||
| 753 | else if (ts->ts_type == JBD2_STATS_CHECKPOINT) | ||
| 754 | seq_printf(seq, "%-4s %-5lu %48s %-5u %-5lu %-5lu %-5lu\n", | ||
| 755 | "C", ts->ts_tid, " ", | ||
| 756 | jiffies_to_msecs(ts->u.chp.cs_chp_time), | ||
| 757 | ts->u.chp.cs_written, ts->u.chp.cs_dropped, | ||
| 758 | ts->u.chp.cs_forced_to_close); | ||
| 759 | else | ||
| 760 | J_ASSERT(0); | ||
| 761 | return 0; | ||
| 762 | } | ||
| 763 | |||
| 764 | static void jbd2_seq_history_stop(struct seq_file *seq, void *v) | ||
| 765 | { | ||
| 766 | } | ||
| 767 | |||
| 768 | static const struct seq_operations jbd2_seq_history_ops = { | ||
| 769 | .start = jbd2_seq_history_start, | ||
| 770 | .next = jbd2_seq_history_next, | ||
| 771 | .stop = jbd2_seq_history_stop, | ||
| 772 | .show = jbd2_seq_history_show, | ||
| 773 | }; | ||
| 774 | |||
| 775 | static int jbd2_seq_history_open(struct inode *inode, struct file *file) | ||
| 776 | { | ||
| 777 | journal_t *journal = PDE(inode)->data; | ||
| 778 | struct jbd2_stats_proc_session *s; | ||
| 779 | int rc, size; | ||
| 780 | |||
| 781 | s = kmalloc(sizeof(*s), GFP_KERNEL); | ||
| 782 | if (s == NULL) | ||
| 783 | return -ENOMEM; | ||
| 784 | size = sizeof(struct transaction_stats_s) * journal->j_history_max; | ||
| 785 | s->stats = kmalloc(size, GFP_KERNEL); | ||
| 786 | if (s->stats == NULL) { | ||
| 787 | kfree(s); | ||
| 788 | return -ENOMEM; | ||
| 789 | } | ||
| 790 | spin_lock(&journal->j_history_lock); | ||
| 791 | memcpy(s->stats, journal->j_history, size); | ||
| 792 | s->max = journal->j_history_max; | ||
| 793 | s->start = journal->j_history_cur % s->max; | ||
| 794 | spin_unlock(&journal->j_history_lock); | ||
| 795 | |||
| 796 | rc = seq_open(file, &jbd2_seq_history_ops); | ||
| 797 | if (rc == 0) { | ||
| 798 | struct seq_file *m = file->private_data; | ||
| 799 | m->private = s; | ||
| 800 | } else { | ||
| 801 | kfree(s->stats); | ||
| 802 | kfree(s); | ||
| 803 | } | ||
| 804 | return rc; | ||
| 805 | |||
| 806 | } | ||
| 807 | |||
| 808 | static int jbd2_seq_history_release(struct inode *inode, struct file *file) | ||
| 809 | { | ||
| 810 | struct seq_file *seq = file->private_data; | ||
| 811 | struct jbd2_stats_proc_session *s = seq->private; | ||
| 812 | |||
| 813 | kfree(s->stats); | ||
| 814 | kfree(s); | ||
| 815 | return seq_release(inode, file); | ||
| 816 | } | ||
| 817 | |||
| 818 | static struct file_operations jbd2_seq_history_fops = { | ||
| 819 | .owner = THIS_MODULE, | ||
| 820 | .open = jbd2_seq_history_open, | ||
| 821 | .read = seq_read, | ||
| 822 | .llseek = seq_lseek, | ||
| 823 | .release = jbd2_seq_history_release, | ||
| 824 | }; | ||
| 825 | |||
| 826 | static void *jbd2_seq_info_start(struct seq_file *seq, loff_t *pos) | 679 | static void *jbd2_seq_info_start(struct seq_file *seq, loff_t *pos) |
| 827 | { | 680 | { |
| 828 | return *pos ? NULL : SEQ_START_TOKEN; | 681 | return *pos ? NULL : SEQ_START_TOKEN; |
| @@ -839,29 +692,29 @@ static int jbd2_seq_info_show(struct seq_file *seq, void *v) | |||
| 839 | 692 | ||
| 840 | if (v != SEQ_START_TOKEN) | 693 | if (v != SEQ_START_TOKEN) |
| 841 | return 0; | 694 | return 0; |
| 842 | seq_printf(seq, "%lu transaction, each upto %u blocks\n", | 695 | seq_printf(seq, "%lu transaction, each up to %u blocks\n", |
| 843 | s->stats->ts_tid, | 696 | s->stats->ts_tid, |
| 844 | s->journal->j_max_transaction_buffers); | 697 | s->journal->j_max_transaction_buffers); |
| 845 | if (s->stats->ts_tid == 0) | 698 | if (s->stats->ts_tid == 0) |
| 846 | return 0; | 699 | return 0; |
| 847 | seq_printf(seq, "average: \n %ums waiting for transaction\n", | 700 | seq_printf(seq, "average: \n %ums waiting for transaction\n", |
| 848 | jiffies_to_msecs(s->stats->u.run.rs_wait / s->stats->ts_tid)); | 701 | jiffies_to_msecs(s->stats->run.rs_wait / s->stats->ts_tid)); |
| 849 | seq_printf(seq, " %ums running transaction\n", | 702 | seq_printf(seq, " %ums running transaction\n", |
| 850 | jiffies_to_msecs(s->stats->u.run.rs_running / s->stats->ts_tid)); | 703 | jiffies_to_msecs(s->stats->run.rs_running / s->stats->ts_tid)); |
| 851 | seq_printf(seq, " %ums transaction was being locked\n", | 704 | seq_printf(seq, " %ums transaction was being locked\n", |
| 852 | jiffies_to_msecs(s->stats->u.run.rs_locked / s->stats->ts_tid)); | 705 | jiffies_to_msecs(s->stats->run.rs_locked / s->stats->ts_tid)); |
| 853 | seq_printf(seq, " %ums flushing data (in ordered mode)\n", | 706 | seq_printf(seq, " %ums flushing data (in ordered mode)\n", |
| 854 | jiffies_to_msecs(s->stats->u.run.rs_flushing / s->stats->ts_tid)); | 707 | jiffies_to_msecs(s->stats->run.rs_flushing / s->stats->ts_tid)); |
| 855 | seq_printf(seq, " %ums logging transaction\n", | 708 | seq_printf(seq, " %ums logging transaction\n", |
| 856 | jiffies_to_msecs(s->stats->u.run.rs_logging / s->stats->ts_tid)); | 709 | jiffies_to_msecs(s->stats->run.rs_logging / s->stats->ts_tid)); |
| 857 | seq_printf(seq, " %lluus average transaction commit time\n", | 710 | seq_printf(seq, " %lluus average transaction commit time\n", |
| 858 | div_u64(s->journal->j_average_commit_time, 1000)); | 711 | div_u64(s->journal->j_average_commit_time, 1000)); |
| 859 | seq_printf(seq, " %lu handles per transaction\n", | 712 | seq_printf(seq, " %lu handles per transaction\n", |
| 860 | s->stats->u.run.rs_handle_count / s->stats->ts_tid); | 713 | s->stats->run.rs_handle_count / s->stats->ts_tid); |
| 861 | seq_printf(seq, " %lu blocks per transaction\n", | 714 | seq_printf(seq, " %lu blocks per transaction\n", |
| 862 | s->stats->u.run.rs_blocks / s->stats->ts_tid); | 715 | s->stats->run.rs_blocks / s->stats->ts_tid); |
| 863 | seq_printf(seq, " %lu logged blocks per transaction\n", | 716 | seq_printf(seq, " %lu logged blocks per transaction\n", |
| 864 | s->stats->u.run.rs_blocks_logged / s->stats->ts_tid); | 717 | s->stats->run.rs_blocks_logged / s->stats->ts_tid); |
| 865 | return 0; | 718 | return 0; |
| 866 | } | 719 | } |
| 867 | 720 | ||
| @@ -931,8 +784,6 @@ static void jbd2_stats_proc_init(journal_t *journal) | |||
| 931 | { | 784 | { |
| 932 | journal->j_proc_entry = proc_mkdir(journal->j_devname, proc_jbd2_stats); | 785 | journal->j_proc_entry = proc_mkdir(journal->j_devname, proc_jbd2_stats); |
| 933 | if (journal->j_proc_entry) { | 786 | if (journal->j_proc_entry) { |
| 934 | proc_create_data("history", S_IRUGO, journal->j_proc_entry, | ||
| 935 | &jbd2_seq_history_fops, journal); | ||
| 936 | proc_create_data("info", S_IRUGO, journal->j_proc_entry, | 787 | proc_create_data("info", S_IRUGO, journal->j_proc_entry, |
| 937 | &jbd2_seq_info_fops, journal); | 788 | &jbd2_seq_info_fops, journal); |
| 938 | } | 789 | } |
| @@ -941,27 +792,9 @@ static void jbd2_stats_proc_init(journal_t *journal) | |||
| 941 | static void jbd2_stats_proc_exit(journal_t *journal) | 792 | static void jbd2_stats_proc_exit(journal_t *journal) |
| 942 | { | 793 | { |
| 943 | remove_proc_entry("info", journal->j_proc_entry); | 794 | remove_proc_entry("info", journal->j_proc_entry); |
| 944 | remove_proc_entry("history", journal->j_proc_entry); | ||
| 945 | remove_proc_entry(journal->j_devname, proc_jbd2_stats); | 795 | remove_proc_entry(journal->j_devname, proc_jbd2_stats); |
| 946 | } | 796 | } |
| 947 | 797 | ||
| 948 | static void journal_init_stats(journal_t *journal) | ||
| 949 | { | ||
| 950 | int size; | ||
| 951 | |||
| 952 | if (!proc_jbd2_stats) | ||
| 953 | return; | ||
| 954 | |||
| 955 | journal->j_history_max = 100; | ||
| 956 | size = sizeof(struct transaction_stats_s) * journal->j_history_max; | ||
| 957 | journal->j_history = kzalloc(size, GFP_KERNEL); | ||
| 958 | if (!journal->j_history) { | ||
| 959 | journal->j_history_max = 0; | ||
| 960 | return; | ||
| 961 | } | ||
| 962 | spin_lock_init(&journal->j_history_lock); | ||
| 963 | } | ||
| 964 | |||
| 965 | /* | 798 | /* |
| 966 | * Management for journal control blocks: functions to create and | 799 | * Management for journal control blocks: functions to create and |
| 967 | * destroy journal_t structures, and to initialise and read existing | 800 | * destroy journal_t structures, and to initialise and read existing |
| @@ -1006,7 +839,7 @@ static journal_t * journal_init_common (void) | |||
| 1006 | goto fail; | 839 | goto fail; |
| 1007 | } | 840 | } |
| 1008 | 841 | ||
| 1009 | journal_init_stats(journal); | 842 | spin_lock_init(&journal->j_history_lock); |
| 1010 | 843 | ||
| 1011 | return journal; | 844 | return journal; |
| 1012 | fail: | 845 | fail: |
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 52695d3dfd0b..f1011f7f3d41 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h | |||
| @@ -464,9 +464,9 @@ struct handle_s | |||
| 464 | */ | 464 | */ |
| 465 | struct transaction_chp_stats_s { | 465 | struct transaction_chp_stats_s { |
| 466 | unsigned long cs_chp_time; | 466 | unsigned long cs_chp_time; |
| 467 | unsigned long cs_forced_to_close; | 467 | __u32 cs_forced_to_close; |
| 468 | unsigned long cs_written; | 468 | __u32 cs_written; |
| 469 | unsigned long cs_dropped; | 469 | __u32 cs_dropped; |
| 470 | }; | 470 | }; |
| 471 | 471 | ||
| 472 | /* The transaction_t type is the guts of the journaling mechanism. It | 472 | /* The transaction_t type is the guts of the journaling mechanism. It |
| @@ -668,23 +668,16 @@ struct transaction_run_stats_s { | |||
| 668 | unsigned long rs_flushing; | 668 | unsigned long rs_flushing; |
| 669 | unsigned long rs_logging; | 669 | unsigned long rs_logging; |
| 670 | 670 | ||
| 671 | unsigned long rs_handle_count; | 671 | __u32 rs_handle_count; |
| 672 | unsigned long rs_blocks; | 672 | __u32 rs_blocks; |
| 673 | unsigned long rs_blocks_logged; | 673 | __u32 rs_blocks_logged; |
| 674 | }; | 674 | }; |
| 675 | 675 | ||
| 676 | struct transaction_stats_s { | 676 | struct transaction_stats_s { |
| 677 | int ts_type; | ||
| 678 | unsigned long ts_tid; | 677 | unsigned long ts_tid; |
| 679 | union { | 678 | struct transaction_run_stats_s run; |
| 680 | struct transaction_run_stats_s run; | ||
| 681 | struct transaction_chp_stats_s chp; | ||
| 682 | } u; | ||
| 683 | }; | 679 | }; |
| 684 | 680 | ||
| 685 | #define JBD2_STATS_RUN 1 | ||
| 686 | #define JBD2_STATS_CHECKPOINT 2 | ||
| 687 | |||
| 688 | static inline unsigned long | 681 | static inline unsigned long |
| 689 | jbd2_time_diff(unsigned long start, unsigned long end) | 682 | jbd2_time_diff(unsigned long start, unsigned long end) |
| 690 | { | 683 | { |
| @@ -988,12 +981,6 @@ struct journal_s | |||
| 988 | /* | 981 | /* |
| 989 | * Journal statistics | 982 | * Journal statistics |
| 990 | */ | 983 | */ |
| 991 | struct transaction_stats_s *j_history; | ||
| 992 | int j_history_max; | ||
| 993 | int j_history_cur; | ||
| 994 | /* | ||
| 995 | * Protect the transactions statistics history | ||
| 996 | */ | ||
| 997 | spinlock_t j_history_lock; | 984 | spinlock_t j_history_lock; |
| 998 | struct proc_dir_entry *j_proc_entry; | 985 | struct proc_dir_entry *j_proc_entry; |
| 999 | struct transaction_stats_s j_stats; | 986 | struct transaction_stats_s j_stats; |
diff --git a/include/trace/events/jbd2.h b/include/trace/events/jbd2.h index b851f0b4701c..3c60b75adb9e 100644 --- a/include/trace/events/jbd2.h +++ b/include/trace/events/jbd2.h | |||
| @@ -7,6 +7,9 @@ | |||
| 7 | #include <linux/jbd2.h> | 7 | #include <linux/jbd2.h> |
| 8 | #include <linux/tracepoint.h> | 8 | #include <linux/tracepoint.h> |
| 9 | 9 | ||
| 10 | struct transaction_chp_stats_s; | ||
| 11 | struct transaction_run_stats_s; | ||
| 12 | |||
| 10 | TRACE_EVENT(jbd2_checkpoint, | 13 | TRACE_EVENT(jbd2_checkpoint, |
| 11 | 14 | ||
| 12 | TP_PROTO(journal_t *journal, int result), | 15 | TP_PROTO(journal_t *journal, int result), |
| @@ -162,6 +165,81 @@ TRACE_EVENT(jbd2_submit_inode_data, | |||
| 162 | jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino) | 165 | jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino) |
| 163 | ); | 166 | ); |
| 164 | 167 | ||
| 168 | TRACE_EVENT(jbd2_run_stats, | ||
| 169 | TP_PROTO(dev_t dev, unsigned long tid, | ||
| 170 | struct transaction_run_stats_s *stats), | ||
| 171 | |||
| 172 | TP_ARGS(dev, tid, stats), | ||
| 173 | |||
| 174 | TP_STRUCT__entry( | ||
| 175 | __field( dev_t, dev ) | ||
| 176 | __field( unsigned long, tid ) | ||
| 177 | __field( unsigned long, wait ) | ||
| 178 | __field( unsigned long, running ) | ||
| 179 | __field( unsigned long, locked ) | ||
| 180 | __field( unsigned long, flushing ) | ||
| 181 | __field( unsigned long, logging ) | ||
| 182 | __field( __u32, handle_count ) | ||
| 183 | __field( __u32, blocks ) | ||
| 184 | __field( __u32, blocks_logged ) | ||
| 185 | ), | ||
| 186 | |||
| 187 | TP_fast_assign( | ||
| 188 | __entry->dev = dev; | ||
| 189 | __entry->tid = tid; | ||
| 190 | __entry->wait = stats->rs_wait; | ||
| 191 | __entry->running = stats->rs_running; | ||
| 192 | __entry->locked = stats->rs_locked; | ||
| 193 | __entry->flushing = stats->rs_flushing; | ||
| 194 | __entry->logging = stats->rs_logging; | ||
| 195 | __entry->handle_count = stats->rs_handle_count; | ||
| 196 | __entry->blocks = stats->rs_blocks; | ||
| 197 | __entry->blocks_logged = stats->rs_blocks_logged; | ||
| 198 | ), | ||
| 199 | |||
| 200 | TP_printk("dev %s tid %lu wait %u running %u locked %u flushing %u " | ||
| 201 | "logging %u handle_count %u blocks %u blocks_logged %u", | ||
| 202 | jbd2_dev_to_name(__entry->dev), __entry->tid, | ||
| 203 | jiffies_to_msecs(__entry->wait), | ||
| 204 | jiffies_to_msecs(__entry->running), | ||
| 205 | jiffies_to_msecs(__entry->locked), | ||
| 206 | jiffies_to_msecs(__entry->flushing), | ||
| 207 | jiffies_to_msecs(__entry->logging), | ||
| 208 | __entry->handle_count, __entry->blocks, | ||
| 209 | __entry->blocks_logged) | ||
| 210 | ); | ||
| 211 | |||
| 212 | TRACE_EVENT(jbd2_checkpoint_stats, | ||
| 213 | TP_PROTO(dev_t dev, unsigned long tid, | ||
| 214 | struct transaction_chp_stats_s *stats), | ||
| 215 | |||
| 216 | TP_ARGS(dev, tid, stats), | ||
| 217 | |||
| 218 | TP_STRUCT__entry( | ||
| 219 | __field( dev_t, dev ) | ||
| 220 | __field( unsigned long, tid ) | ||
| 221 | __field( unsigned long, chp_time ) | ||
| 222 | __field( __u32, forced_to_close ) | ||
| 223 | __field( __u32, written ) | ||
| 224 | __field( __u32, dropped ) | ||
| 225 | ), | ||
| 226 | |||
| 227 | TP_fast_assign( | ||
| 228 | __entry->dev = dev; | ||
| 229 | __entry->tid = tid; | ||
| 230 | __entry->chp_time = stats->cs_chp_time; | ||
| 231 | __entry->forced_to_close= stats->cs_forced_to_close; | ||
| 232 | __entry->written = stats->cs_written; | ||
| 233 | __entry->dropped = stats->cs_dropped; | ||
| 234 | ), | ||
| 235 | |||
| 236 | TP_printk("dev %s tid %lu chp_time %u forced_to_close %u " | ||
| 237 | "written %u dropped %u", | ||
| 238 | jbd2_dev_to_name(__entry->dev), __entry->tid, | ||
| 239 | jiffies_to_msecs(__entry->chp_time), | ||
| 240 | __entry->forced_to_close, __entry->written, __entry->dropped) | ||
| 241 | ); | ||
| 242 | |||
| 165 | #endif /* _TRACE_JBD2_H */ | 243 | #endif /* _TRACE_JBD2_H */ |
| 166 | 244 | ||
| 167 | /* This part must be outside protection */ | 245 | /* This part must be outside protection */ |
