Re: [RFC v4+ hot_track 14/19] vfs: add debugfs support

2012-11-06 Thread David Sterba
On Mon, Oct 29, 2012 at 12:30:56PM +0800, zwu.ker...@gmail.com wrote:
 +static int hot_range_seq_show(struct seq_file *seq, void *v)
 +{
 + struct hot_range_item *hr = v;
 + struct hot_inode_item *he = hr-hot_inode;
 + struct hot_freq_data *freq_data = hr-hot_range.hot_freq_data;
 +
 + /* Always lock hot_inode_item first */
 + spin_lock(he-hot_inode.lock);
 + spin_lock(hr-hot_range.lock);
 + seq_printf(seq, inode #%llu, range start  \

the # seems unnecessary to me

 + %llu (range len %u) reads %u, writes %u, 
 + avg read time %llu, avg write time %llu, temp %u\n,

compiler will complain if it sees a %llu format and not the expected
type of 'unsigned long long'

 + he-i_ino,

(unsigned long long)he-i_ino,

 + (u64)hr-start * RANGE_SIZE,
 + hr-len,
 + freq_data-nr_reads,
 + freq_data-nr_writes,
 + freq_data-avg_delta_reads / NSEC_PER_MSEC,
 + freq_data-avg_delta_writes / NSEC_PER_MSEC,
 + freq_data-last_temp  (32 - HEAT_MAP_BITS));
 + spin_unlock(hr-hot_range.lock);
 + spin_unlock(he-hot_inode.lock);
 +
 + return 0;
 +}
 +
 +static int hot_inode_seq_show(struct seq_file *seq, void *v)
 +{
 + struct hot_inode_item *he = v;
 + struct hot_freq_data *freq_data = he-hot_inode.hot_freq_data;
 +
 + spin_lock(he-hot_inode.lock);
 + seq_printf(seq, inode #%llu, reads %u, writes %u,  \
 + avg read time %llu, avg write time %llu, temp %u\n,

(same here)

 + he-i_ino,
 + freq_data-nr_reads,
 + freq_data-nr_writes,
 + freq_data-avg_delta_reads / NSEC_PER_MSEC,
 + freq_data-avg_delta_writes / NSEC_PER_MSEC,
 + freq_data-last_temp  (32 - HEAT_MAP_BITS));
 + spin_unlock(he-hot_inode.lock);
 +
 + return 0;
 +}

 +static void *hot_spot_range_seq_next(struct seq_file *seq, void *v, loff_t 
 *pos)
 +{
 + struct hot_info *root = seq-private;
 + struct hot_range_item *hr_next, *hr = v;
 + struct hot_comm_item *comm_item;
 + struct list_head *n_list;
 + int i =
 +  hr-hot_range.hot_freq_data.last_temp  (32 - HEAT_MAP_BITS);

now I have noticed that I've seen the ... (32 - HEAT_MAP_BITS)
expression so many times that it tend to think it deserves a helper
function

 +
 + n_list = seq_list_next(hr-hot_range.n_list,
 + root-heat_range_map[i].node_list, pos);
 + hot_range_item_put(hr);
 +next:
 + if (n_list) {
 + comm_item = container_of(n_list,
 + struct hot_comm_item, n_list);
 + hr_next = container_of(comm_item,
 + struct hot_range_item, hot_range);
 + kref_get(hr_next-hot_range.refs);
 + return hr_next;
 + } else if (--i = 0) {
 + n_list = seq_list_next(root-heat_range_map[i].node_list,
 + root-heat_range_map[i].node_list, pos);
 + goto next;
 + }
 +
 + return NULL;
 +}
 +
 +static void hot_debugfs_exit(struct super_block *sb)
 +{
 + struct dentry *vol_dentry;
 +
 + vol_dentry = debugfs_get_dentry(sb-s_id,
 + sb-s_hot_root-debugfs_root, strlen(sb-s_id));
 + /* remove all debugfs entries recursively from the volume root */
 + if (vol_dentry)
 + debugfs_remove_recursive(vol_dentry);
 + else
 + BUG_ON(1);

BUG()

 +
 + if (list_empty(sb-s_hot_root-debugfs_root-d_subdirs))
 + debugfs_remove(sb-s_hot_root-debugfs_root);
 +}
 +
 +/*

david
--
To unsubscribe from this list: send the line unsubscribe linux-btrfs in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC v4+ hot_track 14/19] vfs: add debugfs support

2012-11-06 Thread Zhi Yong Wu
On Wed, Nov 7, 2012 at 7:45 AM, David Sterba d...@jikos.cz wrote:
 On Mon, Oct 29, 2012 at 12:30:56PM +0800, zwu.ker...@gmail.com wrote:
 +static int hot_range_seq_show(struct seq_file *seq, void *v)
 +{
 + struct hot_range_item *hr = v;
 + struct hot_inode_item *he = hr-hot_inode;
 + struct hot_freq_data *freq_data = hr-hot_range.hot_freq_data;
 +
 + /* Always lock hot_inode_item first */
 + spin_lock(he-hot_inode.lock);
 + spin_lock(hr-hot_range.lock);
 + seq_printf(seq, inode #%llu, range start  \

 the # seems unnecessary to me
OK, removed.

 + %llu (range len %u) reads %u, writes %u, 
 + avg read time %llu, avg write time %llu, temp %u\n,

 compiler will complain if it sees a %llu format and not the expected
 type of 'unsigned long long'
When built, i haven't seen any warning report about this...

 + he-i_ino,

 (unsigned long long)he-i_ino,

 + (u64)hr-start * RANGE_SIZE,
 + hr-len,
 + freq_data-nr_reads,
 + freq_data-nr_writes,
 + freq_data-avg_delta_reads / NSEC_PER_MSEC,
 + freq_data-avg_delta_writes / NSEC_PER_MSEC,
 + freq_data-last_temp  (32 - HEAT_MAP_BITS));
 + spin_unlock(hr-hot_range.lock);
 + spin_unlock(he-hot_inode.lock);
 +
 + return 0;
 +}
 +
 +static int hot_inode_seq_show(struct seq_file *seq, void *v)
 +{
 + struct hot_inode_item *he = v;
 + struct hot_freq_data *freq_data = he-hot_inode.hot_freq_data;
 +
 + spin_lock(he-hot_inode.lock);
 + seq_printf(seq, inode #%llu, reads %u, writes %u,  \
 + avg read time %llu, avg write time %llu, temp %u\n,

 (same here)
ditto.

 + he-i_ino,
 + freq_data-nr_reads,
 + freq_data-nr_writes,
 + freq_data-avg_delta_reads / NSEC_PER_MSEC,
 + freq_data-avg_delta_writes / NSEC_PER_MSEC,
 + freq_data-last_temp  (32 - HEAT_MAP_BITS));
 + spin_unlock(he-hot_inode.lock);
 +
 + return 0;
 +}

 +static void *hot_spot_range_seq_next(struct seq_file *seq, void *v, loff_t 
 *pos)
 +{
 + struct hot_info *root = seq-private;
 + struct hot_range_item *hr_next, *hr = v;
 + struct hot_comm_item *comm_item;
 + struct list_head *n_list;
 + int i =
 +  hr-hot_range.hot_freq_data.last_temp  (32 - HEAT_MAP_BITS);

 now I have noticed that I've seen the ... (32 - HEAT_MAP_BITS)
 expression so many times that it tend to think it deserves a helper
 function
This helper function has existed, hot_raw_shift(), i will replace this with it.

 +
 + n_list = seq_list_next(hr-hot_range.n_list,
 + root-heat_range_map[i].node_list, pos);
 + hot_range_item_put(hr);
 +next:
 + if (n_list) {
 + comm_item = container_of(n_list,
 + struct hot_comm_item, n_list);
 + hr_next = container_of(comm_item,
 + struct hot_range_item, hot_range);
 + kref_get(hr_next-hot_range.refs);
 + return hr_next;
 + } else if (--i = 0) {
 + n_list = seq_list_next(root-heat_range_map[i].node_list,
 + root-heat_range_map[i].node_list, pos);
 + goto next;
 + }
 +
 + return NULL;
 +}
 +
 +static void hot_debugfs_exit(struct super_block *sb)
 +{
 + struct dentry *vol_dentry;
 +
 + vol_dentry = debugfs_get_dentry(sb-s_id,
 + sb-s_hot_root-debugfs_root, 
 strlen(sb-s_id));
 + /* remove all debugfs entries recursively from the volume root */
 + if (vol_dentry)
 + debugfs_remove_recursive(vol_dentry);
 + else
 + BUG_ON(1);

 BUG()
done, thanks.

 +
 + if (list_empty(sb-s_hot_root-debugfs_root-d_subdirs))
 + debugfs_remove(sb-s_hot_root-debugfs_root);
 +}
 +
 +/*

 david



-- 
Regards,

Zhi Yong Wu
--
To unsubscribe from this list: send the line unsubscribe linux-btrfs in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC v4+ hot_track 14/19] vfs: add debugfs support

2012-10-28 Thread zwu . kernel
From: Zhi Yong Wu wu...@linux.vnet.ibm.com

  Add a /sys/kernel/debug/hot_track/device_name/ directory for each
volume that contains two files. The first, `inode_stats', contains the
heat information for inodes that have been brought into the hot data map
structures. The second, `range_stats', contains similar information for
subfile ranges.

Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com
---
 fs/hot_tracking.c|  484 ++
 fs/hot_tracking.h|5 +
 include/linux/hot_tracking.h |1 +
 3 files changed, 490 insertions(+), 0 deletions(-)

diff --git a/fs/hot_tracking.c b/fs/hot_tracking.c
index 54a8208..376d7fb 100644
--- a/fs/hot_tracking.c
+++ b/fs/hot_tracking.c
@@ -21,6 +21,7 @@
 #include linux/blkdev.h
 #include linux/types.h
 #include linux/list_sort.h
+#include linux/debugfs.h
 #include linux/limits.h
 #include hot_tracking.h
 
@@ -628,6 +629,477 @@ static void hot_update_worker(struct work_struct *work)
 }
 
 /*
+ * take the inode, find ranges associated with inode
+ * and print each range data struct
+ */
+static struct hot_range_item
+*hot_range_tree_walk(struct hot_inode_item *he,
+   loff_t *pos, u32 start, bool flag)
+{
+   struct hot_range_item *hr_nodes[8];
+   loff_t l = *pos;
+   int i, n;
+
+   /* Walk the hot_range_tree for inode */
+   while (1) {
+   spin_lock(he-lock);
+   n = radix_tree_gang_lookup(he-hot_range_tree,
+  (void **)hr_nodes, start,
+  ARRAY_SIZE(hr_nodes));
+   if (!n) {
+   spin_unlock(he-lock);
+   break;
+   }
+   spin_unlock(he-lock);
+
+   start = hr_nodes[n - 1]-start + 1;
+   for (i = 0; i  n; i++) {
+   if ((!flag  !l--) || (flag)) {
+   if (flag)
+   (*pos)++;
+   kref_get(hr_nodes[i]-hot_range.refs);
+   return hr_nodes[i];
+   }
+   }
+   }
+
+   return NULL;
+}
+
+static void
+*hot_inode_tree_walk(struct seq_file *seq, loff_t *pos,
+   u64 ino, bool type, bool flag)
+{
+   struct hot_info *root = seq-private;
+   struct hot_inode_item *hi_nodes[8];
+   struct hot_range_item *hr;
+   loff_t l = *pos;
+   int i, n;
+
+   while (1) {
+   spin_lock(root-lock);
+   n = radix_tree_gang_lookup(root-hot_inode_tree,
+   (void **)hi_nodes, ino,
+   ARRAY_SIZE(hi_nodes));
+   if (!n) {
+   spin_unlock(root-lock);
+   break;
+   }
+   spin_unlock(root-lock);
+
+   ino = hi_nodes[n - 1]-i_ino + 1;
+   for (i = 0; i  n; i++) {
+   if (!type) {
+   hr = hot_range_tree_walk(hi_nodes[i],
+   pos, 0, flag);
+   if (hr)
+   return hr;
+   } else {
+   if ((!flag  !l--) || (flag)) {
+   if (flag)
+   (*pos)++;
+   kref_get(hi_nodes[i]-hot_inode.refs);
+   return hi_nodes[i];
+   }
+   }
+   }
+   }
+
+   return NULL;
+}
+
+static void *hot_range_seq_start(struct seq_file *seq, loff_t *pos)
+{
+   return hot_inode_tree_walk(seq, pos, 0, false, false);
+}
+
+static void *hot_range_seq_next(struct seq_file *seq,
+   void *v, loff_t *pos)
+{
+   struct hot_range_item *hr_next, *hr = v;
+   u32 start = hr-start + 1;
+
+   /* Walk the hot_range_tree for inode */
+   hr_next = hot_range_tree_walk(hr-hot_inode, pos, start, true);
+   if (hr_next)
+   return hr_next;
+
+   return hot_inode_tree_walk(seq, pos,
+   hr-hot_inode-i_ino + 1, false, true);
+}
+
+static void hot_range_seq_stop(struct seq_file *seq, void *v)
+{
+   struct hot_range_item *hr = v;
+
+   if (hr)
+   hot_range_item_put(hr);
+}
+
+static int hot_range_seq_show(struct seq_file *seq, void *v)
+{
+   struct hot_range_item *hr = v;
+   struct hot_inode_item *he = hr-hot_inode;
+   struct hot_freq_data *freq_data = hr-hot_range.hot_freq_data;
+
+   /* Always lock hot_inode_item first */
+   spin_lock(he-hot_inode.lock);
+   spin_lock(hr-hot_range.lock);
+   seq_printf(seq, inode #%llu, range start  \
+   %llu (range len %u) reads %u,