[Devel] [PATCH rh7] mm/memcg: Bypass charges to offlined cgroup.
Andrey Ryabinin
aryabinin at virtuozzo.com
Fri Jul 13 15:39:16 MSK 2018
On 07/13/2018 03:34 PM, Konstantin Khorenko wrote:
> Do we need it to RK as well for older kernels?
>
Yes.
> --
> Best regards,
>
> Konstantin Khorenko,
> Virtuozzo Linux Kernel Team
>
> On 07/13/2018 02:28 PM, Andrey Ryabinin wrote:
>> Charges to offlined cgroup can happen. E.g. swapped
>> KSM page may charge to offlined cgroup. If such charge
>> races with reparenting during the offlining process
>> it may result in hang in mem_cgroup_reparent_charges()
>>
>> Let's say we have cgroup A and cgroup B. A is parent of
>> B, B is offlined already, and A in the process of offlining.
>> During offline of A, we walk through all childs of A
>> and reparent their charges. After that, we reparent the A itself
>> If charge to B cgroup will appear after the reparenting
>> of B and before reparenting A, the reparanting of A will hang.
>> Charge to B also increases ->memory counter of its parent A,
>> so mem_cgroup_reparent_charges(A) will never satisfy the condition
>> 'A->memory - A->kmem > 0'
>> which is required to break the loop.
>>
>> https://jira.sw.ru/browse/PSBM-86092
>> Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
>> ---
>> mm/memcontrol.c | 22 ++++++++++++++++++++++
>> 1 file changed, 22 insertions(+)
>>
>> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
>> index 59cf47972f9e..8b979d88045c 100644
>> --- a/mm/memcontrol.c
>> +++ b/mm/memcontrol.c
>> @@ -2909,6 +2909,28 @@ static int try_charge(struct mem_cgroup *memcg, gfp_t gfp_mask, bool kmem_charge
>> return -EINTR;
>>
>> done_restock:
>> +
>> + /*
>> + * Cancel charge in case if cgroup was offlined while we were here,
>> + * otherwise we can get a pending user memory charge to an offline
>> + * cgroup, which might race with reparanting in mem_cgroup_css_offline()
>> + * and result in hang.
>> + *
>> + * Note, no need to issue an explicit barrier here, because a
>> + * successful charge implies full memory barrier.
>> + */
>> + if (unlikely(memcg->is_offline)) {
>> + page_counter_uncharge(&memcg->memory, batch);
>> + if (do_swap_account)
>> + page_counter_uncharge(&memcg->memsw, batch);
>> + if (cache_charge)
>> + page_counter_uncharge(&memcg->cache, nr_pages);
>> + if (kmem_charge)
>> + page_counter_uncharge(&memcg->kmem, nr_pages);
>> +
>> + goto bypass;
>> + }
>> +
>> if (batch > nr_pages)
>> refill_stock(memcg, batch - nr_pages);
>> done:
>>
More information about the Devel
mailing list