memcg-v1: fully deprecate move_charge_at_immigrate

Patch series "memcg-v1: fully deprecate charge moving".

The memcg v1's charge moving feature has been deprecated for almost 2
years and the kernel warns if someone try to use it.  This warning has
been backported to all stable kernel and there have not been any report of
the warning or the request to support this feature anymore.  Let's proceed
to fully deprecate this feature.


This patch (of 6):

Proceed with the complete deprecation of memcg v1's charge moving feature.
The deprecation warning has been in the kernel for almost two years and
has been ported to all stable kernel since.  Now is the time to fully
deprecate this feature.

Link: https://lkml.kernel.org/r/20241025012304.2473312-1-shakeel.butt@linux.dev
Link: https://lkml.kernel.org/r/20241025012304.2473312-2-shakeel.butt@linux.dev
Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev>
Reviewed-by: Roman Gushchin <roman.gushchin@linux.dev>
Acked-by: Michal Hocko <mhocko@suse.com>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Yosry Ahmed <yosryahmed@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Shakeel Butt 2024-10-24 18:22:58 -07:00 committed by Andrew Morton
parent 729881ffd3
commit aa6b4fdf59
2 changed files with 5 additions and 91 deletions

View File

@ -90,9 +90,7 @@ Brief summary of control files.
used. used.
memory.swappiness set/show swappiness parameter of vmscan memory.swappiness set/show swappiness parameter of vmscan
(See sysctl's vm.swappiness) (See sysctl's vm.swappiness)
memory.move_charge_at_immigrate set/show controls of moving charges memory.move_charge_at_immigrate This knob is deprecated.
This knob is deprecated and shouldn't be
used.
memory.oom_control set/show oom controls. memory.oom_control set/show oom controls.
This knob is deprecated and shouldn't be This knob is deprecated and shouldn't be
used. used.
@ -243,10 +241,6 @@ behind this approach is that a cgroup that aggressively uses a shared
page will eventually get charged for it (once it is uncharged from page will eventually get charged for it (once it is uncharged from
the cgroup that brought it in -- this will happen on memory pressure). the cgroup that brought it in -- this will happen on memory pressure).
But see :ref:`section 8.2 <cgroup-v1-memory-movable-charges>` when moving a
task to another cgroup, its pages may be recharged to the new cgroup, if
move_charge_at_immigrate has been chosen.
2.4 Swap Extension 2.4 Swap Extension
-------------------------------------- --------------------------------------
@ -756,78 +750,8 @@ If we want to change this to 1G, we can at any time use::
THIS IS DEPRECATED! THIS IS DEPRECATED!
It's expensive and unreliable! It's better practice to launch workload Reading memory.move_charge_at_immigrate will always return 0 and writing
tasks directly from inside their target cgroup. Use dedicated workload to it will always return -EINVAL.
cgroups to allow fine-grained policy adjustments without having to
move physical pages between control domains.
Users can move charges associated with a task along with task migration, that
is, uncharge task's pages from the old cgroup and charge them to the new cgroup.
This feature is not supported in !CONFIG_MMU environments because of lack of
page tables.
8.1 Interface
-------------
This feature is disabled by default. It can be enabled (and disabled again) by
writing to memory.move_charge_at_immigrate of the destination cgroup.
If you want to enable it::
# echo (some positive value) > memory.move_charge_at_immigrate
.. note::
Each bits of move_charge_at_immigrate has its own meaning about what type
of charges should be moved. See :ref:`section 8.2
<cgroup-v1-memory-movable-charges>` for details.
.. note::
Charges are moved only when you move mm->owner, in other words,
a leader of a thread group.
.. note::
If we cannot find enough space for the task in the destination cgroup, we
try to make space by reclaiming memory. Task migration may fail if we
cannot make enough space.
.. note::
It can take several seconds if you move charges much.
And if you want disable it again::
# echo 0 > memory.move_charge_at_immigrate
.. _cgroup-v1-memory-movable-charges:
8.2 Type of charges which can be moved
--------------------------------------
Each bit in move_charge_at_immigrate has its own meaning about what type of
charges should be moved. But in any case, it must be noted that an account of
a page or a swap can be moved only when it is charged to the task's current
(old) memory cgroup.
+---+--------------------------------------------------------------------------+
|bit| what type of charges would be moved ? |
+===+==========================================================================+
| 0 | A charge of an anonymous page (or swap of it) used by the target task. |
| | You must enable Swap Extension (see 2.4) to enable move of swap charges. |
+---+--------------------------------------------------------------------------+
| 1 | A charge of file pages (normal file, tmpfs file (e.g. ipc shared memory) |
| | and swaps of tmpfs file) mmapped by the target task. Unlike the case of |
| | anonymous pages, file pages (and swaps) in the range mmapped by the task |
| | will be moved even if the task hasn't done page fault, i.e. they might |
| | not be the task's "RSS", but other task's "RSS" that maps the same file. |
| | The mapcount of the page is ignored (the page can be moved independent |
| | of the mapcount). You must enable Swap Extension (see 2.4) to |
| | enable move of swap charges. |
+---+--------------------------------------------------------------------------+
8.3 TODO
--------
- All of moving charge operations are done under cgroup_mutex. It's not good
behavior to hold the mutex too long, so we may need some trick.
9. Memory thresholds 9. Memory thresholds
==================== ====================

View File

@ -593,29 +593,19 @@ static inline int mem_cgroup_move_swap_account(swp_entry_t entry,
static u64 mem_cgroup_move_charge_read(struct cgroup_subsys_state *css, static u64 mem_cgroup_move_charge_read(struct cgroup_subsys_state *css,
struct cftype *cft) struct cftype *cft)
{ {
return mem_cgroup_from_css(css)->move_charge_at_immigrate; return 0;
} }
#ifdef CONFIG_MMU #ifdef CONFIG_MMU
static int mem_cgroup_move_charge_write(struct cgroup_subsys_state *css, static int mem_cgroup_move_charge_write(struct cgroup_subsys_state *css,
struct cftype *cft, u64 val) struct cftype *cft, u64 val)
{ {
struct mem_cgroup *memcg = mem_cgroup_from_css(css);
pr_warn_once("Cgroup memory moving (move_charge_at_immigrate) is deprecated. " pr_warn_once("Cgroup memory moving (move_charge_at_immigrate) is deprecated. "
"Please report your usecase to linux-mm@kvack.org if you " "Please report your usecase to linux-mm@kvack.org if you "
"depend on this functionality.\n"); "depend on this functionality.\n");
if (val & ~MOVE_MASK) if (val != 0)
return -EINVAL; return -EINVAL;
/*
* No kind of locking is needed in here, because ->can_attach() will
* check this value once in the beginning of the process, and then carry
* on with stale data. This means that changes to this value will only
* affect task migrations starting after the change.
*/
memcg->move_charge_at_immigrate = val;
return 0; return 0;
} }
#else #else