| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2013 Red Hat, Inc. and Parallels Inc. All rights reserved. |
|---|
| 3 | 4 | * Authors: David Chinner and Glauber Costa |
|---|
| .. | .. |
|---|
| 11 | 12 | #include <linux/slab.h> |
|---|
| 12 | 13 | #include <linux/mutex.h> |
|---|
| 13 | 14 | #include <linux/memcontrol.h> |
|---|
| 15 | +#include "slab.h" |
|---|
| 14 | 16 | |
|---|
| 15 | 17 | #ifdef CONFIG_MEMCG_KMEM |
|---|
| 16 | 18 | static LIST_HEAD(list_lrus); |
|---|
| .. | .. |
|---|
| 55 | 57 | return &nlru->lru; |
|---|
| 56 | 58 | } |
|---|
| 57 | 59 | |
|---|
| 58 | | -static __always_inline struct mem_cgroup *mem_cgroup_from_kmem(void *ptr) |
|---|
| 59 | | -{ |
|---|
| 60 | | - struct page *page; |
|---|
| 61 | | - |
|---|
| 62 | | - if (!memcg_kmem_enabled()) |
|---|
| 63 | | - return NULL; |
|---|
| 64 | | - page = virt_to_head_page(ptr); |
|---|
| 65 | | - return page->mem_cgroup; |
|---|
| 66 | | -} |
|---|
| 67 | | - |
|---|
| 68 | 60 | static inline struct list_lru_one * |
|---|
| 69 | 61 | list_lru_from_kmem(struct list_lru_node *nlru, void *ptr, |
|---|
| 70 | 62 | struct mem_cgroup **memcg_ptr) |
|---|
| .. | .. |
|---|
| 75 | 67 | if (!nlru->memcg_lrus) |
|---|
| 76 | 68 | goto out; |
|---|
| 77 | 69 | |
|---|
| 78 | | - memcg = mem_cgroup_from_kmem(ptr); |
|---|
| 70 | + memcg = mem_cgroup_from_obj(ptr); |
|---|
| 79 | 71 | if (!memcg) |
|---|
| 80 | 72 | goto out; |
|---|
| 81 | 73 | |
|---|
| .. | .. |
|---|
| 188 | 180 | |
|---|
| 189 | 181 | rcu_read_lock(); |
|---|
| 190 | 182 | l = list_lru_from_memcg_idx(nlru, memcg_cache_id(memcg)); |
|---|
| 191 | | - count = l->nr_items; |
|---|
| 183 | + count = READ_ONCE(l->nr_items); |
|---|
| 192 | 184 | rcu_read_unlock(); |
|---|
| 193 | 185 | |
|---|
| 194 | 186 | return count; |
|---|
| .. | .. |
|---|
| 221 | 213 | |
|---|
| 222 | 214 | /* |
|---|
| 223 | 215 | * decrement nr_to_walk first so that we don't livelock if we |
|---|
| 224 | | - * get stuck on large numbesr of LRU_RETRY items |
|---|
| 216 | + * get stuck on large numbers of LRU_RETRY items |
|---|
| 225 | 217 | */ |
|---|
| 226 | 218 | if (!*nr_to_walk) |
|---|
| 227 | 219 | break; |
|---|
| .. | .. |
|---|
| 231 | 223 | switch (ret) { |
|---|
| 232 | 224 | case LRU_REMOVED_RETRY: |
|---|
| 233 | 225 | assert_spin_locked(&nlru->lock); |
|---|
| 234 | | - /* fall through */ |
|---|
| 226 | + fallthrough; |
|---|
| 235 | 227 | case LRU_REMOVED: |
|---|
| 236 | 228 | isolated++; |
|---|
| 237 | 229 | nlru->nr_items--; |
|---|
| .. | .. |
|---|
| 381 | 373 | struct list_lru_memcg *memcg_lrus; |
|---|
| 382 | 374 | /* |
|---|
| 383 | 375 | * This is called when shrinker has already been unregistered, |
|---|
| 384 | | - * and nobody can use it. So, there is no need to use kvfree_rcu(). |
|---|
| 376 | + * and nobody can use it. So, there is no need to use kvfree_rcu_local(). |
|---|
| 385 | 377 | */ |
|---|
| 386 | 378 | memcg_lrus = rcu_dereference_protected(nlru->memcg_lrus, true); |
|---|
| 387 | 379 | __memcg_destroy_list_lru_node(memcg_lrus, 0, memcg_nr_cache_ids); |
|---|
| 388 | 380 | kvfree(memcg_lrus); |
|---|
| 389 | 381 | } |
|---|
| 390 | 382 | |
|---|
| 391 | | -static void kvfree_rcu(struct rcu_head *head) |
|---|
| 383 | +static void kvfree_rcu_local(struct rcu_head *head) |
|---|
| 392 | 384 | { |
|---|
| 393 | 385 | struct list_lru_memcg *mlru; |
|---|
| 394 | 386 | |
|---|
| .. | .. |
|---|
| 427 | 419 | rcu_assign_pointer(nlru->memcg_lrus, new); |
|---|
| 428 | 420 | spin_unlock_irq(&nlru->lock); |
|---|
| 429 | 421 | |
|---|
| 430 | | - call_rcu(&old->rcu, kvfree_rcu); |
|---|
| 422 | + call_rcu(&old->rcu, kvfree_rcu_local); |
|---|
| 431 | 423 | return 0; |
|---|
| 432 | 424 | } |
|---|
| 433 | 425 | |
|---|
| .. | .. |
|---|
| 599 | 591 | struct lock_class_key *key, struct shrinker *shrinker) |
|---|
| 600 | 592 | { |
|---|
| 601 | 593 | int i; |
|---|
| 602 | | - size_t size = sizeof(*lru->node) * nr_node_ids; |
|---|
| 603 | 594 | int err = -ENOMEM; |
|---|
| 604 | 595 | |
|---|
| 605 | 596 | #ifdef CONFIG_MEMCG_KMEM |
|---|
| .. | .. |
|---|
| 610 | 601 | #endif |
|---|
| 611 | 602 | memcg_get_cache_ids(); |
|---|
| 612 | 603 | |
|---|
| 613 | | - lru->node = kzalloc(size, GFP_KERNEL); |
|---|
| 604 | + lru->node = kcalloc(nr_node_ids, sizeof(*lru->node), GFP_KERNEL); |
|---|
| 614 | 605 | if (!lru->node) |
|---|
| 615 | 606 | goto out; |
|---|
| 616 | 607 | |
|---|