lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <bfd67339-6202-9a7a-3765-4608913bcbd3@suse.cz>
Date:   Thu, 19 Oct 2017 15:21:38 +0200
From:   Vlastimil Babka <vbabka@...e.cz>
To:     Mel Gorman <mgorman@...hsingularity.net>
Cc:     Andrew Morton <akpm@...ux-foundation.org>,
        Linux-MM <linux-mm@...ck.org>,
        Linux-FSDevel <linux-fsdevel@...r.kernel.org>,
        LKML <linux-kernel@...r.kernel.org>, Jan Kara <jack@...e.cz>,
        Andi Kleen <ak@...ux.intel.com>,
        Dave Hansen <dave.hansen@...el.com>,
        Dave Chinner <david@...morbit.com>
Subject: Re: [PATCH 4/8] mm: Only drain per-cpu pagevecs once per pagevec
 usage

On 10/19/2017 11:33 AM, Mel Gorman wrote:
> On Thu, Oct 19, 2017 at 11:12:52AM +0200, Vlastimil Babka wrote:
>> On 10/18/2017 09:59 AM, Mel Gorman wrote:
>>> When a pagevec is initialised on the stack, it is generally used multiple
>>> times over a range of pages, looking up entries and then releasing them.
>>> On each pagevec_release, the per-cpu deferred LRU pagevecs are drained
>>> on the grounds the page being released may be on those queues and the
>>> pages may be cache hot. In many cases only the first drain is necessary
>>> as it's unlikely that the range of pages being walked is racing against
>>> LRU addition.  Even if there is such a race, the impact is marginal where
>>> as constantly redraining the lru pagevecs costs.
>>
>> Right, the drain is only to a local cpu, not all of them, so that kind
>> of "racing" shouldn't be even possible.
>>
> 
> Potentially the user of the pagevec can be preempted and another process
> modify the per-cpu pagevecs in parallel. Note even that users of a pagevec
> in a loop may call cond_resched so preemption is not even necessary if
> the pagevec is being used for a large enough number of operations. The
> risk is still marginal.
> 
>>> This patch ensures that pagevec is only drained once in a given lifecycle
>>> without increasing the cache footprint of the pagevec structure. Only
>>
>> Well, strictly speaking it does prevent decreasing the cache footprint
>> by removing the 'cold' field later :)
>>
> 
> Debatable. Even freeing a cold page if it was handled properly still has
> a cache footprint impact because the struct page fields are accessed.
> Maybe that's not what you meant and you are referring to the size of the
> structure itself.

Yes, I meant the size, sorry.

> If so, note that I change the type of the two fields so
> they should fit in the same size as an unsigned long in many cases.

Yeah.

> It's not draining the LRU as such. How about the following patch on top
> of the series? If another full series repost is necessary, I'll fold it
> in.

Looks good, thanks! The series is already in mmots so I expect Andrew
will fold it to the original patch.

> ---8<---
> mm, pagevec: Rename pagevec drained field
> 
> According to Vlastimil Babka, the drained field in pagevec is potentially
> misleading because it might be interpreted as draining this pagevec instead
> of the percpu lru pagevecs. Rename the field for clarity.
> 
> Suggested-by: Vlastimil Babka <vbabka@...e.cz>
> Signed-off-by: Mel Gorman <mgorman@...hsingularity.net>
> ---
>  include/linux/pagevec.h | 4 ++--
>  mm/swap.c               | 4 ++--
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
> index 8dcde51e80ff..ba5dc27ef6bb 100644
> --- a/include/linux/pagevec.h
> +++ b/include/linux/pagevec.h
> @@ -16,7 +16,7 @@ struct address_space;
>  
>  struct pagevec {
>  	unsigned long nr;
> -	bool drained;
> +	bool percpu_pvec_drained;
>  	struct page *pages[PAGEVEC_SIZE];
>  };
>  
> @@ -52,7 +52,7 @@ static inline unsigned pagevec_lookup_tag(struct pagevec *pvec,
>  static inline void pagevec_init(struct pagevec *pvec)
>  {
>  	pvec->nr = 0;
> -	pvec->drained = false;
> +	pvec->percpu_pvec_drained = false;
>  }
>  
>  static inline void pagevec_reinit(struct pagevec *pvec)
> diff --git a/mm/swap.c b/mm/swap.c
> index b480279c760c..38e1b6374a97 100644
> --- a/mm/swap.c
> +++ b/mm/swap.c
> @@ -833,9 +833,9 @@ EXPORT_SYMBOL(release_pages);
>   */
>  void __pagevec_release(struct pagevec *pvec)
>  {
> -	if (!pvec->drained) {
> +	if (!pvec->percpu_pvec_drained) {
>  		lru_add_drain();
> -		pvec->drained = true;
> +		pvec->percpu_pvec_drained = true;
>  	}
>  	release_pages(pvec->pages, pagevec_count(pvec));
>  	pagevec_reinit(pvec);
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ