* have an ID allocated to it anymore, charge the closest online
* ancestor for the swap instead and transfer the memory+swap charge.
*/
- swap_memcg = mem_cgroup_private_id_get_online(memcg);
nr_entries = folio_nr_pages(folio);
- /* Get references for the tail pages, too */
- if (nr_entries > 1)
- mem_cgroup_private_id_get_many(swap_memcg, nr_entries - 1);
+ swap_memcg = mem_cgroup_private_id_get_online(memcg, nr_entries);
mod_memcg_state(swap_memcg, MEMCG_SWAP, nr_entries);
swap_cgroup_record(folio, mem_cgroup_private_id(swap_memcg), entry);
unsigned long memcg_events(struct mem_cgroup *memcg, int event);
int memory_stat_show(struct seq_file *m, void *v);
-void mem_cgroup_private_id_get_many(struct mem_cgroup *memcg, unsigned int n);
-struct mem_cgroup *mem_cgroup_private_id_get_online(struct mem_cgroup *memcg);
+struct mem_cgroup *mem_cgroup_private_id_get_online(struct mem_cgroup *memcg,
+ unsigned int n);
/* Cgroup v1-specific declarations */
#ifdef CONFIG_MEMCG_V1
}
}
-void __maybe_unused mem_cgroup_private_id_get_many(struct mem_cgroup *memcg,
- unsigned int n)
-{
- refcount_add(n, &memcg->id.ref);
-}
-
-static void mem_cgroup_private_id_put_many(struct mem_cgroup *memcg, unsigned int n)
+static inline void mem_cgroup_private_id_put(struct mem_cgroup *memcg, unsigned int n)
{
if (refcount_sub_and_test(n, &memcg->id.ref)) {
mem_cgroup_private_id_remove(memcg);
}
}
-static inline void mem_cgroup_private_id_put(struct mem_cgroup *memcg)
+struct mem_cgroup *mem_cgroup_private_id_get_online(struct mem_cgroup *memcg, unsigned int n)
{
- mem_cgroup_private_id_put_many(memcg, 1);
-}
-
-struct mem_cgroup *mem_cgroup_private_id_get_online(struct mem_cgroup *memcg)
-{
- while (!refcount_inc_not_zero(&memcg->id.ref)) {
+ while (!refcount_add_not_zero(n, &memcg->id.ref)) {
/*
* The root cgroup cannot be destroyed, so it's refcount must
* always be >= 1.
drain_all_stock(memcg);
- mem_cgroup_private_id_put(memcg);
+ mem_cgroup_private_id_put(memcg, 1);
}
static void mem_cgroup_css_released(struct cgroup_subsys_state *css)
return 0;
}
- memcg = mem_cgroup_private_id_get_online(memcg);
+ memcg = mem_cgroup_private_id_get_online(memcg, nr_pages);
if (!mem_cgroup_is_root(memcg) &&
!page_counter_try_charge(&memcg->swap, nr_pages, &counter)) {
memcg_memory_event(memcg, MEMCG_SWAP_MAX);
memcg_memory_event(memcg, MEMCG_SWAP_FAIL);
- mem_cgroup_private_id_put(memcg);
+ mem_cgroup_private_id_put(memcg, nr_pages);
return -ENOMEM;
}
-
- /* Get references for the tail pages, too */
- if (nr_pages > 1)
- mem_cgroup_private_id_get_many(memcg, nr_pages - 1);
mod_memcg_state(memcg, MEMCG_SWAP, nr_pages);
swap_cgroup_record(folio, mem_cgroup_private_id(memcg), entry);
page_counter_uncharge(&memcg->swap, nr_pages);
}
mod_memcg_state(memcg, MEMCG_SWAP, -nr_pages);
- mem_cgroup_private_id_put_many(memcg, nr_pages);
+ mem_cgroup_private_id_put(memcg, nr_pages);
}
rcu_read_unlock();
}