summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.2/0075-dcache-use-a-dispose-list-in-select_parent.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.2/0075-dcache-use-a-dispose-list-in-select_parent.patch')
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.2/0075-dcache-use-a-dispose-list-in-select_parent.patch172
1 files changed, 172 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.2/0075-dcache-use-a-dispose-list-in-select_parent.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.2/0075-dcache-use-a-dispose-list-in-select_parent.patch
new file mode 100644
index 00000000..d369d7a3
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.2/0075-dcache-use-a-dispose-list-in-select_parent.patch
@@ -0,0 +1,172 @@
1From 48a7a2bae38f29f5b231f460dd2852e00e50d549 Mon Sep 17 00:00:00 2001
2From: Dave Chinner <david@fromorbit.com>
3Date: Tue, 23 Aug 2011 18:56:24 +1000
4Subject: [PATCH 075/130] dcache: use a dispose list in select_parent
5
6commit b48f03b319ba78f3abf9a7044d1f436d8d90f4f9 upstream.
7
8select_parent currently abuses the dentry cache LRU to provide
9cleanup features for child dentries that need to be freed. It moves
10them to the tail of the LRU, then tells shrink_dcache_parent() to
11calls __shrink_dcache_sb to unconditionally move them to a dispose
12list (as DCACHE_REFERENCED is ignored). __shrink_dcache_sb() has to
13relock the dentries to move them off the LRU onto the dispose list,
14but otherwise does not touch the dentries that select_parent() moved
15to the tail of the LRU. It then passses the dispose list to
16shrink_dentry_list() which tries to free the dentries.
17
18IOWs, the use of __shrink_dcache_sb() is superfluous - we can build
19exactly the same list of dentries for disposal directly in
20select_parent() and call shrink_dentry_list() instead of calling
21__shrink_dcache_sb() to do that. This means that we avoid long holds
22on the lru lock walking the LRU moving dentries to the dispose list
23We also avoid the need to relock each dentry just to move it off the
24LRU, reducing the numebr of times we lock each dentry to dispose of
25them in shrink_dcache_parent() from 3 to 2 times.
26
27Further, we remove one of the two callers of __shrink_dcache_sb().
28This also means that __shrink_dcache_sb can be moved into back into
29prune_dcache_sb() and we no longer have to handle referenced
30dentries conditionally, simplifying the code.
31
32Signed-off-by: Dave Chinner <dchinner@redhat.com>
33Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
34Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
35Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
36---
37 fs/dcache.c | 63 +++++++++++++++++++---------------------------------------
38 1 files changed, 21 insertions(+), 42 deletions(-)
39
40diff --git a/fs/dcache.c b/fs/dcache.c
41index 89509b5..108116e 100644
42--- a/fs/dcache.c
43+++ b/fs/dcache.c
44@@ -275,15 +275,15 @@ static void dentry_lru_prune(struct dentry *dentry)
45 }
46 }
47
48-static void dentry_lru_move_tail(struct dentry *dentry)
49+static void dentry_lru_move_list(struct dentry *dentry, struct list_head *list)
50 {
51 spin_lock(&dcache_lru_lock);
52 if (list_empty(&dentry->d_lru)) {
53- list_add_tail(&dentry->d_lru, &dentry->d_sb->s_dentry_lru);
54+ list_add_tail(&dentry->d_lru, list);
55 dentry->d_sb->s_nr_dentry_unused++;
56 dentry_stat.nr_unused++;
57 } else {
58- list_move_tail(&dentry->d_lru, &dentry->d_sb->s_dentry_lru);
59+ list_move_tail(&dentry->d_lru, list);
60 }
61 spin_unlock(&dcache_lru_lock);
62 }
63@@ -769,14 +769,18 @@ static void shrink_dentry_list(struct list_head *list)
64 }
65
66 /**
67- * __shrink_dcache_sb - shrink the dentry LRU on a given superblock
68- * @sb: superblock to shrink dentry LRU.
69- * @count: number of entries to prune
70- * @flags: flags to control the dentry processing
71+ * prune_dcache_sb - shrink the dcache
72+ * @sb: superblock
73+ * @count: number of entries to try to free
74+ *
75+ * Attempt to shrink the superblock dcache LRU by @count entries. This is
76+ * done when we need more memory an called from the superblock shrinker
77+ * function.
78 *
79- * If flags contains DCACHE_REFERENCED reference dentries will not be pruned.
80+ * This function may fail to free any resources if all the dentries are in
81+ * use.
82 */
83-static void __shrink_dcache_sb(struct super_block *sb, int count, int flags)
84+void prune_dcache_sb(struct super_block *sb, int count)
85 {
86 struct dentry *dentry;
87 LIST_HEAD(referenced);
88@@ -795,13 +799,7 @@ relock:
89 goto relock;
90 }
91
92- /*
93- * If we are honouring the DCACHE_REFERENCED flag and the
94- * dentry has this flag set, don't free it. Clear the flag
95- * and put it back on the LRU.
96- */
97- if (flags & DCACHE_REFERENCED &&
98- dentry->d_flags & DCACHE_REFERENCED) {
99+ if (dentry->d_flags & DCACHE_REFERENCED) {
100 dentry->d_flags &= ~DCACHE_REFERENCED;
101 list_move(&dentry->d_lru, &referenced);
102 spin_unlock(&dentry->d_lock);
103@@ -821,23 +819,6 @@ relock:
104 }
105
106 /**
107- * prune_dcache_sb - shrink the dcache
108- * @sb: superblock
109- * @nr_to_scan: number of entries to try to free
110- *
111- * Attempt to shrink the superblock dcache LRU by @nr_to_scan entries. This is
112- * done when we need more memory an called from the superblock shrinker
113- * function.
114- *
115- * This function may fail to free any resources if all the dentries are in
116- * use.
117- */
118-void prune_dcache_sb(struct super_block *sb, int nr_to_scan)
119-{
120- __shrink_dcache_sb(sb, nr_to_scan, DCACHE_REFERENCED);
121-}
122-
123-/**
124 * shrink_dcache_sb - shrink dcache for a superblock
125 * @sb: superblock
126 *
127@@ -1091,7 +1072,7 @@ EXPORT_SYMBOL(have_submounts);
128 * drop the lock and return early due to latency
129 * constraints.
130 */
131-static int select_parent(struct dentry * parent)
132+static int select_parent(struct dentry *parent, struct list_head *dispose)
133 {
134 struct dentry *this_parent;
135 struct list_head *next;
136@@ -1113,12 +1094,11 @@ resume:
137
138 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
139
140- /*
141- * move only zero ref count dentries to the end
142- * of the unused list for prune_dcache
143+ /*
144+ * move only zero ref count dentries to the dispose list.
145 */
146 if (!dentry->d_count) {
147- dentry_lru_move_tail(dentry);
148+ dentry_lru_move_list(dentry, dispose);
149 found++;
150 } else {
151 dentry_lru_del(dentry);
152@@ -1180,14 +1160,13 @@ rename_retry:
153 *
154 * Prune the dcache to remove unused children of the parent dentry.
155 */
156-
157 void shrink_dcache_parent(struct dentry * parent)
158 {
159- struct super_block *sb = parent->d_sb;
160+ LIST_HEAD(dispose);
161 int found;
162
163- while ((found = select_parent(parent)) != 0)
164- __shrink_dcache_sb(sb, found, 0);
165+ while ((found = select_parent(parent, &dispose)) != 0)
166+ shrink_dentry_list(&dispose);
167 }
168 EXPORT_SYMBOL(shrink_dcache_parent);
169
170--
1711.7.7.4
172