1 From 8bd00bc3ee3c0d2703954a1f09c1d96031d5a1a8 Mon Sep 17 00:00:00 2001
2 From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
3 Date: Thu, 29 Jan 2015 17:19:44 +0100
4 Subject: [PATCH 046/366] mm/workingset: Do not protect workingset_shadow_nodes
7 workingset_shadow_nodes is protected by local_irq_disable(). Some users
9 Replace the irq/on with a local_lock(). Rename workingset_shadow_nodes
10 so I catch users of it which will be introduced later.
12 Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
14 include/linux/swap.h | 4 +++-
15 mm/filemap.c | 11 ++++++++---
16 mm/truncate.c | 7 +++++--
17 mm/workingset.c | 23 ++++++++++++-----------
18 4 files changed, 28 insertions(+), 17 deletions(-)
20 diff --git a/include/linux/swap.h b/include/linux/swap.h
21 index d8ca2ea..973b384 100644
22 --- a/include/linux/swap.h
23 +++ b/include/linux/swap.h
26 #include <linux/atomic.h>
27 #include <linux/page-flags.h>
28 +#include <linux/locallock.h>
31 struct notifier_block;
32 @@ -252,7 +253,8 @@ struct swap_info_struct {
33 void *workingset_eviction(struct address_space *mapping, struct page *page);
34 bool workingset_refault(void *shadow);
35 void workingset_activation(struct page *page);
36 -extern struct list_lru workingset_shadow_nodes;
37 +extern struct list_lru __workingset_shadow_nodes;
38 +DECLARE_LOCAL_IRQ_LOCK(workingset_shadow_lock);
40 static inline unsigned int workingset_node_pages(struct radix_tree_node *node)
42 diff --git a/mm/filemap.c b/mm/filemap.c
43 index fad46b1..7fb06d4 100644
46 @@ -144,9 +144,12 @@ static int page_cache_tree_insert(struct address_space *mapping,
47 * node->private_list is protected by
50 - if (!list_empty(&node->private_list))
51 - list_lru_del(&workingset_shadow_nodes,
52 + if (!list_empty(&node->private_list)) {
53 + local_lock(workingset_shadow_lock);
54 + list_lru_del(&__workingset_shadow_nodes,
56 + local_unlock(workingset_shadow_lock);
61 @@ -218,7 +221,9 @@ static void page_cache_tree_delete(struct address_space *mapping,
62 if (!workingset_node_pages(node) &&
63 list_empty(&node->private_list)) {
64 node->private_data = mapping;
65 - list_lru_add(&workingset_shadow_nodes, &node->private_list);
66 + local_lock(workingset_shadow_lock);
67 + list_lru_add(&__workingset_shadow_nodes, &node->private_list);
68 + local_unlock(workingset_shadow_lock);
72 diff --git a/mm/truncate.c b/mm/truncate.c
73 index 76e35ad..5f19642 100644
76 @@ -56,8 +56,11 @@ static void clear_exceptional_entry(struct address_space *mapping,
77 * protected by mapping->tree_lock.
79 if (!workingset_node_shadows(node) &&
80 - !list_empty(&node->private_list))
81 - list_lru_del(&workingset_shadow_nodes, &node->private_list);
82 + !list_empty(&node->private_list)) {
83 + local_lock(workingset_shadow_lock);
84 + list_lru_del(&__workingset_shadow_nodes, &node->private_list);
85 + local_unlock(workingset_shadow_lock);
87 __radix_tree_delete_node(&mapping->page_tree, node);
89 spin_unlock_irq(&mapping->tree_lock);
90 diff --git a/mm/workingset.c b/mm/workingset.c
91 index df66f42..6db7b24 100644
94 @@ -264,7 +264,8 @@ void workingset_activation(struct page *page)
95 * point where they would still be useful.
98 -struct list_lru workingset_shadow_nodes;
99 +struct list_lru __workingset_shadow_nodes;
100 +DEFINE_LOCAL_IRQ_LOCK(workingset_shadow_lock);
102 static unsigned long count_shadow_nodes(struct shrinker *shrinker,
103 struct shrink_control *sc)
104 @@ -274,9 +275,9 @@ static unsigned long count_shadow_nodes(struct shrinker *shrinker,
107 /* list_lru lock nests inside IRQ-safe mapping->tree_lock */
108 - local_irq_disable();
109 - shadow_nodes = list_lru_shrink_count(&workingset_shadow_nodes, sc);
110 - local_irq_enable();
111 + local_lock_irq(workingset_shadow_lock);
112 + shadow_nodes = list_lru_shrink_count(&__workingset_shadow_nodes, sc);
113 + local_unlock_irq(workingset_shadow_lock);
115 pages = node_present_pages(sc->nid);
117 @@ -361,9 +362,9 @@ static enum lru_status shadow_lru_isolate(struct list_head *item,
118 spin_unlock(&mapping->tree_lock);
119 ret = LRU_REMOVED_RETRY;
121 - local_irq_enable();
122 + local_unlock_irq(workingset_shadow_lock);
124 - local_irq_disable();
125 + local_lock_irq(workingset_shadow_lock);
129 @@ -374,10 +375,10 @@ static unsigned long scan_shadow_nodes(struct shrinker *shrinker,
132 /* list_lru lock nests inside IRQ-safe mapping->tree_lock */
133 - local_irq_disable();
134 - ret = list_lru_shrink_walk(&workingset_shadow_nodes, sc,
135 + local_lock_irq(workingset_shadow_lock);
136 + ret = list_lru_shrink_walk(&__workingset_shadow_nodes, sc,
137 shadow_lru_isolate, NULL);
138 - local_irq_enable();
139 + local_unlock_irq(workingset_shadow_lock);
143 @@ -398,7 +399,7 @@ static int __init workingset_init(void)
147 - ret = list_lru_init_key(&workingset_shadow_nodes, &shadow_nodes_key);
148 + ret = list_lru_init_key(&__workingset_shadow_nodes, &shadow_nodes_key);
151 ret = register_shrinker(&workingset_shadow_shrinker);
152 @@ -406,7 +407,7 @@ static int __init workingset_init(void)
156 - list_lru_destroy(&workingset_shadow_nodes);
157 + list_lru_destroy(&__workingset_shadow_nodes);