aboutsummaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2015-01-29 17:19:44 +0100
committerAnders Roxell <anders.roxell@linaro.org>2015-05-08 22:30:32 +0200
commit20ce1926916dfae5c7e279395d7d35edd8430f1e (patch)
tree13f6264fc5df95d36923729e922e686a04d9ac0d /mm
parenta840e72ab1accb16862da56c01eb5adaf0e5a796 (diff)
mm/workingset: do not protect workingset_shadow_nodes with irq off
workingset_shadow_nodes is protected by local_irq_disable(). Some users use spin_lock_irq(). Replace the irq/on with a local_lock(). Rename workingset_shadow_nodes so I catch users of it which will be introduced later. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/filemap.c11
-rw-r--r--mm/truncate.c7
-rw-r--r--mm/workingset.c23
3 files changed, 25 insertions, 16 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index 37beab98b416..9159e0454fba 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -168,7 +168,9 @@ static void page_cache_tree_delete(struct address_space *mapping,
if (!workingset_node_pages(node) &&
list_empty(&node->private_list)) {
node->private_data = mapping;
- list_lru_add(&workingset_shadow_nodes, &node->private_list);
+ local_lock(workingset_shadow_lock);
+ list_lru_add(&__workingset_shadow_nodes, &node->private_list);
+ local_unlock(workingset_shadow_lock);
}
}
@@ -535,9 +537,12 @@ static int page_cache_tree_insert(struct address_space *mapping,
* node->private_list is protected by
* mapping->tree_lock.
*/
- if (!list_empty(&node->private_list))
- list_lru_del(&workingset_shadow_nodes,
+ if (!list_empty(&node->private_list)) {
+ local_lock(workingset_shadow_lock);
+ list_lru_del(&__workingset_shadow_nodes,
&node->private_list);
+ local_unlock(workingset_shadow_lock);
+ }
}
return 0;
}
diff --git a/mm/truncate.c b/mm/truncate.c
index f1e4d6052369..a06369d67fa4 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -56,8 +56,11 @@ static void clear_exceptional_entry(struct address_space *mapping,
* protected by mapping->tree_lock.
*/
if (!workingset_node_shadows(node) &&
- !list_empty(&node->private_list))
- list_lru_del(&workingset_shadow_nodes, &node->private_list);
+ !list_empty(&node->private_list)) {
+ local_lock(workingset_shadow_lock);
+ list_lru_del(&__workingset_shadow_nodes, &node->private_list);
+ local_unlock(workingset_shadow_lock);
+ }
__radix_tree_delete_node(&mapping->page_tree, node);
unlock:
spin_unlock_irq(&mapping->tree_lock);
diff --git a/mm/workingset.c b/mm/workingset.c
index f7216fa7da27..0decb9ca8db8 100644
--- a/mm/workingset.c
+++ b/mm/workingset.c
@@ -264,7 +264,8 @@ void workingset_activation(struct page *page)
* point where they would still be useful.
*/
-struct list_lru workingset_shadow_nodes;
+struct list_lru __workingset_shadow_nodes;
+DEFINE_LOCAL_IRQ_LOCK(workingset_shadow_lock);
static unsigned long count_shadow_nodes(struct shrinker *shrinker,
struct shrink_control *sc)
@@ -274,9 +275,9 @@ static unsigned long count_shadow_nodes(struct shrinker *shrinker,
unsigned long pages;
/* list_lru lock nests inside IRQ-safe mapping->tree_lock */
- local_irq_disable();
- shadow_nodes = list_lru_count_node(&workingset_shadow_nodes, sc->nid);
- local_irq_enable();
+ local_lock_irq(workingset_shadow_lock);
+ shadow_nodes = list_lru_count_node(&__workingset_shadow_nodes, sc->nid);
+ local_unlock_irq(workingset_shadow_lock);
pages = node_present_pages(sc->nid);
/*
@@ -362,9 +363,9 @@ static enum lru_status shadow_lru_isolate(struct list_head *item,
spin_unlock(&mapping->tree_lock);
ret = LRU_REMOVED_RETRY;
out:
- local_irq_enable();
+ local_unlock_irq(workingset_shadow_lock);
cond_resched();
- local_irq_disable();
+ local_lock_irq(workingset_shadow_lock);
spin_lock(lru_lock);
return ret;
}
@@ -375,10 +376,10 @@ static unsigned long scan_shadow_nodes(struct shrinker *shrinker,
unsigned long ret;
/* list_lru lock nests inside IRQ-safe mapping->tree_lock */
- local_irq_disable();
- ret = list_lru_walk_node(&workingset_shadow_nodes, sc->nid,
+ local_lock_irq(workingset_shadow_lock);
+ ret = list_lru_walk_node(&__workingset_shadow_nodes, sc->nid,
shadow_lru_isolate, NULL, &sc->nr_to_scan);
- local_irq_enable();
+ local_unlock_irq(workingset_shadow_lock);
return ret;
}
@@ -399,7 +400,7 @@ static int __init workingset_init(void)
{
int ret;
- ret = list_lru_init_key(&workingset_shadow_nodes, &shadow_nodes_key);
+ ret = list_lru_init_key(&__workingset_shadow_nodes, &shadow_nodes_key);
if (ret)
goto err;
ret = register_shrinker(&workingset_shadow_shrinker);
@@ -407,7 +408,7 @@ static int __init workingset_init(void)
goto err_list_lru;
return 0;
err_list_lru:
- list_lru_destroy(&workingset_shadow_nodes);
+ list_lru_destroy(&__workingset_shadow_nodes);
err:
return ret;
}