[RFC v3 08/13] vfs: add aging function for old map info

2012-10-10 Thread zwu . kernel
From: Zhi Yong Wu 

Signed-off-by: Zhi Yong Wu 
---
 fs/hot_tracking.c |   57 +
 fs/hot_tracking.h |6 +
 2 files changed, 63 insertions(+), 0 deletions(-)

diff --git a/fs/hot_tracking.c b/fs/hot_tracking.c
index 717faa7..a8dc599 100644
--- a/fs/hot_tracking.c
+++ b/fs/hot_tracking.c
@@ -376,6 +376,24 @@ inline void hot_update_freqs(struct hot_info *root,
hot_inode_item_put(he);
 }
 
+static bool hot_freq_data_is_aging(struct hot_freq_data *freq_data)
+{
+int ret = 0;
+struct timespec ckt = current_kernel_time();
+
+u64 cur_time = timespec_to_ns();
+u64 last_read_ns =
+(cur_time - timespec_to_ns(_data->last_read_time));
+u64 last_write_ns =
+(cur_time - timespec_to_ns(_data->last_write_time));
+u64 kick_ns = TIME_TO_KICK * (u64)10;
+
+if ((last_read_ns > kick_ns) && (last_write_ns > kick_ns))
+ret = 1;
+
+return ret;
+}
+
 static u64 hot_raw_shift(u64 counter, u32 bits, bool dir)
 {
if (dir)
@@ -529,6 +547,45 @@ static void hot_map_array_update(struct hot_freq_data 
*freq_data,
}
 }
 
+/* Update temperatures for each range item for aging purposes */
+static void hot_range_update(struct hot_inode_item *he,
+   struct hot_info *root)
+{
+   struct hot_range_item *hr_nodes[8];
+   u32 start = 0;
+   bool range_is_aging;
+   int i, n;
+
+   while (1) {
+   spin_lock(>lock);
+   n = radix_tree_gang_lookup(>hot_range_tree,
+   (void **)hr_nodes, start,
+   ARRAY_SIZE(hr_nodes));
+   if (!n) {
+   spin_unlock(>lock);
+   break;
+   }
+
+   start = hr_nodes[n - 1]->start + 1;
+   for (i = 0; i < n; i++) {
+   kref_get(_nodes[i]->hot_range.refs);
+   hot_map_array_update(
+   _nodes[i]->hot_range.hot_freq_data, root);
+
+   spin_lock(_nodes[i]->hot_range.lock);
+   range_is_aging = hot_freq_data_is_aging(
+   _nodes[i]->hot_range.hot_freq_data);
+   spin_unlock(_nodes[i]->hot_range.lock);
+
+   hot_range_item_put(hr_nodes[i]);
+   if (range_is_aging) {
+   hot_range_item_put(hr_nodes[i]);
+   }
+   }
+   spin_unlock(>lock);
+   }
+}
+
 /*
  * Initialize inode and range map arrays.
  */
diff --git a/fs/hot_tracking.h b/fs/hot_tracking.h
index 5a9517b..d19e64a 100644
--- a/fs/hot_tracking.h
+++ b/fs/hot_tracking.h
@@ -31,6 +31,12 @@
 #define FREQ_POWER 4
 
 /*
+ * time to quit keeping track of
+ * tracking data (seconds)
+ */
+#define TIME_TO_KICK 400
+
+/*
  * The following comments explain what exactly comprises a unit of heat.
  *
  * Each of six values of heat are calculated and combined in order to form an
-- 
1.7.6.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC v3 08/13] vfs: add aging function for old map info

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

Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com
---
 fs/hot_tracking.c |   57 +
 fs/hot_tracking.h |6 +
 2 files changed, 63 insertions(+), 0 deletions(-)

diff --git a/fs/hot_tracking.c b/fs/hot_tracking.c
index 717faa7..a8dc599 100644
--- a/fs/hot_tracking.c
+++ b/fs/hot_tracking.c
@@ -376,6 +376,24 @@ inline void hot_update_freqs(struct hot_info *root,
hot_inode_item_put(he);
 }
 
+static bool hot_freq_data_is_aging(struct hot_freq_data *freq_data)
+{
+int ret = 0;
+struct timespec ckt = current_kernel_time();
+
+u64 cur_time = timespec_to_ns(ckt);
+u64 last_read_ns =
+(cur_time - timespec_to_ns(freq_data-last_read_time));
+u64 last_write_ns =
+(cur_time - timespec_to_ns(freq_data-last_write_time));
+u64 kick_ns = TIME_TO_KICK * (u64)10;
+
+if ((last_read_ns  kick_ns)  (last_write_ns  kick_ns))
+ret = 1;
+
+return ret;
+}
+
 static u64 hot_raw_shift(u64 counter, u32 bits, bool dir)
 {
if (dir)
@@ -529,6 +547,45 @@ static void hot_map_array_update(struct hot_freq_data 
*freq_data,
}
 }
 
+/* Update temperatures for each range item for aging purposes */
+static void hot_range_update(struct hot_inode_item *he,
+   struct hot_info *root)
+{
+   struct hot_range_item *hr_nodes[8];
+   u32 start = 0;
+   bool range_is_aging;
+   int i, n;
+
+   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;
+   }
+
+   start = hr_nodes[n - 1]-start + 1;
+   for (i = 0; i  n; i++) {
+   kref_get(hr_nodes[i]-hot_range.refs);
+   hot_map_array_update(
+   hr_nodes[i]-hot_range.hot_freq_data, root);
+
+   spin_lock(hr_nodes[i]-hot_range.lock);
+   range_is_aging = hot_freq_data_is_aging(
+   hr_nodes[i]-hot_range.hot_freq_data);
+   spin_unlock(hr_nodes[i]-hot_range.lock);
+
+   hot_range_item_put(hr_nodes[i]);
+   if (range_is_aging) {
+   hot_range_item_put(hr_nodes[i]);
+   }
+   }
+   spin_unlock(he-lock);
+   }
+}
+
 /*
  * Initialize inode and range map arrays.
  */
diff --git a/fs/hot_tracking.h b/fs/hot_tracking.h
index 5a9517b..d19e64a 100644
--- a/fs/hot_tracking.h
+++ b/fs/hot_tracking.h
@@ -31,6 +31,12 @@
 #define FREQ_POWER 4
 
 /*
+ * time to quit keeping track of
+ * tracking data (seconds)
+ */
+#define TIME_TO_KICK 400
+
+/*
  * The following comments explain what exactly comprises a unit of heat.
  *
  * Each of six values of heat are calculated and combined in order to form an
-- 
1.7.6.5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/