summaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/shmem.c20
-rw-r--r--mm/slub.c13
2 files changed, 22 insertions, 11 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index 3a88c6622432..ba63273ebda7 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1854,11 +1854,12 @@ static void shmem_tag_pins(struct address_space *mapping)
void **slot;
pgoff_t start;
struct page *page;
+ unsigned int tagged = 0;
lru_add_drain();
start = 0;
- rcu_read_lock();
+ spin_lock_irq(&mapping->tree_lock);
restart:
radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) {
page = radix_tree_deref_slot(slot);
@@ -1866,19 +1867,20 @@ restart:
if (radix_tree_deref_retry(page))
goto restart;
} else if (page_count(page) - page_mapcount(page) > 1) {
- spin_lock_irq(&mapping->tree_lock);
radix_tree_tag_set(&mapping->page_tree, iter.index,
SHMEM_TAG_PINNED);
- spin_unlock_irq(&mapping->tree_lock);
}
- if (need_resched()) {
- cond_resched_rcu();
- start = iter.index + 1;
- goto restart;
- }
+ if (++tagged % 1024)
+ continue;
+
+ spin_unlock_irq(&mapping->tree_lock);
+ cond_resched();
+ start = iter.index + 1;
+ spin_lock_irq(&mapping->tree_lock);
+ goto restart;
}
- rcu_read_unlock();
+ spin_unlock_irq(&mapping->tree_lock);
}
/*
diff --git a/mm/slub.c b/mm/slub.c
index 191bbc3378d3..04f8561c19e0 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -4639,7 +4639,17 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
}
}
- get_online_mems();
+ /*
+ * It is impossible to take "mem_hotplug_lock" here with "kernfs_mutex"
+ * already held which will conflict with an existing lock order:
+ *
+ * mem_hotplug_lock->slab_mutex->kernfs_mutex
+ *
+ * We don't really need mem_hotplug_lock (to hold off
+ * slab_mem_going_offline_callback) here because slab's memory hot
+ * unplug code doesn't destroy the kmem_cache->node[] data.
+ */
+
#ifdef CONFIG_SLUB_DEBUG
if (flags & SO_ALL) {
struct kmem_cache_node *n;
@@ -4680,7 +4690,6 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
x += sprintf(buf + x, " N%d=%lu",
node, nodes[node]);
#endif
- put_online_mems();
kfree(nodes);
return x + sprintf(buf + x, "\n");
}