@@ -421,35 +421,16 @@ static void memcg_reparent_list_lru_node(struct list_lru *lru, int nid,
421
421
spin_unlock_irq (& nlru -> lock );
422
422
}
423
423
424
- static void memcg_reparent_list_lru (struct list_lru * lru ,
425
- int src_idx , struct mem_cgroup * dst_memcg )
426
- {
427
- int i ;
428
-
429
- for_each_node (i )
430
- memcg_reparent_list_lru_node (lru , i , src_idx , dst_memcg );
431
-
432
- memcg_list_lru_free (lru , src_idx );
433
- }
434
-
435
424
void memcg_reparent_list_lrus (struct mem_cgroup * memcg , struct mem_cgroup * parent )
436
425
{
437
426
struct cgroup_subsys_state * css ;
438
427
struct list_lru * lru ;
439
- int src_idx = memcg -> kmemcg_id ;
428
+ int src_idx = memcg -> kmemcg_id , i ;
440
429
441
430
/*
442
431
* Change kmemcg_id of this cgroup and all its descendants to the
443
432
* parent's id, and then move all entries from this cgroup's list_lrus
444
433
* to ones of the parent.
445
- *
446
- * After we have finished, all list_lrus corresponding to this cgroup
447
- * are guaranteed to remain empty. So we can safely free this cgroup's
448
- * list lrus in memcg_list_lru_free().
449
- *
450
- * Changing ->kmemcg_id to the parent can prevent memcg_list_lru_alloc()
451
- * from allocating list lrus for this cgroup after memcg_list_lru_free()
452
- * call.
453
434
*/
454
435
rcu_read_lock ();
455
436
css_for_each_descendant_pre (css , & memcg -> css ) {
@@ -460,9 +441,23 @@ void memcg_reparent_list_lrus(struct mem_cgroup *memcg, struct mem_cgroup *paren
460
441
}
461
442
rcu_read_unlock ();
462
443
444
+ /*
445
+ * With kmemcg_id set to parent, holding the lock of each list_lru_node
446
+ * below can prevent list_lru_{add,del,isolate} from touching the lru,
447
+ * safe to reparent.
448
+ */
463
449
mutex_lock (& list_lrus_mutex );
464
- list_for_each_entry (lru , & memcg_list_lrus , list )
465
- memcg_reparent_list_lru (lru , src_idx , parent );
450
+ list_for_each_entry (lru , & memcg_list_lrus , list ) {
451
+ for_each_node (i )
452
+ memcg_reparent_list_lru_node (lru , i , src_idx , parent );
453
+
454
+ /*
455
+ * Here all list_lrus corresponding to the cgroup are guaranteed
456
+ * to remain empty, we can safely free this lru, any further
457
+ * memcg_list_lru_alloc() call will simply bail out.
458
+ */
459
+ memcg_list_lru_free (lru , src_idx );
460
+ }
466
461
mutex_unlock (& list_lrus_mutex );
467
462
}
468
463
0 commit comments