• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013 Red Hat, Inc. and Parallels Inc. All rights reserved.
3  * Authors: David Chinner and Glauber Costa
4  *
5  * Generic LRU infrastructure
6  */
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/mm.h>
10 #include <linux/list_lru.h>
11 #include <linux/slab.h>
12 #include <linux/mutex.h>
13 #include <linux/memcontrol.h>
14 
15 #ifdef CONFIG_MEMCG_KMEM
16 static LIST_HEAD(list_lrus);
17 static DEFINE_MUTEX(list_lrus_mutex);
18 
list_lru_register(struct list_lru * lru)19 static void list_lru_register(struct list_lru *lru)
20 {
21 	mutex_lock(&list_lrus_mutex);
22 	list_add(&lru->list, &list_lrus);
23 	mutex_unlock(&list_lrus_mutex);
24 }
25 
list_lru_unregister(struct list_lru * lru)26 static void list_lru_unregister(struct list_lru *lru)
27 {
28 	mutex_lock(&list_lrus_mutex);
29 	list_del(&lru->list);
30 	mutex_unlock(&list_lrus_mutex);
31 }
32 #else
list_lru_register(struct list_lru * lru)33 static void list_lru_register(struct list_lru *lru)
34 {
35 }
36 
list_lru_unregister(struct list_lru * lru)37 static void list_lru_unregister(struct list_lru *lru)
38 {
39 }
40 #endif /* CONFIG_MEMCG_KMEM */
41 
42 #ifdef CONFIG_MEMCG_KMEM
list_lru_memcg_aware(struct list_lru * lru)43 static inline bool list_lru_memcg_aware(struct list_lru *lru)
44 {
45 	return lru->memcg_aware;
46 }
47 
48 static inline struct list_lru_one *
list_lru_from_memcg_idx(struct list_lru_node * nlru,int idx)49 list_lru_from_memcg_idx(struct list_lru_node *nlru, int idx)
50 {
51 	/*
52 	 * The lock protects the array of per cgroup lists from relocation
53 	 * (see memcg_update_list_lru_node).
54 	 */
55 	lockdep_assert_held(&nlru->lock);
56 	if (nlru->memcg_lrus && idx >= 0)
57 		return nlru->memcg_lrus->lru[idx];
58 
59 	return &nlru->lru;
60 }
61 
mem_cgroup_from_kmem(void * ptr)62 static __always_inline struct mem_cgroup *mem_cgroup_from_kmem(void *ptr)
63 {
64 	struct page *page;
65 
66 	if (!memcg_kmem_enabled())
67 		return NULL;
68 	page = virt_to_head_page(ptr);
69 	return page->mem_cgroup;
70 }
71 
72 static inline struct list_lru_one *
list_lru_from_kmem(struct list_lru_node * nlru,void * ptr)73 list_lru_from_kmem(struct list_lru_node *nlru, void *ptr)
74 {
75 	struct mem_cgroup *memcg;
76 
77 	if (!nlru->memcg_lrus)
78 		return &nlru->lru;
79 
80 	memcg = mem_cgroup_from_kmem(ptr);
81 	if (!memcg)
82 		return &nlru->lru;
83 
84 	return list_lru_from_memcg_idx(nlru, memcg_cache_id(memcg));
85 }
86 #else
list_lru_memcg_aware(struct list_lru * lru)87 static inline bool list_lru_memcg_aware(struct list_lru *lru)
88 {
89 	return false;
90 }
91 
92 static inline struct list_lru_one *
list_lru_from_memcg_idx(struct list_lru_node * nlru,int idx)93 list_lru_from_memcg_idx(struct list_lru_node *nlru, int idx)
94 {
95 	return &nlru->lru;
96 }
97 
98 static inline struct list_lru_one *
list_lru_from_kmem(struct list_lru_node * nlru,void * ptr)99 list_lru_from_kmem(struct list_lru_node *nlru, void *ptr)
100 {
101 	return &nlru->lru;
102 }
103 #endif /* CONFIG_MEMCG_KMEM */
104 
list_lru_add(struct list_lru * lru,struct list_head * item)105 bool list_lru_add(struct list_lru *lru, struct list_head *item)
106 {
107 	int nid = page_to_nid(virt_to_page(item));
108 	struct list_lru_node *nlru = &lru->node[nid];
109 	struct list_lru_one *l;
110 
111 	spin_lock(&nlru->lock);
112 	if (list_empty(item)) {
113 		l = list_lru_from_kmem(nlru, item);
114 		list_add_tail(item, &l->list);
115 		l->nr_items++;
116 		nlru->nr_items++;
117 		spin_unlock(&nlru->lock);
118 		return true;
119 	}
120 	spin_unlock(&nlru->lock);
121 	return false;
122 }
123 EXPORT_SYMBOL_GPL(list_lru_add);
124 
list_lru_del(struct list_lru * lru,struct list_head * item)125 bool list_lru_del(struct list_lru *lru, struct list_head *item)
126 {
127 	int nid = page_to_nid(virt_to_page(item));
128 	struct list_lru_node *nlru = &lru->node[nid];
129 	struct list_lru_one *l;
130 
131 	spin_lock(&nlru->lock);
132 	if (!list_empty(item)) {
133 		l = list_lru_from_kmem(nlru, item);
134 		list_del_init(item);
135 		l->nr_items--;
136 		nlru->nr_items--;
137 		spin_unlock(&nlru->lock);
138 		return true;
139 	}
140 	spin_unlock(&nlru->lock);
141 	return false;
142 }
143 EXPORT_SYMBOL_GPL(list_lru_del);
144 
list_lru_isolate(struct list_lru_one * list,struct list_head * item)145 void list_lru_isolate(struct list_lru_one *list, struct list_head *item)
146 {
147 	list_del_init(item);
148 	list->nr_items--;
149 }
150 EXPORT_SYMBOL_GPL(list_lru_isolate);
151 
list_lru_isolate_move(struct list_lru_one * list,struct list_head * item,struct list_head * head)152 void list_lru_isolate_move(struct list_lru_one *list, struct list_head *item,
153 			   struct list_head *head)
154 {
155 	list_move(item, head);
156 	list->nr_items--;
157 }
158 EXPORT_SYMBOL_GPL(list_lru_isolate_move);
159 
__list_lru_count_one(struct list_lru * lru,int nid,int memcg_idx)160 static unsigned long __list_lru_count_one(struct list_lru *lru,
161 					  int nid, int memcg_idx)
162 {
163 	struct list_lru_node *nlru = &lru->node[nid];
164 	struct list_lru_one *l;
165 	unsigned long count;
166 
167 	spin_lock(&nlru->lock);
168 	l = list_lru_from_memcg_idx(nlru, memcg_idx);
169 	count = l->nr_items;
170 	spin_unlock(&nlru->lock);
171 
172 	return count;
173 }
174 
list_lru_count_one(struct list_lru * lru,int nid,struct mem_cgroup * memcg)175 unsigned long list_lru_count_one(struct list_lru *lru,
176 				 int nid, struct mem_cgroup *memcg)
177 {
178 	return __list_lru_count_one(lru, nid, memcg_cache_id(memcg));
179 }
180 EXPORT_SYMBOL_GPL(list_lru_count_one);
181 
list_lru_count_node(struct list_lru * lru,int nid)182 unsigned long list_lru_count_node(struct list_lru *lru, int nid)
183 {
184 	struct list_lru_node *nlru;
185 
186 	nlru = &lru->node[nid];
187 	return nlru->nr_items;
188 }
189 EXPORT_SYMBOL_GPL(list_lru_count_node);
190 
191 static unsigned long
__list_lru_walk_one(struct list_lru * lru,int nid,int memcg_idx,list_lru_walk_cb isolate,void * cb_arg,unsigned long * nr_to_walk)192 __list_lru_walk_one(struct list_lru *lru, int nid, int memcg_idx,
193 		    list_lru_walk_cb isolate, void *cb_arg,
194 		    unsigned long *nr_to_walk)
195 {
196 
197 	struct list_lru_node *nlru = &lru->node[nid];
198 	struct list_lru_one *l;
199 	struct list_head *item, *n;
200 	unsigned long isolated = 0;
201 
202 	spin_lock(&nlru->lock);
203 	l = list_lru_from_memcg_idx(nlru, memcg_idx);
204 restart:
205 	list_for_each_safe(item, n, &l->list) {
206 		enum lru_status ret;
207 
208 		/*
209 		 * decrement nr_to_walk first so that we don't livelock if we
210 		 * get stuck on large numbesr of LRU_RETRY items
211 		 */
212 		if (!*nr_to_walk)
213 			break;
214 		--*nr_to_walk;
215 
216 		ret = isolate(item, l, &nlru->lock, cb_arg);
217 		switch (ret) {
218 		case LRU_REMOVED_RETRY:
219 			assert_spin_locked(&nlru->lock);
220 		case LRU_REMOVED:
221 			isolated++;
222 			nlru->nr_items--;
223 			/*
224 			 * If the lru lock has been dropped, our list
225 			 * traversal is now invalid and so we have to
226 			 * restart from scratch.
227 			 */
228 			if (ret == LRU_REMOVED_RETRY)
229 				goto restart;
230 			break;
231 		case LRU_ROTATE:
232 			list_move_tail(item, &l->list);
233 			break;
234 		case LRU_SKIP:
235 			break;
236 		case LRU_RETRY:
237 			/*
238 			 * The lru lock has been dropped, our list traversal is
239 			 * now invalid and so we have to restart from scratch.
240 			 */
241 			assert_spin_locked(&nlru->lock);
242 			goto restart;
243 		default:
244 			BUG();
245 		}
246 	}
247 
248 	spin_unlock(&nlru->lock);
249 	return isolated;
250 }
251 
252 unsigned long
list_lru_walk_one(struct list_lru * lru,int nid,struct mem_cgroup * memcg,list_lru_walk_cb isolate,void * cb_arg,unsigned long * nr_to_walk)253 list_lru_walk_one(struct list_lru *lru, int nid, struct mem_cgroup *memcg,
254 		  list_lru_walk_cb isolate, void *cb_arg,
255 		  unsigned long *nr_to_walk)
256 {
257 	return __list_lru_walk_one(lru, nid, memcg_cache_id(memcg),
258 				   isolate, cb_arg, nr_to_walk);
259 }
260 EXPORT_SYMBOL_GPL(list_lru_walk_one);
261 
list_lru_walk_node(struct list_lru * lru,int nid,list_lru_walk_cb isolate,void * cb_arg,unsigned long * nr_to_walk)262 unsigned long list_lru_walk_node(struct list_lru *lru, int nid,
263 				 list_lru_walk_cb isolate, void *cb_arg,
264 				 unsigned long *nr_to_walk)
265 {
266 	long isolated = 0;
267 	int memcg_idx;
268 
269 	isolated += __list_lru_walk_one(lru, nid, -1, isolate, cb_arg,
270 					nr_to_walk);
271 	if (*nr_to_walk > 0 && list_lru_memcg_aware(lru)) {
272 		for_each_memcg_cache_index(memcg_idx) {
273 			isolated += __list_lru_walk_one(lru, nid, memcg_idx,
274 						isolate, cb_arg, nr_to_walk);
275 			if (*nr_to_walk <= 0)
276 				break;
277 		}
278 	}
279 	return isolated;
280 }
281 EXPORT_SYMBOL_GPL(list_lru_walk_node);
282 
init_one_lru(struct list_lru_one * l)283 static void init_one_lru(struct list_lru_one *l)
284 {
285 	INIT_LIST_HEAD(&l->list);
286 	l->nr_items = 0;
287 }
288 
289 #ifdef CONFIG_MEMCG_KMEM
__memcg_destroy_list_lru_node(struct list_lru_memcg * memcg_lrus,int begin,int end)290 static void __memcg_destroy_list_lru_node(struct list_lru_memcg *memcg_lrus,
291 					  int begin, int end)
292 {
293 	int i;
294 
295 	for (i = begin; i < end; i++)
296 		kfree(memcg_lrus->lru[i]);
297 }
298 
__memcg_init_list_lru_node(struct list_lru_memcg * memcg_lrus,int begin,int end)299 static int __memcg_init_list_lru_node(struct list_lru_memcg *memcg_lrus,
300 				      int begin, int end)
301 {
302 	int i;
303 
304 	for (i = begin; i < end; i++) {
305 		struct list_lru_one *l;
306 
307 		l = kmalloc(sizeof(struct list_lru_one), GFP_KERNEL);
308 		if (!l)
309 			goto fail;
310 
311 		init_one_lru(l);
312 		memcg_lrus->lru[i] = l;
313 	}
314 	return 0;
315 fail:
316 	__memcg_destroy_list_lru_node(memcg_lrus, begin, i);
317 	return -ENOMEM;
318 }
319 
memcg_init_list_lru_node(struct list_lru_node * nlru)320 static int memcg_init_list_lru_node(struct list_lru_node *nlru)
321 {
322 	int size = memcg_nr_cache_ids;
323 
324 	nlru->memcg_lrus = kmalloc(size * sizeof(void *), GFP_KERNEL);
325 	if (!nlru->memcg_lrus)
326 		return -ENOMEM;
327 
328 	if (__memcg_init_list_lru_node(nlru->memcg_lrus, 0, size)) {
329 		kfree(nlru->memcg_lrus);
330 		return -ENOMEM;
331 	}
332 
333 	return 0;
334 }
335 
memcg_destroy_list_lru_node(struct list_lru_node * nlru)336 static void memcg_destroy_list_lru_node(struct list_lru_node *nlru)
337 {
338 	__memcg_destroy_list_lru_node(nlru->memcg_lrus, 0, memcg_nr_cache_ids);
339 	kfree(nlru->memcg_lrus);
340 }
341 
memcg_update_list_lru_node(struct list_lru_node * nlru,int old_size,int new_size)342 static int memcg_update_list_lru_node(struct list_lru_node *nlru,
343 				      int old_size, int new_size)
344 {
345 	struct list_lru_memcg *old, *new;
346 
347 	BUG_ON(old_size > new_size);
348 
349 	old = nlru->memcg_lrus;
350 	new = kmalloc(new_size * sizeof(void *), GFP_KERNEL);
351 	if (!new)
352 		return -ENOMEM;
353 
354 	if (__memcg_init_list_lru_node(new, old_size, new_size)) {
355 		kfree(new);
356 		return -ENOMEM;
357 	}
358 
359 	memcpy(new, old, old_size * sizeof(void *));
360 
361 	/*
362 	 * The lock guarantees that we won't race with a reader
363 	 * (see list_lru_from_memcg_idx).
364 	 *
365 	 * Since list_lru_{add,del} may be called under an IRQ-safe lock,
366 	 * we have to use IRQ-safe primitives here to avoid deadlock.
367 	 */
368 	spin_lock_irq(&nlru->lock);
369 	nlru->memcg_lrus = new;
370 	spin_unlock_irq(&nlru->lock);
371 
372 	kfree(old);
373 	return 0;
374 }
375 
memcg_cancel_update_list_lru_node(struct list_lru_node * nlru,int old_size,int new_size)376 static void memcg_cancel_update_list_lru_node(struct list_lru_node *nlru,
377 					      int old_size, int new_size)
378 {
379 	/* do not bother shrinking the array back to the old size, because we
380 	 * cannot handle allocation failures here */
381 	__memcg_destroy_list_lru_node(nlru->memcg_lrus, old_size, new_size);
382 }
383 
memcg_init_list_lru(struct list_lru * lru,bool memcg_aware)384 static int memcg_init_list_lru(struct list_lru *lru, bool memcg_aware)
385 {
386 	int i;
387 
388 	lru->memcg_aware = memcg_aware;
389 
390 	if (!memcg_aware)
391 		return 0;
392 
393 	for_each_node(i) {
394 		if (memcg_init_list_lru_node(&lru->node[i]))
395 			goto fail;
396 	}
397 	return 0;
398 fail:
399 	for (i = i - 1; i >= 0; i--) {
400 		if (!lru->node[i].memcg_lrus)
401 			continue;
402 		memcg_destroy_list_lru_node(&lru->node[i]);
403 	}
404 	return -ENOMEM;
405 }
406 
memcg_destroy_list_lru(struct list_lru * lru)407 static void memcg_destroy_list_lru(struct list_lru *lru)
408 {
409 	int i;
410 
411 	if (!list_lru_memcg_aware(lru))
412 		return;
413 
414 	for_each_node(i)
415 		memcg_destroy_list_lru_node(&lru->node[i]);
416 }
417 
memcg_update_list_lru(struct list_lru * lru,int old_size,int new_size)418 static int memcg_update_list_lru(struct list_lru *lru,
419 				 int old_size, int new_size)
420 {
421 	int i;
422 
423 	if (!list_lru_memcg_aware(lru))
424 		return 0;
425 
426 	for_each_node(i) {
427 		if (memcg_update_list_lru_node(&lru->node[i],
428 					       old_size, new_size))
429 			goto fail;
430 	}
431 	return 0;
432 fail:
433 	for (i = i - 1; i >= 0; i--) {
434 		if (!lru->node[i].memcg_lrus)
435 			continue;
436 
437 		memcg_cancel_update_list_lru_node(&lru->node[i],
438 						  old_size, new_size);
439 	}
440 	return -ENOMEM;
441 }
442 
memcg_cancel_update_list_lru(struct list_lru * lru,int old_size,int new_size)443 static void memcg_cancel_update_list_lru(struct list_lru *lru,
444 					 int old_size, int new_size)
445 {
446 	int i;
447 
448 	if (!list_lru_memcg_aware(lru))
449 		return;
450 
451 	for_each_node(i)
452 		memcg_cancel_update_list_lru_node(&lru->node[i],
453 						  old_size, new_size);
454 }
455 
memcg_update_all_list_lrus(int new_size)456 int memcg_update_all_list_lrus(int new_size)
457 {
458 	int ret = 0;
459 	struct list_lru *lru;
460 	int old_size = memcg_nr_cache_ids;
461 
462 	mutex_lock(&list_lrus_mutex);
463 	list_for_each_entry(lru, &list_lrus, list) {
464 		ret = memcg_update_list_lru(lru, old_size, new_size);
465 		if (ret)
466 			goto fail;
467 	}
468 out:
469 	mutex_unlock(&list_lrus_mutex);
470 	return ret;
471 fail:
472 	list_for_each_entry_continue_reverse(lru, &list_lrus, list)
473 		memcg_cancel_update_list_lru(lru, old_size, new_size);
474 	goto out;
475 }
476 
memcg_drain_list_lru_node(struct list_lru_node * nlru,int src_idx,int dst_idx)477 static void memcg_drain_list_lru_node(struct list_lru_node *nlru,
478 				      int src_idx, int dst_idx)
479 {
480 	struct list_lru_one *src, *dst;
481 
482 	/*
483 	 * Since list_lru_{add,del} may be called under an IRQ-safe lock,
484 	 * we have to use IRQ-safe primitives here to avoid deadlock.
485 	 */
486 	spin_lock_irq(&nlru->lock);
487 
488 	src = list_lru_from_memcg_idx(nlru, src_idx);
489 	dst = list_lru_from_memcg_idx(nlru, dst_idx);
490 
491 	list_splice_init(&src->list, &dst->list);
492 	dst->nr_items += src->nr_items;
493 	src->nr_items = 0;
494 
495 	spin_unlock_irq(&nlru->lock);
496 }
497 
memcg_drain_list_lru(struct list_lru * lru,int src_idx,int dst_idx)498 static void memcg_drain_list_lru(struct list_lru *lru,
499 				 int src_idx, int dst_idx)
500 {
501 	int i;
502 
503 	if (!list_lru_memcg_aware(lru))
504 		return;
505 
506 	for_each_node(i)
507 		memcg_drain_list_lru_node(&lru->node[i], src_idx, dst_idx);
508 }
509 
memcg_drain_all_list_lrus(int src_idx,int dst_idx)510 void memcg_drain_all_list_lrus(int src_idx, int dst_idx)
511 {
512 	struct list_lru *lru;
513 
514 	mutex_lock(&list_lrus_mutex);
515 	list_for_each_entry(lru, &list_lrus, list)
516 		memcg_drain_list_lru(lru, src_idx, dst_idx);
517 	mutex_unlock(&list_lrus_mutex);
518 }
519 #else
memcg_init_list_lru(struct list_lru * lru,bool memcg_aware)520 static int memcg_init_list_lru(struct list_lru *lru, bool memcg_aware)
521 {
522 	return 0;
523 }
524 
memcg_destroy_list_lru(struct list_lru * lru)525 static void memcg_destroy_list_lru(struct list_lru *lru)
526 {
527 }
528 #endif /* CONFIG_MEMCG_KMEM */
529 
__list_lru_init(struct list_lru * lru,bool memcg_aware,struct lock_class_key * key)530 int __list_lru_init(struct list_lru *lru, bool memcg_aware,
531 		    struct lock_class_key *key)
532 {
533 	int i;
534 	size_t size = sizeof(*lru->node) * nr_node_ids;
535 	int err = -ENOMEM;
536 
537 	memcg_get_cache_ids();
538 
539 	lru->node = kzalloc(size, GFP_KERNEL);
540 	if (!lru->node)
541 		goto out;
542 
543 	for_each_node(i) {
544 		spin_lock_init(&lru->node[i].lock);
545 		if (key)
546 			lockdep_set_class(&lru->node[i].lock, key);
547 		init_one_lru(&lru->node[i].lru);
548 	}
549 
550 	err = memcg_init_list_lru(lru, memcg_aware);
551 	if (err) {
552 		kfree(lru->node);
553 		/* Do this so a list_lru_destroy() doesn't crash: */
554 		lru->node = NULL;
555 		goto out;
556 	}
557 
558 	list_lru_register(lru);
559 out:
560 	memcg_put_cache_ids();
561 	return err;
562 }
563 EXPORT_SYMBOL_GPL(__list_lru_init);
564 
list_lru_destroy(struct list_lru * lru)565 void list_lru_destroy(struct list_lru *lru)
566 {
567 	/* Already destroyed or not yet initialized? */
568 	if (!lru->node)
569 		return;
570 
571 	memcg_get_cache_ids();
572 
573 	list_lru_unregister(lru);
574 
575 	memcg_destroy_list_lru(lru);
576 	kfree(lru->node);
577 	lru->node = NULL;
578 
579 	memcg_put_cache_ids();
580 }
581 EXPORT_SYMBOL_GPL(list_lru_destroy);
582