mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-25 12:00:22 +09:00
UPSTREAM: mm: refactor vm_area_struct::anon_vma_name usage code
Avoid mixing strings and their anon_vma_name referenced pointers by
using struct anon_vma_name whenever possible. This simplifies the code
and allows easier sharing of anon_vma_name structures when they
represent the same name.
[surenb@google.com: fix comment]
Link: https://lkml.kernel.org/r/20220223153613.835563-1-surenb@google.com
Link: https://lkml.kernel.org/r/20220224231834.1481408-1-surenb@google.com
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Suggested-by: Matthew Wilcox <willy@infradead.org>
Suggested-by: Michal Hocko <mhocko@suse.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Cc: Colin Cross <ccross@google.com>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Alexey Gladkov <legion@kernel.org>
Cc: Sasha Levin <sashal@kernel.org>
Cc: Chris Hyser <chris.hyser@oracle.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Peter Collingbourne <pcc@google.com>
Cc: Xiaofeng Cao <caoxiaofeng@yulong.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
(cherry picked from commit 5c26f6ac94)
Bug: 218352794
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Change-Id: I4a6b5602ce7151d1a4b88fac489f86d68089bd4d
This commit is contained in:
@@ -309,7 +309,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
|
||||
|
||||
name = arch_vma_name(vma);
|
||||
if (!name) {
|
||||
const char *anon_name;
|
||||
struct anon_vma_name *anon_name;
|
||||
|
||||
if (!mm) {
|
||||
name = "[vdso]";
|
||||
@@ -327,10 +327,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
|
||||
goto done;
|
||||
}
|
||||
|
||||
anon_name = vma_anon_name(vma);
|
||||
anon_name = anon_vma_name(vma);
|
||||
if (anon_name) {
|
||||
seq_pad(m, ' ');
|
||||
seq_printf(m, "[anon:%s]", anon_name);
|
||||
seq_printf(m, "[anon:%s]", anon_name->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -880,7 +880,7 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
|
||||
new_flags, vma->anon_vma,
|
||||
vma->vm_file, vma->vm_pgoff,
|
||||
vma_policy(vma),
|
||||
NULL_VM_UFFD_CTX, vma_anon_name(vma));
|
||||
NULL_VM_UFFD_CTX, anon_vma_name(vma));
|
||||
if (prev)
|
||||
vma = prev;
|
||||
else
|
||||
@@ -1438,7 +1438,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
|
||||
vma->anon_vma, vma->vm_file, vma->vm_pgoff,
|
||||
vma_policy(vma),
|
||||
((struct vm_userfaultfd_ctx){ ctx }),
|
||||
vma_anon_name(vma));
|
||||
anon_vma_name(vma));
|
||||
if (prev) {
|
||||
vma = prev;
|
||||
goto next;
|
||||
@@ -1617,7 +1617,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
|
||||
prev = vma_merge(mm, prev, start, vma_end, new_flags,
|
||||
vma->anon_vma, vma->vm_file, vma->vm_pgoff,
|
||||
vma_policy(vma),
|
||||
NULL_VM_UFFD_CTX, vma_anon_name(vma));
|
||||
NULL_VM_UFFD_CTX, anon_vma_name(vma));
|
||||
if (prev) {
|
||||
vma = prev;
|
||||
goto next;
|
||||
|
||||
@@ -2672,13 +2672,13 @@ extern struct vm_area_struct *__vma_merge(struct mm_struct *mm,
|
||||
struct vm_area_struct *prev, unsigned long addr, unsigned long end,
|
||||
unsigned long vm_flags, struct anon_vma *anon, struct file *file,
|
||||
pgoff_t pgoff, struct mempolicy *mpol, struct vm_userfaultfd_ctx uff,
|
||||
const char *, bool keep_locked);
|
||||
struct anon_vma_name *, bool keep_locked);
|
||||
|
||||
static inline struct vm_area_struct *vma_merge(struct mm_struct *mm,
|
||||
struct vm_area_struct *prev, unsigned long addr, unsigned long end,
|
||||
unsigned long vm_flags, struct anon_vma *anon, struct file *file,
|
||||
pgoff_t off, struct mempolicy *pol, struct vm_userfaultfd_ctx uff,
|
||||
const char *anon_name)
|
||||
struct anon_vma_name *anon_name)
|
||||
{
|
||||
return __vma_merge(mm, prev, addr, end, vm_flags, anon, file, off,
|
||||
pol, uff, anon_name, false);
|
||||
@@ -3397,11 +3397,12 @@ static inline int seal_check_future_write(int seals, struct vm_area_struct *vma)
|
||||
|
||||
#ifdef CONFIG_ANON_VMA_NAME
|
||||
int madvise_set_anon_name(struct mm_struct *mm, unsigned long start,
|
||||
unsigned long len_in, const char *name);
|
||||
unsigned long len_in,
|
||||
struct anon_vma_name *anon_name);
|
||||
#else
|
||||
static inline int
|
||||
madvise_set_anon_name(struct mm_struct *mm, unsigned long start,
|
||||
unsigned long len_in, const char *name) {
|
||||
unsigned long len_in, struct anon_vma_name *anon_name) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -129,50 +129,80 @@ static __always_inline enum lru_list page_lru(struct page *page)
|
||||
|
||||
#ifdef CONFIG_ANON_VMA_NAME
|
||||
/*
|
||||
* mmap_lock should be read-locked when calling vma_anon_name() and while using
|
||||
* the returned pointer.
|
||||
* mmap_lock should be read-locked when calling anon_vma_name(). Caller should
|
||||
* either keep holding the lock while using the returned pointer or it should
|
||||
* raise anon_vma_name refcount before releasing the lock.
|
||||
*/
|
||||
extern const char *vma_anon_name(struct vm_area_struct *vma);
|
||||
|
||||
/*
|
||||
* mmap_lock should be read-locked for orig_vma->vm_mm.
|
||||
* mmap_lock should be write-locked for new_vma->vm_mm or new_vma should be
|
||||
* isolated.
|
||||
*/
|
||||
extern void dup_vma_anon_name(struct vm_area_struct *orig_vma,
|
||||
struct vm_area_struct *new_vma);
|
||||
|
||||
/*
|
||||
* mmap_lock should be write-locked or vma should have been isolated under
|
||||
* write-locked mmap_lock protection.
|
||||
*/
|
||||
extern void free_vma_anon_name(struct vm_area_struct *vma);
|
||||
extern struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma);
|
||||
extern struct anon_vma_name *anon_vma_name_alloc(const char *name);
|
||||
extern void anon_vma_name_free(struct kref *kref);
|
||||
|
||||
/* mmap_lock should be read-locked */
|
||||
static inline bool is_same_vma_anon_name(struct vm_area_struct *vma,
|
||||
const char *name)
|
||||
static inline void anon_vma_name_get(struct anon_vma_name *anon_name)
|
||||
{
|
||||
const char *vma_name = vma_anon_name(vma);
|
||||
if (anon_name)
|
||||
kref_get(&anon_name->kref);
|
||||
}
|
||||
|
||||
/* either both NULL, or pointers to same string */
|
||||
if (vma_name == name)
|
||||
static inline void anon_vma_name_put(struct anon_vma_name *anon_name)
|
||||
{
|
||||
if (anon_name)
|
||||
kref_put(&anon_name->kref, anon_vma_name_free);
|
||||
}
|
||||
|
||||
static inline void dup_anon_vma_name(struct vm_area_struct *orig_vma,
|
||||
struct vm_area_struct *new_vma)
|
||||
{
|
||||
struct anon_vma_name *anon_name = anon_vma_name(orig_vma);
|
||||
|
||||
if (anon_name) {
|
||||
anon_vma_name_get(anon_name);
|
||||
new_vma->anon_name = anon_name;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void free_anon_vma_name(struct vm_area_struct *vma)
|
||||
{
|
||||
/*
|
||||
* Not using anon_vma_name because it generates a warning if mmap_lock
|
||||
* is not held, which might be the case here.
|
||||
*/
|
||||
if (!vma->vm_file)
|
||||
anon_vma_name_put(vma->anon_name);
|
||||
}
|
||||
|
||||
static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1,
|
||||
struct anon_vma_name *anon_name2)
|
||||
{
|
||||
if (anon_name1 == anon_name2)
|
||||
return true;
|
||||
|
||||
return name && vma_name && !strcmp(name, vma_name);
|
||||
return anon_name1 && anon_name2 &&
|
||||
!strcmp(anon_name1->name, anon_name2->name);
|
||||
}
|
||||
#else /* CONFIG_ANON_VMA_NAME */
|
||||
static inline const char *vma_anon_name(struct vm_area_struct *vma)
|
||||
static inline struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline void dup_vma_anon_name(struct vm_area_struct *orig_vma,
|
||||
struct vm_area_struct *new_vma) {}
|
||||
static inline void free_vma_anon_name(struct vm_area_struct *vma) {}
|
||||
static inline bool is_same_vma_anon_name(struct vm_area_struct *vma,
|
||||
const char *name)
|
||||
|
||||
static inline struct anon_vma_name *anon_vma_name_alloc(const char *name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void anon_vma_name_get(struct anon_vma_name *anon_name) {}
|
||||
static inline void anon_vma_name_put(struct anon_vma_name *anon_name) {}
|
||||
static inline void dup_anon_vma_name(struct vm_area_struct *orig_vma,
|
||||
struct vm_area_struct *new_vma) {}
|
||||
static inline void free_anon_vma_name(struct vm_area_struct *vma) {}
|
||||
|
||||
static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1,
|
||||
struct anon_vma_name *anon_name2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ANON_VMA_NAME */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -356,7 +356,10 @@ struct vm_area_struct {
|
||||
struct rb_node rb;
|
||||
unsigned long rb_subtree_last;
|
||||
} shared;
|
||||
/* Serialized by mmap_sem. */
|
||||
/*
|
||||
* Serialized by mmap_sem. Never use directly because it is
|
||||
* valid only when vm_file is NULL. Use anon_vma_name instead.
|
||||
*/
|
||||
struct anon_vma_name *anon_name;
|
||||
};
|
||||
|
||||
|
||||
@@ -375,14 +375,14 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig)
|
||||
*new = data_race(*orig);
|
||||
INIT_VMA(new);
|
||||
new->vm_next = new->vm_prev = NULL;
|
||||
dup_vma_anon_name(orig, new);
|
||||
dup_anon_vma_name(orig, new);
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
void vm_area_free(struct vm_area_struct *vma)
|
||||
{
|
||||
free_vma_anon_name(vma);
|
||||
free_anon_vma_name(vma);
|
||||
kmem_cache_free(vm_area_cachep, vma);
|
||||
}
|
||||
|
||||
|
||||
19
kernel/sys.c
19
kernel/sys.c
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/mm_inline.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/reboot.h>
|
||||
@@ -2298,15 +2299,16 @@ static int prctl_set_vma(unsigned long opt, unsigned long addr,
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
const char __user *uname;
|
||||
char *name, *pch;
|
||||
struct anon_vma_name *anon_name = NULL;
|
||||
int error;
|
||||
|
||||
switch (opt) {
|
||||
case PR_SET_VMA_ANON_NAME:
|
||||
uname = (const char __user *)arg;
|
||||
if (uname) {
|
||||
name = strndup_user(uname, ANON_VMA_NAME_MAX_LEN);
|
||||
char *name, *pch;
|
||||
|
||||
name = strndup_user(uname, ANON_VMA_NAME_MAX_LEN);
|
||||
if (IS_ERR(name))
|
||||
return PTR_ERR(name);
|
||||
|
||||
@@ -2316,15 +2318,18 @@ static int prctl_set_vma(unsigned long opt, unsigned long addr,
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Reset the name */
|
||||
name = NULL;
|
||||
/* anon_vma has its own copy */
|
||||
anon_name = anon_vma_name_alloc(name);
|
||||
kfree(name);
|
||||
if (!anon_name)
|
||||
return -ENOMEM;
|
||||
|
||||
}
|
||||
|
||||
mmap_write_lock(mm);
|
||||
error = madvise_set_anon_name(mm, addr, size, name);
|
||||
error = madvise_set_anon_name(mm, addr, size, anon_name);
|
||||
mmap_write_unlock(mm);
|
||||
kfree(name);
|
||||
anon_vma_name_put(anon_name);
|
||||
break;
|
||||
default:
|
||||
error = -EINVAL;
|
||||
|
||||
87
mm/madvise.c
87
mm/madvise.c
@@ -63,7 +63,7 @@ static int madvise_need_mmap_write(int behavior)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ANON_VMA_NAME
|
||||
static struct anon_vma_name *anon_vma_name_alloc(const char *name)
|
||||
struct anon_vma_name *anon_vma_name_alloc(const char *name)
|
||||
{
|
||||
struct anon_vma_name *anon_name;
|
||||
size_t count;
|
||||
@@ -79,78 +79,49 @@ static struct anon_vma_name *anon_vma_name_alloc(const char *name)
|
||||
return anon_name;
|
||||
}
|
||||
|
||||
static void vma_anon_name_free(struct kref *kref)
|
||||
void anon_vma_name_free(struct kref *kref)
|
||||
{
|
||||
struct anon_vma_name *anon_name =
|
||||
container_of(kref, struct anon_vma_name, kref);
|
||||
kfree(anon_name);
|
||||
}
|
||||
|
||||
static inline bool has_vma_anon_name(struct vm_area_struct *vma)
|
||||
struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma)
|
||||
{
|
||||
return !vma->vm_file && vma->anon_name;
|
||||
}
|
||||
|
||||
const char *vma_anon_name(struct vm_area_struct *vma)
|
||||
{
|
||||
if (!has_vma_anon_name(vma))
|
||||
return NULL;
|
||||
|
||||
mmap_assert_locked(vma->vm_mm);
|
||||
|
||||
return vma->anon_name->name;
|
||||
}
|
||||
if (vma->vm_file)
|
||||
return NULL;
|
||||
|
||||
void dup_vma_anon_name(struct vm_area_struct *orig_vma,
|
||||
struct vm_area_struct *new_vma)
|
||||
{
|
||||
if (!has_vma_anon_name(orig_vma))
|
||||
return;
|
||||
|
||||
kref_get(&orig_vma->anon_name->kref);
|
||||
new_vma->anon_name = orig_vma->anon_name;
|
||||
}
|
||||
|
||||
void free_vma_anon_name(struct vm_area_struct *vma)
|
||||
{
|
||||
struct anon_vma_name *anon_name;
|
||||
|
||||
if (!has_vma_anon_name(vma))
|
||||
return;
|
||||
|
||||
anon_name = vma->anon_name;
|
||||
vma->anon_name = NULL;
|
||||
kref_put(&anon_name->kref, vma_anon_name_free);
|
||||
return vma->anon_name;
|
||||
}
|
||||
|
||||
/* mmap_lock should be write-locked */
|
||||
static int replace_vma_anon_name(struct vm_area_struct *vma, const char *name)
|
||||
static int replace_anon_vma_name(struct vm_area_struct *vma,
|
||||
struct anon_vma_name *anon_name)
|
||||
{
|
||||
const char *anon_name;
|
||||
struct anon_vma_name *orig_name = anon_vma_name(vma);
|
||||
|
||||
if (!name) {
|
||||
free_vma_anon_name(vma);
|
||||
if (!anon_name) {
|
||||
vma->anon_name = NULL;
|
||||
anon_vma_name_put(orig_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
anon_name = vma_anon_name(vma);
|
||||
if (anon_name) {
|
||||
/* Same name, nothing to do here */
|
||||
if (!strcmp(name, anon_name))
|
||||
return 0;
|
||||
if (anon_vma_name_eq(orig_name, anon_name))
|
||||
return 0;
|
||||
|
||||
free_vma_anon_name(vma);
|
||||
}
|
||||
vma->anon_name = anon_vma_name_alloc(name);
|
||||
if (!vma->anon_name)
|
||||
return -ENOMEM;
|
||||
anon_vma_name_get(anon_name);
|
||||
vma->anon_name = anon_name;
|
||||
anon_vma_name_put(orig_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else /* CONFIG_ANON_VMA_NAME */
|
||||
static int replace_vma_anon_name(struct vm_area_struct *vma, const char *name)
|
||||
static int replace_anon_vma_name(struct vm_area_struct *vma,
|
||||
struct anon_vma_name *anon_name)
|
||||
{
|
||||
if (name)
|
||||
if (anon_name)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@@ -163,13 +134,13 @@ static int replace_vma_anon_name(struct vm_area_struct *vma, const char *name)
|
||||
static int madvise_update_vma(struct vm_area_struct *vma,
|
||||
struct vm_area_struct **prev, unsigned long start,
|
||||
unsigned long end, unsigned long new_flags,
|
||||
const char *name)
|
||||
struct anon_vma_name *anon_name)
|
||||
{
|
||||
struct mm_struct *mm = vma->vm_mm;
|
||||
int error;
|
||||
pgoff_t pgoff;
|
||||
|
||||
if (new_flags == vma->vm_flags && is_same_vma_anon_name(vma, name)) {
|
||||
if (new_flags == vma->vm_flags && anon_vma_name_eq(anon_vma_name(vma), anon_name)) {
|
||||
*prev = vma;
|
||||
return 0;
|
||||
}
|
||||
@@ -177,7 +148,7 @@ static int madvise_update_vma(struct vm_area_struct *vma,
|
||||
pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
|
||||
*prev = vma_merge(mm, *prev, start, end, new_flags, vma->anon_vma,
|
||||
vma->vm_file, pgoff, vma_policy(vma),
|
||||
vma->vm_userfaultfd_ctx, name);
|
||||
vma->vm_userfaultfd_ctx, anon_name);
|
||||
if (*prev) {
|
||||
vma = *prev;
|
||||
goto success;
|
||||
@@ -209,7 +180,7 @@ success:
|
||||
WRITE_ONCE(vma->vm_flags, new_flags);
|
||||
vm_write_end(vma);
|
||||
if (!vma->vm_file) {
|
||||
error = replace_vma_anon_name(vma, name);
|
||||
error = replace_anon_vma_name(vma, anon_name);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
@@ -986,7 +957,7 @@ static int madvise_vma_behavior(struct vm_area_struct *vma,
|
||||
}
|
||||
|
||||
error = madvise_update_vma(vma, prev, start, end, new_flags,
|
||||
vma_anon_name(vma));
|
||||
anon_vma_name(vma));
|
||||
|
||||
out:
|
||||
/*
|
||||
@@ -1172,7 +1143,7 @@ int madvise_walk_vmas(struct mm_struct *mm, unsigned long start,
|
||||
static int madvise_vma_anon_name(struct vm_area_struct *vma,
|
||||
struct vm_area_struct **prev,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long name)
|
||||
unsigned long anon_name)
|
||||
{
|
||||
int error;
|
||||
|
||||
@@ -1181,7 +1152,7 @@ static int madvise_vma_anon_name(struct vm_area_struct *vma,
|
||||
return -EBADF;
|
||||
|
||||
error = madvise_update_vma(vma, prev, start, end, vma->vm_flags,
|
||||
(const char *)name);
|
||||
(struct anon_vma_name *)anon_name);
|
||||
|
||||
/*
|
||||
* madvise() returns EAGAIN if kernel resources, such as
|
||||
@@ -1193,7 +1164,7 @@ static int madvise_vma_anon_name(struct vm_area_struct *vma,
|
||||
}
|
||||
|
||||
int madvise_set_anon_name(struct mm_struct *mm, unsigned long start,
|
||||
unsigned long len_in, const char *name)
|
||||
unsigned long len_in, struct anon_vma_name *anon_name)
|
||||
{
|
||||
unsigned long end;
|
||||
unsigned long len;
|
||||
@@ -1213,7 +1184,7 @@ int madvise_set_anon_name(struct mm_struct *mm, unsigned long start,
|
||||
if (end == start)
|
||||
return 0;
|
||||
|
||||
return madvise_walk_vmas(mm, start, end, (unsigned long)name,
|
||||
return madvise_walk_vmas(mm, start, end, (unsigned long)anon_name,
|
||||
madvise_vma_anon_name);
|
||||
}
|
||||
#endif /* CONFIG_ANON_VMA_NAME */
|
||||
|
||||
@@ -842,7 +842,7 @@ static int mbind_range(struct mm_struct *mm, unsigned long start,
|
||||
prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags,
|
||||
vma->anon_vma, vma->vm_file, pgoff,
|
||||
new_pol, vma->vm_userfaultfd_ctx,
|
||||
vma_anon_name(vma));
|
||||
anon_vma_name(vma));
|
||||
if (prev) {
|
||||
vma = prev;
|
||||
next = vma->vm_next;
|
||||
|
||||
@@ -550,7 +550,7 @@ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
|
||||
pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
|
||||
*prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma,
|
||||
vma->vm_file, pgoff, vma_policy(vma),
|
||||
vma->vm_userfaultfd_ctx, vma_anon_name(vma));
|
||||
vma->vm_userfaultfd_ctx, anon_vma_name(vma));
|
||||
if (*prev) {
|
||||
vma = *prev;
|
||||
goto success;
|
||||
|
||||
12
mm/mmap.c
12
mm/mmap.c
@@ -1084,7 +1084,7 @@ again:
|
||||
static inline int is_mergeable_vma(struct vm_area_struct *vma,
|
||||
struct file *file, unsigned long vm_flags,
|
||||
struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
|
||||
const char *anon_name)
|
||||
struct anon_vma_name *anon_name)
|
||||
{
|
||||
/*
|
||||
* VM_SOFTDIRTY should not prevent from VMA merging, if we
|
||||
@@ -1102,7 +1102,7 @@ static inline int is_mergeable_vma(struct vm_area_struct *vma,
|
||||
return 0;
|
||||
if (!is_mergeable_vm_userfaultfd_ctx(vma, vm_userfaultfd_ctx))
|
||||
return 0;
|
||||
if (!is_same_vma_anon_name(vma, anon_name))
|
||||
if (!anon_vma_name_eq(anon_vma_name(vma), anon_name))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
@@ -1137,7 +1137,7 @@ can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
|
||||
struct anon_vma *anon_vma, struct file *file,
|
||||
pgoff_t vm_pgoff,
|
||||
struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
|
||||
const char *anon_name)
|
||||
struct anon_vma_name *anon_name)
|
||||
{
|
||||
if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx, anon_name) &&
|
||||
is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) {
|
||||
@@ -1159,7 +1159,7 @@ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
|
||||
struct anon_vma *anon_vma, struct file *file,
|
||||
pgoff_t vm_pgoff,
|
||||
struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
|
||||
const char *anon_name)
|
||||
struct anon_vma_name *anon_name)
|
||||
{
|
||||
if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx, anon_name) &&
|
||||
is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) {
|
||||
@@ -1220,7 +1220,7 @@ struct vm_area_struct *__vma_merge(struct mm_struct *mm,
|
||||
struct anon_vma *anon_vma, struct file *file,
|
||||
pgoff_t pgoff, struct mempolicy *policy,
|
||||
struct vm_userfaultfd_ctx vm_userfaultfd_ctx,
|
||||
const char *anon_name, bool keep_locked)
|
||||
struct anon_vma_name *anon_name, bool keep_locked)
|
||||
{
|
||||
pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
|
||||
struct vm_area_struct *area, *next;
|
||||
@@ -3410,7 +3410,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
|
||||
new_vma = __vma_merge(mm, prev, addr, addr + len, vma->vm_flags,
|
||||
vma->anon_vma, vma->vm_file, pgoff,
|
||||
vma_policy(vma), vma->vm_userfaultfd_ctx,
|
||||
vma_anon_name(vma), true);
|
||||
anon_vma_name(vma), true);
|
||||
if (new_vma) {
|
||||
/*
|
||||
* Source vma may have been merged into new_vma
|
||||
|
||||
@@ -454,7 +454,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
|
||||
pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
|
||||
*pprev = vma_merge(mm, *pprev, start, end, newflags,
|
||||
vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma),
|
||||
vma->vm_userfaultfd_ctx, vma_anon_name(vma));
|
||||
vma->vm_userfaultfd_ctx, anon_vma_name(vma));
|
||||
if (*pprev) {
|
||||
vma = *pprev;
|
||||
VM_WARN_ON((vma->vm_flags ^ newflags) & ~VM_SOFTDIRTY);
|
||||
|
||||
Reference in New Issue
Block a user