diff options
author | Kalesh Singh <kaleshsingh@google.com> | 2024-01-25 16:10:27 -0800 |
---|---|---|
committer | Kalesh Singh <kaleshsingh@google.com> | 2024-02-01 18:13:33 +0000 |
commit | 11d7e4f57f688287511f911187ada11784b4263d (patch) | |
tree | b02cbcbc876acdeb045aed46433e5a0f83254f12 | |
parent | 0b84d89c30eefd3318d039e5660f03ffb2ecb24c (diff) | |
download | gs-11d7e4f57f688287511f911187ada11784b4263d.tar.gz |
ANDROID: mm: Fix VMA ref count after fast-mremap
Since the cmpxchg() to unlock the VMA (reset ref count from -1), is
enclosed in VM_BUG_ON_VMA() it gets compiled out in non-debug builds
(CONFIG_DEBUG_VM=n). This means that any VMA that underwent a fast-remap
will have it's refcount stuck at -1, making it not be eligible for
future speculative faults, and preventing freeing of the VMA.
Bug: 323371343
Bug: 322411509
Change-Id: If5bf61c7d94268700f2c4f096d946201b68abdb8
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
-rw-r--r-- | mm/mremap.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/mm/mremap.c b/mm/mremap.c index a6484e845706..fa90d4b7aa0e 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -217,7 +217,7 @@ static inline bool trylock_vma_ref_count(struct vm_area_struct *vma) * If we have the only reference, swap the refcount to -1. This * will prevent other concurrent references by get_vma() for SPFs. */ - return atomic_cmpxchg(&vma->vm_ref_count, 1, -1) == 1; + return atomic_cmpxchg_acquire(&vma->vm_ref_count, 1, -1) == 1; } /* @@ -225,12 +225,13 @@ static inline bool trylock_vma_ref_count(struct vm_area_struct *vma) */ static inline void unlock_vma_ref_count(struct vm_area_struct *vma) { + int old = atomic_xchg_release(&vma->vm_ref_count, 1); + /* * This should only be called after a corresponding, * successful trylock_vma_ref_count(). */ - VM_BUG_ON_VMA(atomic_cmpxchg(&vma->vm_ref_count, -1, 1) != -1, - vma); + VM_BUG_ON_VMA(old != -1, vma); } #else /* !CONFIG_SPECULATIVE_PAGE_FAULT */ static inline bool trylock_vma_ref_count(struct vm_area_struct *vma) |