diff options
Diffstat (limited to 'include/linux/mm_types.h')
| -rw-r--r-- | include/linux/mm_types.h | 182 | 
1 files changed, 65 insertions, 117 deletions
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 1ae3537c7920..9db36dc5d4cf 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -5,6 +5,7 @@  #include <linux/mm_types_task.h>  #include <linux/auxvec.h> +#include <linux/kref.h>  #include <linux/list.h>  #include <linux/spinlock.h>  #include <linux/rbtree.h> @@ -118,31 +119,6 @@ struct page {  				atomic_long_t pp_frag_count;  			};  		}; -		struct {	/* slab, slob and slub */ -			union { -				struct list_head slab_list; -				struct {	/* Partial pages */ -					struct page *next; -#ifdef CONFIG_64BIT -					int pages;	/* Nr of pages left */ -#else -					short int pages; -#endif -				}; -			}; -			struct kmem_cache *slab_cache; /* not slob */ -			/* Double-word boundary */ -			void *freelist;		/* first free object */ -			union { -				void *s_mem;	/* slab: first object */ -				unsigned long counters;		/* SLUB */ -				struct {			/* SLUB */ -					unsigned inuse:16; -					unsigned objects:15; -					unsigned frozen:1; -				}; -			}; -		};  		struct {	/* Tail pages of compound page */  			unsigned long compound_head;	/* Bit zero is set */ @@ -206,9 +182,6 @@ struct page {  		 * which are currently stored here.  		 */  		unsigned int page_type; - -		unsigned int active;		/* SLAB */ -		int units;			/* SLOB */  	};  	/* Usage count. *DO NOT USE DIRECTLY*. See page_ref.h */ @@ -386,6 +359,12 @@ struct vm_userfaultfd_ctx {  struct vm_userfaultfd_ctx {};  #endif /* CONFIG_USERFAULTFD */ +struct anon_vma_name { +	struct kref kref; +	/* The name needs to be at the end because it is dynamically sized. */ +	char name[]; +}; +  /*   * This struct describes a virtual memory area. There is one of these   * per VM-area/task. A VM area is any part of the process virtual memory @@ -426,11 +405,19 @@ struct vm_area_struct {  	/*  	 * For areas with an address space and backing store,  	 * linkage into the address_space->i_mmap interval tree. +	 * +	 * For private anonymous mappings, a pointer to a null terminated string +	 * containing the name given to the vma, or NULL if unnamed.  	 */ -	struct { -		struct rb_node rb; -		unsigned long rb_subtree_last; -	} shared; + +	union { +		struct { +			struct rb_node rb; +			unsigned long rb_subtree_last; +		} shared; +		/* Serialized by mmap_sem. */ +		struct anon_vma_name *anon_name; +	};  	/*  	 * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma @@ -632,7 +619,7 @@ struct mm_struct {  		atomic_t tlb_flush_pending;  #ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH  		/* See flush_tlb_batched_pending() */ -		bool tlb_flush_batched; +		atomic_t tlb_flush_batched;  #endif  		struct uprobes_state uprobes_state;  #ifdef CONFIG_PREEMPT_RT @@ -677,90 +664,6 @@ extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm);  extern void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm);  extern void tlb_finish_mmu(struct mmu_gather *tlb); -static inline void init_tlb_flush_pending(struct mm_struct *mm) -{ -	atomic_set(&mm->tlb_flush_pending, 0); -} - -static inline void inc_tlb_flush_pending(struct mm_struct *mm) -{ -	atomic_inc(&mm->tlb_flush_pending); -	/* -	 * The only time this value is relevant is when there are indeed pages -	 * to flush. And we'll only flush pages after changing them, which -	 * requires the PTL. -	 * -	 * So the ordering here is: -	 * -	 *	atomic_inc(&mm->tlb_flush_pending); -	 *	spin_lock(&ptl); -	 *	... -	 *	set_pte_at(); -	 *	spin_unlock(&ptl); -	 * -	 *				spin_lock(&ptl) -	 *				mm_tlb_flush_pending(); -	 *				.... -	 *				spin_unlock(&ptl); -	 * -	 *	flush_tlb_range(); -	 *	atomic_dec(&mm->tlb_flush_pending); -	 * -	 * Where the increment if constrained by the PTL unlock, it thus -	 * ensures that the increment is visible if the PTE modification is -	 * visible. After all, if there is no PTE modification, nobody cares -	 * about TLB flushes either. -	 * -	 * This very much relies on users (mm_tlb_flush_pending() and -	 * mm_tlb_flush_nested()) only caring about _specific_ PTEs (and -	 * therefore specific PTLs), because with SPLIT_PTE_PTLOCKS and RCpc -	 * locks (PPC) the unlock of one doesn't order against the lock of -	 * another PTL. -	 * -	 * The decrement is ordered by the flush_tlb_range(), such that -	 * mm_tlb_flush_pending() will not return false unless all flushes have -	 * completed. -	 */ -} - -static inline void dec_tlb_flush_pending(struct mm_struct *mm) -{ -	/* -	 * See inc_tlb_flush_pending(). -	 * -	 * This cannot be smp_mb__before_atomic() because smp_mb() simply does -	 * not order against TLB invalidate completion, which is what we need. -	 * -	 * Therefore we must rely on tlb_flush_*() to guarantee order. -	 */ -	atomic_dec(&mm->tlb_flush_pending); -} - -static inline bool mm_tlb_flush_pending(struct mm_struct *mm) -{ -	/* -	 * Must be called after having acquired the PTL; orders against that -	 * PTLs release and therefore ensures that if we observe the modified -	 * PTE we must also observe the increment from inc_tlb_flush_pending(). -	 * -	 * That is, it only guarantees to return true if there is a flush -	 * pending for _this_ PTL. -	 */ -	return atomic_read(&mm->tlb_flush_pending); -} - -static inline bool mm_tlb_flush_nested(struct mm_struct *mm) -{ -	/* -	 * Similar to mm_tlb_flush_pending(), we must have acquired the PTL -	 * for which there is a TLB flush pending in order to guarantee -	 * we've seen both that PTE modification and the increment. -	 * -	 * (no requirement on actually still holding the PTL, that is irrelevant) -	 */ -	return atomic_read(&mm->tlb_flush_pending) > 1; -} -  struct vm_fault;  /** @@ -875,4 +778,49 @@ typedef struct {  	unsigned long val;  } swp_entry_t; +/** + * enum fault_flag - Fault flag definitions. + * @FAULT_FLAG_WRITE: Fault was a write fault. + * @FAULT_FLAG_MKWRITE: Fault was mkwrite of existing PTE. + * @FAULT_FLAG_ALLOW_RETRY: Allow to retry the fault if blocked. + * @FAULT_FLAG_RETRY_NOWAIT: Don't drop mmap_lock and wait when retrying. + * @FAULT_FLAG_KILLABLE: The fault task is in SIGKILL killable region. + * @FAULT_FLAG_TRIED: The fault has been tried once. + * @FAULT_FLAG_USER: The fault originated in userspace. + * @FAULT_FLAG_REMOTE: The fault is not for current task/mm. + * @FAULT_FLAG_INSTRUCTION: The fault was during an instruction fetch. + * @FAULT_FLAG_INTERRUPTIBLE: The fault can be interrupted by non-fatal signals. + * + * About @FAULT_FLAG_ALLOW_RETRY and @FAULT_FLAG_TRIED: we can specify + * whether we would allow page faults to retry by specifying these two + * fault flags correctly.  Currently there can be three legal combinations: + * + * (a) ALLOW_RETRY and !TRIED:  this means the page fault allows retry, and + *                              this is the first try + * + * (b) ALLOW_RETRY and TRIED:   this means the page fault allows retry, and + *                              we've already tried at least once + * + * (c) !ALLOW_RETRY and !TRIED: this means the page fault does not allow retry + * + * The unlisted combination (!ALLOW_RETRY && TRIED) is illegal and should never + * be used.  Note that page faults can be allowed to retry for multiple times, + * in which case we'll have an initial fault with flags (a) then later on + * continuous faults with flags (b).  We should always try to detect pending + * signals before a retry to make sure the continuous page faults can still be + * interrupted if necessary. + */ +enum fault_flag { +	FAULT_FLAG_WRITE =		1 << 0, +	FAULT_FLAG_MKWRITE =		1 << 1, +	FAULT_FLAG_ALLOW_RETRY =	1 << 2, +	FAULT_FLAG_RETRY_NOWAIT = 	1 << 3, +	FAULT_FLAG_KILLABLE =		1 << 4, +	FAULT_FLAG_TRIED = 		1 << 5, +	FAULT_FLAG_USER =		1 << 6, +	FAULT_FLAG_REMOTE =		1 << 7, +	FAULT_FLAG_INSTRUCTION =	1 << 8, +	FAULT_FLAG_INTERRUPTIBLE =	1 << 9, +}; +  #endif /* _LINUX_MM_TYPES_H */  | 
