From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 14DE8C433EF for ; Fri, 25 Feb 2022 20:29:34 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 162FA8D0002; Fri, 25 Feb 2022 15:29:34 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 111BA8D0001; Fri, 25 Feb 2022 15:29:34 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0014E8D0002; Fri, 25 Feb 2022 15:29:33 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0056.hostedemail.com [216.40.44.56]) by kanga.kvack.org (Postfix) with ESMTP id E4C738D0001 for ; Fri, 25 Feb 2022 15:29:33 -0500 (EST) Received: from smtpin19.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with ESMTP id 972219F5F4 for ; Fri, 25 Feb 2022 20:29:33 +0000 (UTC) X-FDA: 79182442626.19.5A8F8FF Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by imf15.hostedemail.com (Postfix) with ESMTP id A1783A0021 for ; Fri, 25 Feb 2022 20:29:32 +0000 (UTC) Date: Fri, 25 Feb 2022 21:13:07 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1645819989; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/BpWwwa3UrrnGqWsSuMc0gDmuI2beFCWr4sjiH+86Ao=; b=s6tT3aqsGpNGkByofJ8qal7wMVDI0W7iqVOV12HqnDaiKUsxmrIOKh3k0eljr0PexTw4Gm Wu1Fdg2TsNtx7y51zvh0+DbStqHXUiilKWQh9EwkgqQm+5c3zraEfrWRJkwQNu1Jo8HTYj uGw3enVlEnmaWJHY3ohrmPWxjPvpuG5v5btCTtNfGodOYSm6Vjcpd7D6psCLzCRWY6DQ3r TxhrjGOCKAqbD5dXqReq4XvRlLbrxCsNaUrm5ag5LIMP0REukScBEoWJtRYLJ1w6lbG7mL 2z9yGNPPUOQBQnxkdVF9XsCTm6oy/AQzvnCQ7pCiEI3iszSHkqJ3007RQT4ICQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1645819989; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/BpWwwa3UrrnGqWsSuMc0gDmuI2beFCWr4sjiH+86Ao=; b=bC/EK5l9Fp6eX5seGNFdGpmEbBkH3Jm745DF9MTAVqVkRNXhRpaxYCDISco2G5pQxZu47l ZXgnBdR98uPNi+AQ== From: Sebastian Andrzej Siewior To: Michal Hocko Cc: cgroups@vger.kernel.org, linux-mm@kvack.org, Andrew Morton , Johannes Weiner , Michal =?utf-8?Q?Koutn=C3=BD?= , Peter Zijlstra , Thomas Gleixner , Vladimir Davydov , Waiman Long Subject: [PATCH v5 6/6] mm/memcg: Disable migration instead of preemption in drain_all_stock(). Message-ID: References: <20220221182540.380526-1-bigeasy@linutronix.de> <20220221182540.380526-7-bigeasy@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable In-Reply-To: Authentication-Results: imf15.hostedemail.com; dkim=pass header.d=linutronix.de header.s=2020 header.b=s6tT3aqs; dkim=pass header.d=linutronix.de header.s=2020e header.b="bC/EK5l9"; spf=pass (imf15.hostedemail.com: domain of bigeasy@linutronix.de designates 193.142.43.55 as permitted sender) smtp.mailfrom=bigeasy@linutronix.de; dmarc=pass (policy=none) header.from=linutronix.de X-Rspam-User: X-Rspamd-Server: rspam03 X-Rspamd-Queue-Id: A1783A0021 X-Stat-Signature: eede5mdfqxsnrwg1xyxzxc8aez3u4xae X-HE-Tag: 1645820972-97827 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Before the for-each-CPU loop, preemption is disabled so that so that drain_local_stock() can be invoked directly instead of scheduling a worker. Ensuring that drain_local_stock() completed on the local CPU is not correctness problem. It _could_ be that the charging path will be forced to reclaim memory because cached charges are still waiting for their draining. Disabling preemption before invoking drain_local_stock() is problematic on PREEMPT_RT due to the sleeping locks involved. To ensure that no CPU migrations happens across for_each_online_cpu() it is enouhg to use migrate_disable() which disables migration and keeps context preemptible to a sleeping lock can be acquired. A race with CPU hotplug is not a problem because pcp data is not going away. In the worst case we just schedule draining of an empty stock. Use migrate_disable() instead of get_cpu() around the for_each_online_cpu() loop. Signed-off-by: Sebastian Andrzej Siewior Acked-by: Michal Hocko --- v4=E2=80=A6v5: Added Michal's notes regarding CPU hotplug. mm/memcontrol.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 3d7ccb104374c..9c29b1a0e6bec 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -2293,7 +2293,8 @@ static void drain_all_stock(struct mem_cgroup *root_m= emcg) * as well as workers from this path always operate on the local * per-cpu data. CPU up doesn't touch memcg_stock at all. */ - curcpu =3D get_cpu(); + migrate_disable(); + curcpu =3D smp_processor_id(); for_each_online_cpu(cpu) { struct memcg_stock_pcp *stock =3D &per_cpu(memcg_stock, cpu); struct mem_cgroup *memcg; @@ -2316,7 +2317,7 @@ static void drain_all_stock(struct mem_cgroup *root_m= emcg) schedule_work_on(cpu, &stock->work); } } - put_cpu(); + migrate_enable(); mutex_unlock(&percpu_charge_mutex); } =20 --=20 2.35.1 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Sebastian Andrzej Siewior Subject: [PATCH v5 6/6] mm/memcg: Disable migration instead of preemption in drain_all_stock(). Date: Fri, 25 Feb 2022 21:13:07 +0100 Message-ID: References: <20220221182540.380526-1-bigeasy@linutronix.de> <20220221182540.380526-7-bigeasy@linutronix.de> Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Return-path: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1645819989; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/BpWwwa3UrrnGqWsSuMc0gDmuI2beFCWr4sjiH+86Ao=; b=s6tT3aqsGpNGkByofJ8qal7wMVDI0W7iqVOV12HqnDaiKUsxmrIOKh3k0eljr0PexTw4Gm Wu1Fdg2TsNtx7y51zvh0+DbStqHXUiilKWQh9EwkgqQm+5c3zraEfrWRJkwQNu1Jo8HTYj uGw3enVlEnmaWJHY3ohrmPWxjPvpuG5v5btCTtNfGodOYSm6Vjcpd7D6psCLzCRWY6DQ3r TxhrjGOCKAqbD5dXqReq4XvRlLbrxCsNaUrm5ag5LIMP0REukScBEoWJtRYLJ1w6lbG7mL 2z9yGNPPUOQBQnxkdVF9XsCTm6oy/AQzvnCQ7pCiEI3iszSHkqJ3007RQT4ICQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1645819989; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/BpWwwa3UrrnGqWsSuMc0gDmuI2beFCWr4sjiH+86Ao=; b=bC/EK5l9Fp6eX5seGNFdGpmEbBkH3Jm745DF9MTAVqVkRNXhRpaxYCDISco2G5pQxZu47l ZXgnBdR98uPNi+AQ== Content-Disposition: inline In-Reply-To: List-ID: Content-Type: text/plain; charset="windows-1252" To: Michal Hocko Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org, Andrew Morton , Johannes Weiner , Michal =?utf-8?Q?Koutn=C3=BD?= , Peter Zijlstra , Thomas Gleixner , Vladimir Davydov , Waiman Long Before the for-each-CPU loop, preemption is disabled so that so that drain_local_stock() can be invoked directly instead of scheduling a worker. Ensuring that drain_local_stock() completed on the local CPU is not correctness problem. It _could_ be that the charging path will be forced to reclaim memory because cached charges are still waiting for their draining. Disabling preemption before invoking drain_local_stock() is problematic on PREEMPT_RT due to the sleeping locks involved. To ensure that no CPU migrations happens across for_each_online_cpu() it is enouhg to use migrate_disable() which disables migration and keeps context preemptible to a sleeping lock can be acquired. A race with CPU hotplug is not a problem because pcp data is not going away. In the worst case we just schedule draining of an empty stock. Use migrate_disable() instead of get_cpu() around the for_each_online_cpu() loop. Signed-off-by: Sebastian Andrzej Siewior Acked-by: Michal Hocko --- v4=E2=80=A6v5: Added Michal's notes regarding CPU hotplug. mm/memcontrol.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 3d7ccb104374c..9c29b1a0e6bec 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -2293,7 +2293,8 @@ static void drain_all_stock(struct mem_cgroup *root_m= emcg) * as well as workers from this path always operate on the local * per-cpu data. CPU up doesn't touch memcg_stock at all. */ - curcpu =3D get_cpu(); + migrate_disable(); + curcpu =3D smp_processor_id(); for_each_online_cpu(cpu) { struct memcg_stock_pcp *stock =3D &per_cpu(memcg_stock, cpu); struct mem_cgroup *memcg; @@ -2316,7 +2317,7 @@ static void drain_all_stock(struct mem_cgroup *root_m= emcg) schedule_work_on(cpu, &stock->work); } } - put_cpu(); + migrate_enable(); mutex_unlock(&percpu_charge_mutex); } =20 --=20 2.35.1