Whamcloud - gitweb
LU-879 mds: Add a few rename stats under /proc
authorwangdi <di.wang@whamcloud.com>
Fri, 16 Dec 2011 01:19:31 +0000 (17:19 -0800)
committerOleg Drokin <green@whamcloud.com>
Sun, 8 Jan 2012 02:56:15 +0000 (21:56 -0500)
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 <di.wang@whamcloud.com>
Change-Id: I4452ce196802c5724607455e0a9b4b372b06f159
Reviewed-on: http://review.whamcloud.com/1878
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/include/lprocfs_status.h
lustre/mdt/mdt_internal.h
lustre/mdt/mdt_lproc.c
lustre/mdt/mdt_reint.c

index 09bf178..e404768 100644 (file)
@@ -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.
  *
index acb7c78..8a10a6e 100644 (file)
@@ -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);
index f141398..3417cae 100644 (file)
@@ -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");
 }
index 3a11435..9922b82 100644 (file)
@@ -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;