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 X-Spam-Level: X-Spam-Status: No, score=-18.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0F0F9C433ED for ; Wed, 28 Apr 2021 15:05:22 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 6D9CB61419 for ; Wed, 28 Apr 2021 15:05:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6D9CB61419 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id D2C9D6B0036; Wed, 28 Apr 2021 11:05:20 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id D03666B0071; Wed, 28 Apr 2021 11:05:20 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B7E8F8D0001; Wed, 28 Apr 2021 11:05:20 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0245.hostedemail.com [216.40.44.245]) by kanga.kvack.org (Postfix) with ESMTP id 97C086B0036 for ; Wed, 28 Apr 2021 11:05:20 -0400 (EDT) Received: from smtpin23.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id 1AA59181AF5C2 for ; Wed, 28 Apr 2021 15:05:20 +0000 (UTC) X-FDA: 78082099200.23.372E639 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) by imf04.hostedemail.com (Postfix) with ESMTP id BECE23F4 for ; Wed, 28 Apr 2021 15:05:15 +0000 (UTC) Received: by mail-wm1-f54.google.com with SMTP id m5so7254614wmf.1 for ; Wed, 28 Apr 2021 08:05:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=/utO0JUES8bqsMHp6o1HbmgumSL9/IkbjkGaOE+fxJM=; b=sXVaOijJfNFI19nbo7RcDhdrRvL5CF+2EI4624OSIpoi7pG8IP89DKxS8Uaq8ge+2l 0hhhOb/xBebUTxMR81v1MENznZIYN8p/aowm+NcKsJfimzDOi5642mdEaAr451xFuwAB ZTK6Kl/mOS1Q0TkWzoFG6gpHHKkuJsGSjBYMLDNVPeEKBs03SQWVSHpXl9iCB0cqncZE WrhhN8Xv78oE9RgL7XKoiSuUG+NoRPdW07vrPRg4Cz3sdR11V2uoTL1xI7Vz9iooUPqz K3Rr/sbEXYL+nmAuKQDWDknH05q9pctZu5yJ23e+Dynnt9pmVJuuUEwlH/G426VNx4T4 grzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=/utO0JUES8bqsMHp6o1HbmgumSL9/IkbjkGaOE+fxJM=; b=Eort76BSPDR+sM2zJ78TQW8ru8HOohrY+5YbB2FCwF2V+pxdro+SHxm4UzDZuwJEow j57MtN3Wi72NZQCwUXF44DwmRX2kTvpq8DAkl7D+CvlsV+mAdH595EiboDeXub0ugZrM Q6m8VrrenKyn8jISHRM37kG28p7M9hORFpRphy2YRBnqGX+K5vRnJNBP9xEe6eNiFwhU uEFYOx+0+p1LCnXZSeJYNeXEV/TMcaOq8Qzu3HQNoS+YOnlMrFLU1ZpYWBcoqAgjq4kN 5YSDXgA5V1MNcCAwYaah8NGJexzFcRxb8BQLvPlZnlc1LLtQvuMJJn+myleVd5zJkSl2 hYzA== X-Gm-Message-State: AOAM530zqd03y8E0PURRU59bhBWkiCucyYTvtwmCPL/+BrtfuLuNg9eP jeFX2tHydbELI7q+mLz1dXb9pn2Ze/hE9juXeU719g== X-Google-Smtp-Source: ABdhPJwzc8Bo3yQZy0zHTPtuY0RXeQo+X9BpX8xL6qrPlR+iYaCnn0fD7g7FalokrLkDRRHwImEJLPllBxUO+I/e9jk= X-Received: by 2002:a7b:c929:: with SMTP id h9mr3588261wml.48.1619622317994; Wed, 28 Apr 2021 08:05:17 -0700 (PDT) MIME-Version: 1.0 References: <20210416023536.168632-1-zhengjun.xing@linux.intel.com> <7b7a1c09-3d16-e199-15d2-ccea906d4a66@linux.intel.com> In-Reply-To: From: Yu Zhao Date: Wed, 28 Apr 2021 09:05:06 -0600 Message-ID: Subject: Re: [RFC] mm/vmscan.c: avoid possible long latency caused by too_many_isolated() To: Michal Hocko Cc: Xing Zhengjun , Andrew Morton , Linux-MM , linux-kernel , Huang Ying , Tim Chen , Shakeel Butt , wfg@mail.ustc.edu.cn, Rik van Riel , Andrea Arcangeli Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Rspamd-Server: rspam03 X-Rspamd-Queue-Id: BECE23F4 X-Stat-Signature: dxj7p4qnne8odm8xhr5qsgnx3wk8j7b3 Received-SPF: none (google.com>: No applicable sender policy available) receiver=imf04; identity=mailfrom; envelope-from=""; helo=mail-wm1-f54.google.com; client-ip=209.85.128.54 X-HE-DKIM-Result: pass/pass X-HE-Tag: 1619622315-600562 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: On Wed, Apr 28, 2021 at 5:55 AM Michal Hocko wrote: > > [Cc Rik and Andrea] > > On Thu 22-04-21 11:13:34, Yu Zhao wrote: > > On Thu, Apr 22, 2021 at 04:36:19PM +0800, Xing Zhengjun wrote: > > > Hi, > > > > > > In the system with very few file pages (nr_active_file + nr_inacti= ve_file > > > < 100), it is easy to reproduce "nr_isolated_file > nr_inactive_file"= , then > > > too_many_isolated return true, shrink_inactive_list enter "msleep(100= )", the > > > long latency will happen. > > > > > > The test case to reproduce it is very simple: allocate many huge page= s(near > > > the DRAM size), then do free, repeat the same operation many times. > > > In the test case, the system with very few file pages (nr_active_file= + > > > nr_inactive_file < 100), I have dumpped the numbers of > > > active/inactive/isolated file pages during the whole test(see in the > > > attachments) , in shrink_inactive_list "too_many_isolated" is very ea= sy to > > > return true, then enter "msleep(100)",in "too_many_isolated" sc->gfp_= mask is > > > 0x342cca ("_GFP_IO" and "__GFP_FS" is masked) , it is also very easy = to > > > enter =E2=80=9Cinactive >>=3D3=E2=80=9D, then =E2=80=9Cisolated > ina= ctive=E2=80=9D will be true. > > > > > > So I have a proposal to set a threshold number for the total file pa= ges to > > > ignore the system with very few file pages, and then bypass the 100ms= sleep. > > > It is hard to set a perfect number for the threshold, so I just give = an > > > example of "256" for it. > > > > > > I appreciate it if you can give me your suggestion/comments. Thanks. > > > > Hi Zhengjun, > > > > It seems to me using the number of isolated pages to keep a lid on > > direct reclaimers is not a good solution. We shouldn't keep going > > that direction if we really want to fix the problem because migration > > can isolate many pages too, which in turn blocks page reclaim. > > > > Here is something works a lot better. Please give it a try. Thanks. > > O do have a very vague recollection that number of reclaimers used to be > a criterion in very old days and it has proven to be quite bad in the > end. I am sorry but I do not have an reference at hands and do not have > time to crawl git history. Maybe Rik/Andrea will remember details. Well, I found nothing. > The existing throttling mechanism is quite far from optimal but it aims > at handling close to OOM situations where effectivelly a large part of > the existing LRUs can be already isolated. We already have a retry > logic which is LRU aware in the page allocator > (should_reclaim_retry). The logic would have to be extended but that > sounds like a better fit for the back off to me. > > > diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h > > index 507d216610bf2..9a09f7e76f6b8 100644 > > --- a/include/linux/mmzone.h > > +++ b/include/linux/mmzone.h > > @@ -951,6 +951,8 @@ typedef struct pglist_data { > > > > /* Fields commonly accessed by the page reclaim scanner */ > > > > + atomic_t nr_reclaimers; > > + > > /* > > * NOTE: THIS IS UNUSED IF MEMCG IS ENABLED. > > * > > diff --git a/mm/vmscan.c b/mm/vmscan.c > > index 1c080fafec396..f7278642290a6 100644 > > --- a/mm/vmscan.c > > +++ b/mm/vmscan.c > > @@ -1786,43 +1786,6 @@ int isolate_lru_page(struct page *page) > > return ret; > > } > > > > -/* > > - * A direct reclaimer may isolate SWAP_CLUSTER_MAX pages from the LRU = list and > > - * then get rescheduled. When there are massive number of tasks doing = page > > - * allocation, such sleeping direct reclaimers may keep piling up on e= ach CPU, > > - * the LRU list will go small and be scanned faster than necessary, le= ading to > > - * unnecessary swapping, thrashing and OOM. > > - */ > > -static int too_many_isolated(struct pglist_data *pgdat, int file, > > - struct scan_control *sc) > > -{ > > - unsigned long inactive, isolated; > > - > > - if (current_is_kswapd()) > > - return 0; > > - > > - if (!writeback_throttling_sane(sc)) > > - return 0; > > - > > - if (file) { > > - inactive =3D node_page_state(pgdat, NR_INACTIVE_FILE); > > - isolated =3D node_page_state(pgdat, NR_ISOLATED_FILE); > > - } else { > > - inactive =3D node_page_state(pgdat, NR_INACTIVE_ANON); > > - isolated =3D node_page_state(pgdat, NR_ISOLATED_ANON); > > - } > > - > > - /* > > - * GFP_NOIO/GFP_NOFS callers are allowed to isolate more pages, s= o they > > - * won't get blocked by normal direct-reclaimers, forming a circu= lar > > - * deadlock. > > - */ > > - if ((sc->gfp_mask & (__GFP_IO | __GFP_FS)) =3D=3D (__GFP_IO | __G= FP_FS)) > > - inactive >>=3D 3; > > - > > - return isolated > inactive; > > -} > > - > > /* > > * move_pages_to_lru() moves pages from private @list to appropriate L= RU list. > > * On return, @list is reused as a list of pages to be freed by the ca= ller. > > @@ -1924,19 +1887,6 @@ shrink_inactive_list(unsigned long nr_to_scan, s= truct lruvec *lruvec, > > struct pglist_data *pgdat =3D lruvec_pgdat(lruvec); > > bool stalled =3D false; > > > > - while (unlikely(too_many_isolated(pgdat, file, sc))) { > > - if (stalled) > > - return 0; > > - > > - /* wait a bit for the reclaimer. */ > > - msleep(100); > > - stalled =3D true; > > - > > - /* We are about to die and free our memory. Return now. *= / > > - if (fatal_signal_pending(current)) > > - return SWAP_CLUSTER_MAX; > > - } > > - > > lru_add_drain(); > > > > spin_lock_irq(&lruvec->lru_lock); > > @@ -3302,6 +3252,7 @@ static bool throttle_direct_reclaim(gfp_t gfp_mas= k, struct zonelist *zonelist, > > unsigned long try_to_free_pages(struct zonelist *zonelist, int order, > > gfp_t gfp_mask, nodemask_t *nodemask) > > { > > + int nr_cpus; > > unsigned long nr_reclaimed; > > struct scan_control sc =3D { > > .nr_to_reclaim =3D SWAP_CLUSTER_MAX, > > @@ -3334,8 +3285,17 @@ unsigned long try_to_free_pages(struct zonelist = *zonelist, int order, > > set_task_reclaim_state(current, &sc.reclaim_state); > > trace_mm_vmscan_direct_reclaim_begin(order, sc.gfp_mask); > > > > + nr_cpus =3D current_is_kswapd() ? 0 : num_online_cpus(); > > + while (nr_cpus && !atomic_add_unless(&pgdat->nr_reclaimers, 1, nr= _cpus)) { > > + if (schedule_timeout_killable(HZ / 10)) > > + return SWAP_CLUSTER_MAX; > > + } > > + > > nr_reclaimed =3D do_try_to_free_pages(zonelist, &sc); > > > > + if (nr_cpus) > > + atomic_dec(&pgdat->nr_reclaimers); > > + > > trace_mm_vmscan_direct_reclaim_end(nr_reclaimed); > > set_task_reclaim_state(current, NULL); > > This will surely break any memcg direct reclaim. Mind elaborating how it will "surely" break any memcg direct reclaim?