diff options
Diffstat (limited to 'mm')
| -rw-r--r-- | mm/shmem.c | 20 | ||||
| -rw-r--r-- | mm/slub.c | 13 |
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"); } |
