diff --git a/include/linux/mmap_lock.h b/include/linux/mmap_lock.h index 5da384bd0a26..1acac1ab9d30 100644 --- a/include/linux/mmap_lock.h +++ b/include/linux/mmap_lock.h @@ -12,6 +12,7 @@ extern int rcuwait_wake_up(struct rcuwait *w); #include #include #include +#include #define MMAP_LOCK_INITIALIZER(name) \ .mmap_lock = __RWSEM_INITIALIZER((name).mmap_lock), @@ -139,8 +140,18 @@ static inline void vma_refcount_put(struct vm_area_struct *vma) int oldcnt; rwsem_release(&vma->vmlock_dep_map, _RET_IP_); + if (strcmp(current->comm, "TEST") == 0) { + pr_warn("%s: PRE-DECREMENT DELAY START\n", __func__); + mdelay(2000); + pr_warn("%s: PRE-DECREMENT DELAY END\n", __func__); + } if (!__refcount_dec_and_test(&vma->vm_refcnt, &oldcnt)) { + if (strcmp(current->comm, "TEST") == 0) { + pr_warn("%s: PRE-WAKEUP DELAY START (is_vma_writer_only()=%d)\n", __func__, is_vma_writer_only(oldcnt-1)); + mdelay(10000); + pr_warn("%s: PRE-WAKEUP DELAY END\n", __func__); + } if (is_vma_writer_only(oldcnt - 1)) rcuwait_wake_up(&mm->vma_writer_wait); } @@ -170,6 +181,11 @@ static inline struct vm_area_struct *vma_start_read(struct mm_struct *mm, if (READ_ONCE(vma->vm_lock_seq) == READ_ONCE(mm->mm_lock_seq.sequence)) return NULL; + if (strcmp(current->comm, "TEST") == 0) { + pr_warn("%s: PRE-INCREMENT DELAY START on VMA %px\n", __func__, vma); + mdelay(2000); + pr_warn("%s: PRE-INCREMENT DELAY END\n", __func__); + } /* * If VMA_LOCK_OFFSET is set, __refcount_inc_not_zero_limited_acquire() * will fail because VMA_REF_LIMIT is less than VMA_LOCK_OFFSET. @@ -179,6 +195,8 @@ static inline struct vm_area_struct *vma_start_read(struct mm_struct *mm, if (unlikely(!__refcount_inc_not_zero_limited_acquire(&vma->vm_refcnt, &oldcnt, VMA_REF_LIMIT))) { /* return EAGAIN if vma got detached from under us */ + if (strcmp(current->comm, "TEST") == 0) + pr_warn("%s: refcount acquire failed\n", __func__); return oldcnt ? NULL : ERR_PTR(-EAGAIN); } @@ -195,10 +213,14 @@ static inline struct vm_area_struct *vma_start_read(struct mm_struct *mm, * This pairs with RELEASE semantics in vma_end_write_all(). */ if (unlikely(vma->vm_lock_seq == raw_read_seqcount(&mm->mm_lock_seq))) { + if (strcmp(current->comm, "TEST") == 0) + pr_warn("%s: seqcount mismatch\n", __func__); vma_refcount_put(vma); return NULL; } + if (strcmp(current->comm, "TEST") == 0) + pr_warn("%s: returning vma\n", __func__); return vma; } diff --git a/mm/mmap_lock.c b/mm/mmap_lock.c index 5f725cc67334..7c5ca1c0d331 100644 --- a/mm/mmap_lock.c +++ b/mm/mmap_lock.c @@ -60,6 +60,12 @@ static inline bool __vma_enter_locked(struct vm_area_struct *vma, bool detaching if (!refcount_add_not_zero(VMA_LOCK_OFFSET, &vma->vm_refcnt)) return false; + if (strcmp(current->comm, "WRITER") == 0) { + pr_warn("%s: BEGIN DELAY\n", __func__); + mdelay(2000); + pr_warn("%s: END DELAY\n", __func__); + } + rwsem_acquire(&vma->vmlock_dep_map, 0, 0, _RET_IP_); rcuwait_wait_event(&vma->vm_mm->vma_writer_wait, refcount_read(&vma->vm_refcnt) == tgt_refcnt, diff --git a/mm/vma_init.c b/mm/vma_init.c index 8e53c7943561..fb57d57205de 100644 --- a/mm/vma_init.c +++ b/mm/vma_init.c @@ -31,6 +31,8 @@ struct vm_area_struct *vm_area_alloc(struct mm_struct *mm) vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); if (!vma) return NULL; + if (strcmp(current->comm, "WRITER-PREP") == 0) + pr_warn("%s: writer allocated vma %px\n", __func__, vma); vma_init(vma, mm);