Linux kernel -stable discussions
 help / color / mirror / Atom feed
From: "Paul E. McKenney" <paulmck@kernel.org>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: chris@chris-wilson.co.uk, David.Laight@ACULAB.COM,
	elver@google.com, mark.rutland@arm.com,
	mm-commits@vger.kernel.org, rdunlap@infradead.org,
	stable@vger.kernel.org
Subject: Re: + list-prevent-compiler-reloads-inside-safe-list-iteration.patch added to -mm tree
Date: Sat, 14 Mar 2020 07:13:38 -0700	[thread overview]
Message-ID: <20200314141338.GM3199@paulmck-ThinkPad-P72> (raw)
In-Reply-To: <20200312025809.80ZDC8y7j%akpm@linux-foundation.org>

On Wed, Mar 11, 2020 at 07:58:09PM -0700, Andrew Morton wrote:
> 
> The patch titled
>      Subject: lib/list: prevent compiler reloads inside 'safe' list iteration
> has been added to the -mm tree.  Its filename is
>      list-prevent-compiler-reloads-inside-safe-list-iteration.patch
> 
> This patch should soon appear at
>     http://ozlabs.org/~akpm/mmots/broken-out/list-prevent-compiler-reloads-inside-safe-list-iteration.patch
> and later at
>     http://ozlabs.org/~akpm/mmotm/broken-out/list-prevent-compiler-reloads-inside-safe-list-iteration.patch
> 
> Before you just go and hit "reply", please:
>    a) Consider who else should be cc'ed
>    b) Prefer to cc a suitable mailing list as well
>    c) Ideally: find the original patch on the mailing list and do a
>       reply-to-all to that, adding suitable additional cc's
> 
> *** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
> 
> The -mm tree is included into linux-next and is updated
> there every 3-4 working days
> 
> ------------------------------------------------------
> From: Chris Wilson <chris@chris-wilson.co.uk>
> Subject: lib/list: prevent compiler reloads inside 'safe' list iteration
> 
> Instruct the compiler to read the next element in the list iteration
> once, and that it is not allowed to reload the value from the stale
> element later. This is important as during the course of the safe
> iteration, the stale element may be poisoned (unbeknownst to the
> compiler).
> 
> This helps prevent kcsan warnings over 'unsafe' conduct in releasing the
> list elements during list_for_each_entry_safe() and friends.
> 
> Link: http://lkml.kernel.org/r/20200310092119.14965-1-chris@chris-wilson.co.uk
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: "Paul E. McKenney" <paulmck@kernel.org>
> Cc: Randy Dunlap <rdunlap@infradead.org>
> Cc: David Laight <David.Laight@ACULAB.COM>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Marco Elver <elver@google.com>
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

One possible concern is that we are overloading the suffix "_safe()",
but that looks better to me than yet another explosion of this API.
It would be good to have uses, of course.

Reviewed-by: Paul E. McKenney <paulmck@kernel.org>

> ---
> 
>  include/linux/list.h |   50 +++++++++++++++++++++++++++++------------
>  1 file changed, 36 insertions(+), 14 deletions(-)
> 
> --- a/include/linux/list.h~list-prevent-compiler-reloads-inside-safe-list-iteration
> +++ a/include/linux/list.h
> @@ -537,6 +537,17 @@ static inline void list_splice_tail_init
>  	list_entry((pos)->member.next, typeof(*(pos)), member)
>  
>  /**
> + * list_next_entry_safe - get the next element in list [once]
> + * @pos:	the type * to cursor
> + * @member:	the name of the list_head within the struct.
> + *
> + * Like list_next_entry() but prevents the compiler from reloading the
> + * next element.
> + */
> +#define list_next_entry_safe(pos, member) \
> +	list_entry(READ_ONCE((pos)->member.next), typeof(*(pos)), member)
> +
> +/**
>   * list_prev_entry - get the prev element in list
>   * @pos:	the type * to cursor
>   * @member:	the name of the list_head within the struct.
> @@ -545,6 +556,17 @@ static inline void list_splice_tail_init
>  	list_entry((pos)->member.prev, typeof(*(pos)), member)
>  
>  /**
> + * list_prev_entry_safe - get the prev element in list [once]
> + * @pos:	the type * to cursor
> + * @member:	the name of the list_head within the struct.
> + *
> + * Like list_prev_entry() but prevents the compiler from reloading the
> + * previous element.
> + */
> +#define list_prev_entry_safe(pos, member) \
> +	list_entry(READ_ONCE((pos)->member.prev), typeof(*(pos)), member)
> +
> +/**
>   * list_for_each	-	iterate over a list
>   * @pos:	the &struct list_head to use as a loop cursor.
>   * @head:	the head for your list.
> @@ -686,9 +708,9 @@ static inline void list_splice_tail_init
>   */
>  #define list_for_each_entry_safe(pos, n, head, member)			\
>  	for (pos = list_first_entry(head, typeof(*pos), member),	\
> -		n = list_next_entry(pos, member);			\
> +		n = list_next_entry_safe(pos, member);			\
>  	     &pos->member != (head); 					\
> -	     pos = n, n = list_next_entry(n, member))
> +	     pos = n, n = list_next_entry_safe(n, member))
>  
>  /**
>   * list_for_each_entry_safe_continue - continue list iteration safe against removal
> @@ -700,11 +722,11 @@ static inline void list_splice_tail_init
>   * Iterate over list of given type, continuing after current point,
>   * safe against removal of list entry.
>   */
> -#define list_for_each_entry_safe_continue(pos, n, head, member) 		\
> -	for (pos = list_next_entry(pos, member), 				\
> -		n = list_next_entry(pos, member);				\
> -	     &pos->member != (head);						\
> -	     pos = n, n = list_next_entry(n, member))
> +#define list_for_each_entry_safe_continue(pos, n, head, member) 	\
> +	for (pos = list_next_entry(pos, member), 			\
> +		n = list_next_entry_safe(pos, member);			\
> +	     &pos->member != (head);					\
> +	     pos = n, n = list_next_entry_safe(n, member))
>  
>  /**
>   * list_for_each_entry_safe_from - iterate over list from current point safe against removal
> @@ -716,10 +738,10 @@ static inline void list_splice_tail_init
>   * Iterate over list of given type from current point, safe against
>   * removal of list entry.
>   */
> -#define list_for_each_entry_safe_from(pos, n, head, member) 			\
> -	for (n = list_next_entry(pos, member);					\
> -	     &pos->member != (head);						\
> -	     pos = n, n = list_next_entry(n, member))
> +#define list_for_each_entry_safe_from(pos, n, head, member) 		\
> +	for (n = list_next_entry_safe(pos, member);			\
> +	     &pos->member != (head);					\
> +	     pos = n, n = list_next_entry_safe(n, member))
>  
>  /**
>   * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
> @@ -733,9 +755,9 @@ static inline void list_splice_tail_init
>   */
>  #define list_for_each_entry_safe_reverse(pos, n, head, member)		\
>  	for (pos = list_last_entry(head, typeof(*pos), member),		\
> -		n = list_prev_entry(pos, member);			\
> +		n = list_prev_entry_safe(pos, member);			\
>  	     &pos->member != (head); 					\
> -	     pos = n, n = list_prev_entry(n, member))
> +	     pos = n, n = list_prev_entry_safe(n, member))
>  
>  /**
>   * list_safe_reset_next - reset a stale list_for_each_entry_safe loop
> @@ -750,7 +772,7 @@ static inline void list_splice_tail_init
>   * completing the current iteration of the loop body.
>   */
>  #define list_safe_reset_next(pos, n, member)				\
> -	n = list_next_entry(pos, member)
> +	n = list_next_entry_safe(pos, member)
>  
>  /*
>   * Double linked lists with a single pointer list head.
> _
> 
> Patches currently in -mm which might be from chris@chris-wilson.co.uk are
> 
> list-prevent-compiler-reloads-inside-safe-list-iteration.patch
> 

  reply	other threads:[~2020-03-15  2:24 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20200305222751.6d781a3f2802d79510941e4e@linux-foundation.org>
2020-03-06  6:28 ` [patch 1/7] mm, numa: fix bad pmd by atomically check for pmd_trans_huge when marking page tables prot_numa Andrew Morton
2020-03-06  6:28 ` [patch 2/7] mm: fix possible PMD dirty bit lost in set_pmd_migration_entry() Andrew Morton
2020-03-06  6:28 ` [patch 3/7] mm: avoid data corruption on CoW fault into PFN-mapped VMA Andrew Morton
2020-03-06  6:28 ` [patch 4/7] fat: fix uninit-memory access for partial initialized inode Andrew Morton
2020-03-06  6:28 ` [patch 6/7] mm, hotplug: fix page online with DEBUG_PAGEALLOC compiled but not enabled Andrew Morton
2020-03-07 20:58 ` + mm-hotplug-fix-hot-remove-failure-in-sparsememvmemmap-case.patch added to -mm tree Andrew Morton
2020-03-10 23:59 ` + kmod-make-request_module-return-an-error-when-autoloading-is-disabled.patch " Andrew Morton
2020-03-12  1:08 ` + page-flags-fix-a-crash-at-setpageerrorthp_swap.patch " Andrew Morton
2020-03-12  2:58 ` + list-prevent-compiler-reloads-inside-safe-list-iteration.patch " Andrew Morton
2020-03-14 14:13   ` Paul E. McKenney [this message]
2020-03-12 22:29 ` + fs-filesystemsc-downgrade-user-reachable-warn_once-to-pr_warn_once.patch " Andrew Morton
2020-03-12 22:35 ` + mm-memcg-fix-corruption-on-64-bit-divisor-in-memoryhigh-throttling.patch " Andrew Morton
2020-03-12 22:35 ` + mm-memcg-throttle-allocators-based-on-ancestral-memoryhigh.patch " Andrew Morton
2020-03-13  0:26 ` + mm-do-not-allow-madv_pageout-for-cow-pages.patch " Andrew Morton
2020-03-13  3:25 ` + selftests-vm-fix-map_hugetlb-length-used-for-testing-read-and-write.patch " Andrew Morton
2020-03-20 23:48 ` + mm-slub-prevent-kmalloc_node-crashes-and-memory-leaks.patch " Andrew Morton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200314141338.GM3199@paulmck-ThinkPad-P72 \
    --to=paulmck@kernel.org \
    --cc=David.Laight@ACULAB.COM \
    --cc=akpm@linux-foundation.org \
    --cc=chris@chris-wilson.co.uk \
    --cc=elver@google.com \
    --cc=mark.rutland@arm.com \
    --cc=mm-commits@vger.kernel.org \
    --cc=rdunlap@infradead.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox