📄 jbd-stats-2.6.9.patch
字号:
Index: linux-2.6.9/include/linux/jbd.h===================================================================--- linux-2.6.9.orig/include/linux/jbd.h+++ linux-2.6.9/include/linux/jbd.h@@ -422,6 +422,16 @@ struct handle_s }; +/*+ * Some stats for checkpoint phase+ */+struct transaction_chp_stats_s {+ unsigned long cs_chp_time;+ unsigned long cs_forced_to_close;+ unsigned long cs_written;+ unsigned long cs_dropped;+};+ /* The transaction_t type is the guts of the journaling mechanism. It * tracks a compound transaction through its various states: *@@ -553,6 +563,21 @@ struct transaction_s spinlock_t t_handle_lock; /*+ * Longest time some handle had to wait for running transaction+ */+ unsigned long t_max_wait;++ /*+ * When transaction started+ */+ unsigned long t_start;++ /*+ * Checkpointing stats [j_checkpoint_sem]+ */+ struct transaction_chp_stats_s t_chp_stats;++ /* * Number of outstanding updates running on this transaction * [t_handle_lock] */@@ -592,6 +617,57 @@ struct transaction_s struct list_head t_jcb; }; +struct transaction_run_stats_s {+ unsigned long rs_wait;+ unsigned long rs_running;+ unsigned long rs_locked;+ unsigned long rs_flushing;+ unsigned long rs_logging;++ unsigned long rs_handle_count;+ unsigned long rs_blocks;+ unsigned long rs_blocks_logged;+};++struct transaction_stats_s+{+ int ts_type;+ unsigned long ts_tid;+ union {+ struct transaction_run_stats_s run;+ struct transaction_chp_stats_s chp;+ } u;+};++#define JBD_STATS_RUN 1+#define JBD_STATS_CHECKPOINT 2++#define ts_wait u.run.rs_wait+#define ts_running u.run.rs_running+#define ts_locked u.run.rs_locked+#define ts_flushing u.run.rs_flushing+#define ts_logging u.run.rs_logging+#define ts_handle_count u.run.rs_handle_count+#define ts_blocks u.run.rs_blocks+#define ts_blocks_logged u.run.rs_blocks_logged++#define ts_chp_time u.chp.cs_chp_time+#define ts_forced_to_close u.chp.cs_forced_to_close+#define ts_written u.chp.cs_written+#define ts_dropped u.chp.cs_dropped++#define CURRENT_MSECS (jiffies_to_msecs(jiffies))++static inline unsigned int+jbd_time_diff(unsigned int start, unsigned int end)+{+ if (unlikely(start > end))+ end = end + (~0UL - start);+ else+ end -= start;+ return end;+}+ /** * struct journal_s - The journal_s type is the concrete type associated with * journal_t.@@ -828,6 +904,16 @@ struct journal_s struct jbd_revoke_table_s *j_revoke_table[2]; /*+ *+ */+ struct transaction_stats_s *j_history;+ int j_history_max;+ int j_history_cur;+ spinlock_t j_history_lock;+ struct proc_dir_entry *j_proc_entry;+ struct transaction_stats_s j_stats;+ + /* * An opaque pointer to fs-private information. ext3 puts its * superblock pointer here */Index: linux-2.6.9/fs/jbd/commit.c===================================================================--- linux-2.6.9.orig/fs/jbd/commit.c+++ linux-2.6.9/fs/jbd/commit.c@@ -21,6 +21,7 @@ #include <linux/mm.h> #include <linux/pagemap.h> #include <linux/smp_lock.h>+#include <linux/jiffies.h> /* * Default IO end handler for temporary BJ_IO buffer_heads.@@ -101,6 +102,7 @@ static int inverted_lock(journal_t *jour */ void journal_commit_transaction(journal_t *journal) {+ struct transaction_stats_s stats; transaction_t *commit_transaction; struct journal_head *jh, *new_jh, *descriptor; struct buffer_head *wbuf[64];@@ -147,6 +149,11 @@ void journal_commit_transaction(journal_ spin_lock(&journal->j_state_lock); commit_transaction->t_state = T_LOCKED;+ stats.ts_wait = commit_transaction->t_max_wait;+ stats.ts_locked = CURRENT_MSECS;+ stats.ts_running = jbd_time_diff(commit_transaction->t_start,+ stats.ts_locked);+ spin_lock(&commit_transaction->t_handle_lock); while (commit_transaction->t_updates) { DEFINE_WAIT(wait);@@ -219,6 +226,9 @@ void journal_commit_transaction(journal_ */ journal_switch_revoke_table(journal);+ stats.ts_flushing = CURRENT_MSECS;+ stats.ts_locked = jbd_time_diff(stats.ts_locked, stats.ts_flushing);+ commit_transaction->t_state = T_FLUSH; journal->j_committing_transaction = commit_transaction; journal->j_running_transaction = NULL;@@ -365,6 +375,11 @@ write_out_data: */ commit_transaction->t_state = T_COMMIT;+ stats.ts_logging = CURRENT_MSECS;+ stats.ts_flushing = jbd_time_diff(stats.ts_flushing, stats.ts_logging);+ stats.ts_blocks = commit_transaction->t_outstanding_credits;+ stats.ts_blocks_logged = 0;+ descriptor = NULL; bufs = 0; while (commit_transaction->t_buffers) {@@ -513,6 +528,7 @@ start_journal_io: submit_bh(WRITE, bh); } cond_resched();+ stats.ts_blocks_logged += bufs; /* Force a new descriptor to be generated next time round the loop. */@@ -767,6 +783,7 @@ restart_loop: cp_transaction = jh->b_cp_transaction; if (cp_transaction) { JBUFFER_TRACE(jh, "remove from old cp transaction");+ cp_transaction->t_chp_stats.cs_dropped++; __journal_remove_checkpoint(jh); }@@ -816,6 +833,37 @@ restart_loop: } cond_resched_lock(&journal->j_list_lock); }++ commit_transaction->t_start = CURRENT_MSECS;+ stats.ts_logging = jbd_time_diff(stats.ts_logging,+ commit_transaction->t_start);++ /*+ * File the transaction for history+ */+ stats.ts_type = JBD_STATS_RUN;+ stats.ts_tid = commit_transaction->t_tid;+ stats.ts_handle_count = commit_transaction->t_handle_count;+ spin_lock(&journal->j_history_lock);+ memcpy(journal->j_history + journal->j_history_cur, &stats,+ sizeof(stats));+ if (++journal->j_history_cur == journal->j_history_max)+ journal->j_history_cur = 0;++ /*+ * Calculate overall stats+ */+ journal->j_stats.ts_tid++;+ journal->j_stats.ts_wait += stats.ts_wait;+ journal->j_stats.ts_running += stats.ts_running;+ journal->j_stats.ts_locked += stats.ts_locked;+ journal->j_stats.ts_flushing += stats.ts_flushing;+ journal->j_stats.ts_logging += stats.ts_logging;+ journal->j_stats.ts_handle_count += stats.ts_handle_count;+ journal->j_stats.ts_blocks += stats.ts_blocks;+ journal->j_stats.ts_blocks_logged += stats.ts_blocks_logged;+ spin_unlock(&journal->j_history_lock);+ spin_unlock(&journal->j_list_lock); /* * This is a bit sleazy. We borrow j_list_lock to protectIndex: linux-2.6.9/fs/jbd/checkpoint.c===================================================================--- linux-2.6.9.orig/fs/jbd/checkpoint.c+++ linux-2.6.9/fs/jbd/checkpoint.c@@ -166,6 +166,7 @@ static int __cleanup_transaction(journal transaction_t *t = jh->b_transaction; tid_t tid = t->t_tid;+ transaction->t_chp_stats.cs_forced_to_close++; spin_unlock(&journal->j_list_lock); jbd_unlock_bh_state(bh); log_start_commit(journal, tid);@@ -226,7 +227,7 @@ __flush_batch(journal_t *journal, struct */ static int __flush_buffer(journal_t *journal, struct journal_head *jh, struct buffer_head **bhs, int *batch_count,- int *drop_count)+ int *drop_count, transaction_t *transaction) { struct buffer_head *bh = jh2bh(jh); int ret = 0;@@ -247,6 +248,7 @@ static int __flush_buffer(journal_t *jou set_buffer_jwrite(bh); bhs[*batch_count] = bh; jbd_unlock_bh_state(bh);+ transaction->t_chp_stats.cs_written++; (*batch_count)++; if (*batch_count == NR_BATCH) { __flush_batch(journal, bhs, batch_count);@@ -315,6 +317,8 @@ int log_do_checkpoint(journal_t *journal tid_t this_tid; transaction = journal->j_checkpoint_transactions;+ if (transaction->t_chp_stats.cs_chp_time == 0)+ transaction->t_chp_stats.cs_chp_time = CURRENT_MSECS; this_tid = transaction->t_tid; jh = transaction->t_checkpoint_list; last_jh = jh->b_cpprev;@@ -331,7 +335,8 @@ int log_do_checkpoint(journal_t *journal retry = 1; break; }- retry = __flush_buffer(journal, jh, bhs, &batch_count, &drop_count);+ retry = __flush_buffer(journal, jh, bhs, &batch_count, + &drop_count, transaction); } while (jh != last_jh && !retry); if (batch_count) {@@ -597,6 +602,8 @@ void __journal_insert_checkpoint(struct void __journal_drop_transaction(journal_t *journal, transaction_t *transaction) {+ struct transaction_stats_s stats;+ assert_spin_locked(&journal->j_list_lock); if (transaction->t_cpnext) { transaction->t_cpnext->t_cpprev = transaction->t_cpprev;@@ -622,5 +629,25 @@ void __journal_drop_transaction(journal_ J_ASSERT(journal->j_running_transaction != transaction); jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid);++ /*+ * File the transaction for history+ */+ if (transaction->t_chp_stats.cs_written != 0 ||+ transaction->t_chp_stats.cs_chp_time != 0) {+ stats.ts_type = JBD_STATS_CHECKPOINT;+ stats.ts_tid = transaction->t_tid;+ stats.u.chp = transaction->t_chp_stats;+ if (stats.ts_chp_time)+ stats.ts_chp_time = + jbd_time_diff(stats.ts_chp_time, CURRENT_MSECS);+ spin_lock(&journal->j_history_lock);+ memcpy(journal->j_history + journal->j_history_cur, &stats,+ sizeof(stats));+ if (++journal->j_history_cur == journal->j_history_max)+ journal->j_history_cur = 0;+ spin_unlock(&journal->j_history_lock);+ }+ kfree(transaction); }Index: linux-2.6.9/fs/jbd/transaction.c===================================================================--- linux-2.6.9.orig/fs/jbd/transaction.c+++ linux-2.6.9/fs/jbd/transaction.c@@ -60,6 +60,8 @@ get_transaction(journal_t *journal, tran J_ASSERT(journal->j_running_transaction == NULL); journal->j_running_transaction = transaction;+ transaction->t_max_wait = 0;+ transaction->t_start = CURRENT_MSECS; return transaction; }@@ -86,6 +88,7 @@ static int start_this_handle(journal_t * int nblocks = handle->h_buffer_credits; transaction_t *new_transaction = NULL; int ret = 0;+ unsigned long ts = CURRENT_MSECS; if (nblocks > journal->j_max_transaction_buffers) { printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n",@@ -219,6 +222,12 @@ repeat_locked: /* OK, account for the buffers that this operation expects to * use and add the handle to the running transaction. */ + if (time_after(transaction->t_start, ts)) {+ ts = jbd_time_diff(ts, transaction->t_start);+ if (ts > transaction->t_max_wait)+ transaction->t_max_wait= ts;+ }+ handle->h_transaction = transaction; transaction->t_outstanding_credits += nblocks; transaction->t_updates++;Index: linux-2.6.9/fs/jbd/journal.c===================================================================--- linux-2.6.9.orig/fs/jbd/journal.c+++ linux-2.6.9/fs/jbd/journal.c@@ -36,6 +36,7 @@ #include <asm/uaccess.h> #include <asm/page.h> #include <linux/proc_fs.h>+#include <linux/seq_file.h> EXPORT_SYMBOL(journal_start); EXPORT_SYMBOL(journal_restart);@@ -649,6 +650,300 @@ struct journal_head *journal_get_descrip return journal_add_journal_head(bh); } +struct jbd_stats_proc_session {+ journal_t *journal;+ struct transaction_stats_s *stats;+ int start;+ int max;+};++static void *jbd_history_skip_empty(struct jbd_stats_proc_session *s,+ struct transaction_stats_s *ts,+ int first)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -