[2/4] mm/gup: explicitly define and check internal GUP flags, disallow FOLL_TOUCH

Message ID 5b20f3cda7cd841555c2626f98d23aa25a039828.1696174961.git.lstoakes@gmail.com
State New
Headers
Series various improvements to the GUP interface |

Commit Message

Lorenzo Stoakes Oct. 1, 2023, 4 p.m. UTC
  Rather than open-coding a list of internal GUP flags in
is_valid_gup_args(), define which ones are internal.

In addition, we were not explicitly checking to see if the user passed in
FOLL_TOUCH somehow, this patch fixes that.

Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>
---
 mm/gup.c      | 5 ++---
 mm/internal.h | 3 +++
 2 files changed, 5 insertions(+), 3 deletions(-)
  

Comments

David Hildenbrand Oct. 2, 2023, 11 a.m. UTC | #1
On 01.10.23 18:00, Lorenzo Stoakes wrote:
> Rather than open-coding a list of internal GUP flags in
> is_valid_gup_args(), define which ones are internal.
> 
> In addition, we were not explicitly checking to see if the user passed in
> FOLL_TOUCH somehow, this patch fixes that.
> 
> Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>
> ---
>   mm/gup.c      | 5 ++---
>   mm/internal.h | 3 +++
>   2 files changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/mm/gup.c b/mm/gup.c
> index 2f8a2d89fde1..b21b33d1787e 100644
> --- a/mm/gup.c
> +++ b/mm/gup.c
> @@ -2227,12 +2227,11 @@ static bool is_valid_gup_args(struct page **pages, int *locked,
>   	/*
>   	 * These flags not allowed to be specified externally to the gup
>   	 * interfaces:
> -	 * - FOLL_PIN/FOLL_TRIED/FOLL_FAST_ONLY are internal only
> +	 * - FOLL_TOUCH/FOLL_PIN/FOLL_TRIED/FOLL_FAST_ONLY are internal only
>   	 * - FOLL_REMOTE is internal only and used on follow_page()
>   	 * - FOLL_UNLOCKABLE is internal only and used if locked is !NULL
>   	 */
> -	if (WARN_ON_ONCE(gup_flags & (FOLL_PIN | FOLL_TRIED | FOLL_UNLOCKABLE |
> -				      FOLL_REMOTE | FOLL_FAST_ONLY)))
> +	if (WARN_ON_ONCE(gup_flags & INTERNAL_GUP_FLAGS))
>   		return false;
>   
>   	gup_flags |= to_set;
> diff --git a/mm/internal.h b/mm/internal.h
> index 449891ad7fdb..499016c6b01d 100644
> --- a/mm/internal.h
> +++ b/mm/internal.h
> @@ -1018,6 +1018,9 @@ enum {
>   	FOLL_UNLOCKABLE = 1 << 21,
>   };
>   
> +#define INTERNAL_GUP_FLAGS (FOLL_TOUCH | FOLL_TRIED | FOLL_REMOTE | FOLL_PIN | \
> +			    FOLL_FAST_ONLY | FOLL_UNLOCKABLE)
> +
>   /*
>    * Indicates for which pages that are write-protected in the page table,
>    * whether GUP has to trigger unsharing via FAULT_FLAG_UNSHARE such that the

Reviewed-by: David Hildenbrand <david@redhat.com>
  
Jason Gunthorpe Oct. 9, 2023, 10:19 p.m. UTC | #2
On Sun, Oct 01, 2023 at 05:00:03PM +0100, Lorenzo Stoakes wrote:
> Rather than open-coding a list of internal GUP flags in
> is_valid_gup_args(), define which ones are internal.
> 
> In addition, we were not explicitly checking to see if the user passed in
> FOLL_TOUCH somehow, this patch fixes that.
> 
> Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>
> ---
>  mm/gup.c      | 5 ++---
>  mm/internal.h | 3 +++
>  2 files changed, 5 insertions(+), 3 deletions(-)

Does gup_test still work? It uses FOLL_TOUCH?

Hmm. I guess it was broken for a while anyhow:

/* Just the flags we need, copied from mm.h: */
#define FOLL_WRITE	0x01	/* check pte is writable */
#define FOLL_TOUCH	0x02	/* mark page accessed */

Aside from that this seems OK

Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>

Jason
  

Patch

diff --git a/mm/gup.c b/mm/gup.c
index 2f8a2d89fde1..b21b33d1787e 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -2227,12 +2227,11 @@  static bool is_valid_gup_args(struct page **pages, int *locked,
 	/*
 	 * These flags not allowed to be specified externally to the gup
 	 * interfaces:
-	 * - FOLL_PIN/FOLL_TRIED/FOLL_FAST_ONLY are internal only
+	 * - FOLL_TOUCH/FOLL_PIN/FOLL_TRIED/FOLL_FAST_ONLY are internal only
 	 * - FOLL_REMOTE is internal only and used on follow_page()
 	 * - FOLL_UNLOCKABLE is internal only and used if locked is !NULL
 	 */
-	if (WARN_ON_ONCE(gup_flags & (FOLL_PIN | FOLL_TRIED | FOLL_UNLOCKABLE |
-				      FOLL_REMOTE | FOLL_FAST_ONLY)))
+	if (WARN_ON_ONCE(gup_flags & INTERNAL_GUP_FLAGS))
 		return false;
 
 	gup_flags |= to_set;
diff --git a/mm/internal.h b/mm/internal.h
index 449891ad7fdb..499016c6b01d 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -1018,6 +1018,9 @@  enum {
 	FOLL_UNLOCKABLE = 1 << 21,
 };
 
+#define INTERNAL_GUP_FLAGS (FOLL_TOUCH | FOLL_TRIED | FOLL_REMOTE | FOLL_PIN | \
+			    FOLL_FAST_ONLY | FOLL_UNLOCKABLE)
+
 /*
  * Indicates for which pages that are write-protected in the page table,
  * whether GUP has to trigger unsharing via FAULT_FLAG_UNSHARE such that the