From 7c8ebf7b9825d0aadd9ffcf01508f093afc68af9 Mon Sep 17 00:00:00 2001 From: wangdi Date: Thu, 15 Dec 2011 17:19:31 -0800 Subject: [PATCH] LU-879 mds: Add a few rename stats under /proc 1. Add samedir_rename in /proc/fs/lustre/mds/lustre-MDT0000/stats to collect stats of same dir rename. 2. Add crossdir_rename in /proc/fs/lustre/mds/lustre-MDT0000/stats to collect stats of cross dir rename. 3. Add /proc/fs/lustre/mds/lustre-MDT0000/rename_stats(YAML format) to collect stats of rename stats happened on different size directories. The size of directories under which files are being removed. With these patches, it will find out how many renames take place in the same directory compared to how many renames are between So during DNE implementation, we can know how rename may be affected by DNE remote directories and large striped directories. Signed-off-by: Wang Di Change-Id: I4452ce196802c5724607455e0a9b4b372b06f159 Reviewed-on: http://review.whamcloud.com/1878 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Oleg Drokin Reviewed-by: Andreas Dilger --- lustre/include/lprocfs_status.h | 10 +++ lustre/mdt/mdt_internal.h | 6 ++ lustre/mdt/mdt_lproc.c | 161 ++++++++++++++++++++++++++++++++++++++++ lustre/mdt/mdt_reint.c | 3 + 4 files changed, 180 insertions(+) diff --git a/lustre/include/lprocfs_status.h b/lustre/include/lprocfs_status.h index 09bf178..e404768 100644 --- a/lustre/include/lprocfs_status.h +++ b/lustre/include/lprocfs_status.h @@ -103,6 +103,16 @@ struct brw_stats { struct obd_histogram hist[BRW_LAST]; }; +enum { + RENAME_SAMEDIR_SIZE = 0, + RENAME_CROSSDIR_SRC_SIZE, + RENAME_CROSSDIR_TGT_SIZE, + RENAME_LAST, +}; + +struct rename_stats { + struct obd_histogram hist[RENAME_LAST]; +}; /* An lprocfs counter can be configured using the enum bit masks below. * diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h index acb7c78..8a10a6e 100644 --- a/lustre/mdt/mdt_internal.h +++ b/lustre/mdt/mdt_internal.h @@ -172,6 +172,7 @@ struct mdt_device { cfs_proc_dir_entry_t *mdt_proc_entry; struct lprocfs_stats *mdt_stats; int mdt_sec_level; + struct rename_stats mdt_rename_stats; }; #define MDT_SERVICE_WATCHDOG_FACTOR (2) @@ -812,6 +813,8 @@ enum { LPROC_MDT_SETXATTR, LPROC_MDT_STATFS, LPROC_MDT_SYNC, + LPROC_MDT_SAMEDIR_RENAME, + LPROC_MDT_CROSSDIR_RENAME, LPROC_MDT_LAST, }; void mdt_counter_incr(struct obd_export *exp, int opcode); @@ -819,6 +822,9 @@ void mdt_stats_counter_init(struct lprocfs_stats *stats); void lprocfs_mdt_init_vars(struct lprocfs_static_vars *lvars); int mdt_procfs_init(struct mdt_device *mdt, const char *name); int mdt_procfs_fini(struct mdt_device *mdt); +void mdt_rename_counter_tally(struct mdt_thread_info *info, + struct mdt_device *mdt, struct obd_export *exp, + struct mdt_object *src, struct mdt_object *tgt); void mdt_time_start(const struct mdt_thread_info *info); void mdt_time_end(const struct mdt_thread_info *info, int idx); diff --git a/lustre/mdt/mdt_lproc.c b/lustre/mdt/mdt_lproc.c index f141398..3417cae 100644 --- a/lustre/mdt/mdt_lproc.c +++ b/lustre/mdt/mdt_lproc.c @@ -77,6 +77,158 @@ enum { static const char *mdt_proc_names[LPROC_MDT_NR] = { }; +/** + * The rename stats output would be YAML formats, like + * rename_stats: + * - snapshot_time: 1234567890.123456 + * - same_dir: + * 4kB: { samples: 1230, pct: 33, cum_pct: 45 } + * 8kB: { samples: 1242, pct: 33, cum_pct: 78 } + * 16kB: { samples: 132, pct: 3, cum_pct: 81 } + * - crossdir_src: + * 4kB: { samples: 123, pct: 33, cum_pct: 45 } + * 8kB: { samples: 124, pct: 33, cum_pct: 78 } + * 16kB: { samples: 12, pct: 3, cum_pct: 81 } + * - crossdir_tgt: + * 4kB: { samples: 123, pct: 33, cum_pct: 45 } + * 8kB: { samples: 124, pct: 33, cum_pct: 78 } + * 16kB: { samples: 12, pct: 3, cum_pct: 81 } + **/ + +#define pct(a, b) (b ? a * 100 / b : 0) + +static void display_rename_stats(struct seq_file *seq, char *name, + struct obd_histogram *hist) +{ + unsigned long tot, t, cum = 0; + int i; + + tot = lprocfs_oh_sum(hist); + if (tot > 0) + seq_printf(seq, "- %-15s\n", name); + /* dir size start from 4K, start i from 10(2^10) here */ + for (i = 0; i < OBD_HIST_MAX; i++) { + t = hist->oh_buckets[i]; + cum += t; + if (cum == 0) + continue; + + if (i < 10) + seq_printf(seq, "%6s%d%s", " ", 1<< i, "bytes:"); + else if (i < 20) + seq_printf(seq, "%6s%d%s", " ", 1<<(i-10), "KB:"); + else + seq_printf(seq, "%6s%d%s", " ", 1<<(i-20), "MB:"); + + seq_printf(seq, " { sample: %3lu, pct: %3lu, cum_pct: %3lu }\n", + t, pct(t, tot), pct(cum, tot)); + + if (cum == tot) + break; + } +} + +static void rename_stats_show(struct seq_file *seq, + struct rename_stats *rename_stats) +{ + struct timeval now; + + /* this sampling races with updates */ + do_gettimeofday(&now); + seq_printf(seq, "rename_stats:\n"); + seq_printf(seq, "- %-15s %lu.%lu\n", "snapshot_time:", + now.tv_sec, now.tv_usec); + + display_rename_stats(seq, "same_dir", + &rename_stats->hist[RENAME_SAMEDIR_SIZE]); + display_rename_stats(seq, "crossdir_src", + &rename_stats->hist[RENAME_CROSSDIR_SRC_SIZE]); + display_rename_stats(seq, "crossdir_tgt", + &rename_stats->hist[RENAME_CROSSDIR_TGT_SIZE]); +} + +#undef pct + +static int mdt_rename_stats_seq_show(struct seq_file *seq, void *v) +{ + struct mdt_device *mdt = seq->private; + + rename_stats_show(seq, &mdt->mdt_rename_stats); + + return 0; +} + +static ssize_t mdt_rename_stats_seq_write(struct file *file, const char *buf, + size_t len, loff_t *off) +{ + struct seq_file *seq = file->private_data; + struct mdt_device *mdt = seq->private; + int i; + + for (i = 0; i < RENAME_LAST; i++) + lprocfs_oh_clear(&mdt->mdt_rename_stats.hist[i]); + + return len; +} + +LPROC_SEQ_FOPS(mdt_rename_stats); + +static int lproc_mdt_attach_rename_seqstat(struct mdt_device *mdt) +{ + struct lu_device *ld = &mdt->mdt_md_dev.md_lu_dev; + struct obd_device *obd = ld->ld_obd; + int i; + + for (i = 0; i < RENAME_LAST; i++) + spin_lock_init(&mdt->mdt_rename_stats.hist[i].oh_lock); + + return lprocfs_obd_seq_create(obd, "rename_stats", 0444, + &mdt_rename_stats_fops, mdt); +} + +void mdt_rename_counter_tally(struct mdt_thread_info *info, + struct mdt_device *mdt, + struct obd_export *exp, + struct mdt_object *src, + struct mdt_object *tgt) +{ + struct md_attr *ma = &info->mti_attr; + struct rename_stats *rstats = &mdt->mdt_rename_stats; + int rc; + + ma->ma_need = MA_INODE; + ma->ma_valid = 0; + rc = mo_attr_get(info->mti_env, mdt_object_child(src), ma); + if (rc) { + CERROR("%s: "DFID" attr_get, rc = %d\n", + exp->exp_obd->obd_name, PFID(mdt_object_fid(src)), rc); + return; + } + + if (src == tgt) { + mdt_counter_incr(exp, LPROC_MDT_SAMEDIR_RENAME); + lprocfs_oh_tally_log2(&rstats->hist[RENAME_SAMEDIR_SIZE], + (unsigned int)ma->ma_attr.la_size); + return; + } + + mdt_counter_incr(exp, LPROC_MDT_CROSSDIR_RENAME); + lprocfs_oh_tally_log2(&rstats->hist[RENAME_CROSSDIR_SRC_SIZE], + (unsigned int)ma->ma_attr.la_size); + + ma->ma_need = MA_INODE; + ma->ma_valid = 0; + rc = mo_attr_get(info->mti_env, mdt_object_child(tgt), ma); + if (rc) { + CERROR("%s: "DFID" attr_get, rc = %d\n", + exp->exp_obd->obd_name, PFID(mdt_object_fid(tgt)), rc); + return; + } + + lprocfs_oh_tally_log2(&rstats->hist[RENAME_CROSSDIR_TGT_SIZE], + (unsigned int)ma->ma_attr.la_size); +} + int mdt_procfs_init(struct mdt_device *mdt, const char *name) { struct lu_device *ld = &mdt->mdt_md_dev.md_lu_dev; @@ -118,6 +270,11 @@ int mdt_procfs_init(struct mdt_device *mdt, const char *name) if (rc == 0) mdt_stats_counter_init(obd->md_stats); + rc = lproc_mdt_attach_rename_seqstat(mdt); + if (rc) + CERROR("%s: MDT can not create rename stats rc = %d\n", + obd->obd_name, rc); + RETURN(rc); } @@ -851,4 +1008,8 @@ void mdt_stats_counter_init(struct lprocfs_stats *stats) lprocfs_counter_init(stats, LPROC_MDT_SETXATTR, 0, "setxattr", "reqs"); lprocfs_counter_init(stats, LPROC_MDT_STATFS, 0, "statfs", "reqs"); lprocfs_counter_init(stats, LPROC_MDT_SYNC, 0, "sync", "reqs"); + lprocfs_counter_init(stats, LPROC_MDT_SAMEDIR_RENAME, 0, + "samedir_rename", "reqs"); + lprocfs_counter_init(stats, LPROC_MDT_CROSSDIR_RENAME, 0, + "crossdir_rename", "reqs"); } diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index 3a11435..9922b82 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -1278,6 +1278,9 @@ static int mdt_reint_rename(struct mdt_thread_info *info, mdt_counter_incr(req->rq_export, LPROC_MDT_RENAME); if (mnew) mdt_handle_last_unlink(info, mnew, ma); + + mdt_rename_counter_tally(info, info->mti_mdt, req->rq_export, + msrcdir, mtgtdir); } EXIT; -- 1.8.3.1