Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp288297pxa; Wed, 19 Aug 2020 01:00:03 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzD3L0nxsXPGHh8il6FImszUAXfcYm9XNI8zWoZdOJh+9LJ87+KKW+YwQQ3zwkIYEw954AE X-Received: by 2002:a7b:c8c9:: with SMTP id f9mr3880387wml.40.1597824002941; Wed, 19 Aug 2020 01:00:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597824002; cv=none; d=google.com; s=arc-20160816; b=oziShLGsLBOOH6jLD01Lg7+327x5dCqB9lDHWBIV6LabzuBvWc24J/j22G+JC3MZh1 9JAw3jmbmtpO6AHnOcwXyKREtkOXPjijjohqvr9VrAC7FGvtpfkeFqHjLBu2wQCmecKR 63JxZv+7j9C4J1eNDead6BTfAwrEZijz0cgYF/Suqp6KwAQD6hFqFOzS13v6oW1Ih9e2 uwNpVb0RaBjhH+a4L19owAwT9yLtm+7CGz44XQX9mODS7rD3UfZTZ2W4mqB4E27R/PNy 4yoNr6knk68pVctHrR8VMZLzoB1HwOlQ+akVuqUocXAqJxSbogECFtvZk2CzOAKzNHrM aSLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:in-reply-to :mime-version:user-agent:date:message-id:from:references:cc:to :subject; bh=j6/blvzTuRUqB38DKRR8/1IMyLZZ4rkUjxTPdYot+xE=; b=XtkmVZdARhtUg55eeKy7T6t0hzrZHxJ7p9aTe8TPVGu7/mvwZNy/AHKBcwqedqJoEE AaIndGVR2k1TQ3fi85WP+CAC3VafUcTY+/PqKHK04dizEcA1lfbRbYO/iGl9yg3i3ouL z+S3GiO3PhvjaDkXHGnvLuEKgbnDYb++bFpGrVtDo8T52PniYXEqfJ9qKDujS3DLX5If QmhMwWlvxShBN5fnee7LlE0xxZYZ9NKU/utDGhocO9UHXMBZInzxR7D17AukaGAPHCl9 Kh6hZhd0dIeXTtIL9IF+Zbwyx7kw68qDEtUd8hwXntfF6jcl1ex12/cScqINOqHiRaBm 5PuA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id j7si18267393ejo.66.2020.08.19.00.59.39; Wed, 19 Aug 2020 01:00:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=alibaba.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726911AbgHSH6R (ORCPT + 99 others); Wed, 19 Aug 2020 03:58:17 -0400 Received: from out4436.biz.mail.alibaba.com ([47.88.44.36]:53076 "EHLO out4436.biz.mail.alibaba.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726570AbgHSH6L (ORCPT ); Wed, 19 Aug 2020 03:58:11 -0400 X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R881e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=e01e07488;MF=alex.shi@linux.alibaba.com;NM=1;PH=DS;RN=19;SR=0;TI=SMTPD_---0U6D5.Xk_1597823875; Received: from IT-FVFX43SYHV2H.local(mailfrom:alex.shi@linux.alibaba.com fp:SMTPD_---0U6D5.Xk_1597823875) by smtp.aliyun-inc.com(127.0.0.1); Wed, 19 Aug 2020 15:57:57 +0800 Subject: Re: [RFC PATCH v2 5/5] mm: Split move_pages_to_lru into 3 separate passes To: Alexander Duyck Cc: yang.shi@linux.alibaba.com, lkp@intel.com, rong.a.chen@intel.com, khlebnikov@yandex-team.ru, kirill@shutemov.name, hughd@google.com, linux-kernel@vger.kernel.org, daniel.m.jordan@oracle.com, linux-mm@kvack.org, shakeelb@google.com, willy@infradead.org, hannes@cmpxchg.org, tj@kernel.org, cgroups@vger.kernel.org, akpm@linux-foundation.org, richard.weiyang@gmail.com, mgorman@techsingularity.net, iamjoonsoo.kim@lge.com References: <20200819041852.23414.95939.stgit@localhost.localdomain> <20200819042738.23414.60815.stgit@localhost.localdomain> From: Alex Shi Message-ID: <084c58a7-7aac-820c-9606-19391c35b9b5@linux.alibaba.com> Date: Wed, 19 Aug 2020 15:56:43 +0800 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <20200819042738.23414.60815.stgit@localhost.localdomain> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 在 2020/8/19 下午12:27, Alexander Duyck 写道: > From: Alexander Duyck > > The current code for move_pages_to_lru is meant to release the LRU lock > every time it encounters an unevictable page or a compound page that must > be freed. This results in a fair amount of code bulk because the lruvec has > to be reacquired every time the lock is released and reacquired. > > Instead of doing this I believe we can break the code up into 3 passes. The > first pass will identify the pages we can move to LRU and move those. In > addition it will sort the list out leaving the unevictable pages in the > list and moving those pages that have dropped to a reference count of 0 to > pages_to_free. The second pass will return the unevictable pages to the > LRU. The final pass will free any compound pages we have in the > pages_to_free list before we merge it back with the original list and > return from the function. > > The advantage of doing it this way is that we only have to release the lock > between pass 1 and 2, and then we reacquire the lock after pass 3 after we > merge the pages_to_free back into the original list. As such we only have > to release the lock at most once in an entire call instead of having to > test to see if we need to relock with each page. > > Signed-off-by: Alexander Duyck > --- > mm/vmscan.c | 68 ++++++++++++++++++++++++++++++++++------------------------- > 1 file changed, 39 insertions(+), 29 deletions(-) > > diff --git a/mm/vmscan.c b/mm/vmscan.c > index 3ebe3f9b653b..6a2bdbc1a9eb 100644 > --- a/mm/vmscan.c > +++ b/mm/vmscan.c > @@ -1850,22 +1850,21 @@ static unsigned noinline_for_stack move_pages_to_lru(struct lruvec *lruvec, > { > int nr_pages, nr_moved = 0; > LIST_HEAD(pages_to_free); > - struct page *page; > - struct lruvec *orig_lruvec = lruvec; > + struct page *page, *next; > enum lru_list lru; > > - while (!list_empty(list)) { > - page = lru_to_page(list); > + list_for_each_entry_safe(page, next, list, lru) { > VM_BUG_ON_PAGE(PageLRU(page), page); > - list_del(&page->lru); > - if (unlikely(!page_evictable(page))) { > - if (lruvec) { > - spin_unlock_irq(&lruvec->lru_lock); > - lruvec = NULL; > - } > - putback_lru_page(page); > + > + /* > + * if page is unevictable leave it on the list to be returned > + * to the LRU after we have finished processing the other > + * entries in the list. > + */ > + if (unlikely(!page_evictable(page))) > continue; > - } > + > + list_del(&page->lru); > > /* > * The SetPageLRU needs to be kept here for list intergrity. > @@ -1878,20 +1877,14 @@ static unsigned noinline_for_stack move_pages_to_lru(struct lruvec *lruvec, > * list_add(&page->lru,) > * list_add(&page->lru,) > */ > - lruvec = relock_page_lruvec_irq(page, lruvec); It's actually changed the meaning from current func. which I had seen a bug if no relock. but after move to 5.9 kernel, I can not reprodce the bug any more. I am not sure if 5.9 fixed the problem, and we don't need relock here. For the rest of this patch. Reviewed-by: Alex Shi > SetPageLRU(page); > > if (unlikely(put_page_testzero(page))) { > __ClearPageLRU(page); > __ClearPageActive(page); > > - if (unlikely(PageCompound(page))) { > - spin_unlock_irq(&lruvec->lru_lock); > - lruvec = NULL; > - destroy_compound_page(page); > - } else > - list_add(&page->lru, &pages_to_free); > - > + /* defer freeing until we can release lru_lock */ > + list_add(&page->lru, &pages_to_free); > continue; > } > > @@ -1904,16 +1897,33 @@ static unsigned noinline_for_stack move_pages_to_lru(struct lruvec *lruvec, > if (PageActive(page)) > workingset_age_nonresident(lruvec, nr_pages); > } > - if (orig_lruvec != lruvec) { > - if (lruvec) > - spin_unlock_irq(&lruvec->lru_lock); > - spin_lock_irq(&orig_lruvec->lru_lock); > - } > > - /* > - * To save our caller's stack, now use input list for pages to free. > - */ > - list_splice(&pages_to_free, list); > + if (unlikely(!list_empty(list) || !list_empty(&pages_to_free))) { > + spin_unlock_irq(&lruvec->lru_lock); > + > + /* return any unevictable pages to the LRU list */ > + while (!list_empty(list)) { > + page = lru_to_page(list); > + list_del(&page->lru); > + putback_lru_page(page); > + } > + > + /* > + * To save our caller's stack use input > + * list for pages to free. > + */ > + list_splice(&pages_to_free, list); > + > + /* free any compound pages we have in the list */ > + list_for_each_entry_safe(page, next, list, lru) { > + if (likely(!PageCompound(page))) > + continue; > + list_del(&page->lru); > + destroy_compound_page(page); > + } > + > + spin_lock_irq(&lruvec->lru_lock); > + } > > return nr_moved; > } >