From: Sebastian Andrzej Siewior Date: Tue, 1 Dec 2015 17:57:02 +0100 Subject: mm/rmap: retry lock check in anon_vma_free() Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.4-rc6-rt1/patches-4.4-rc6-rt1.tar.xz anon_vma_free() checks if the rwsem is locked and if so performs a rw lock + unlock operation. It seems the purpose is to flush the current reader out. From testing it seems that after the anon_vma_unlock_write() there is the rt_mutex's owner field has the waiter bit set. It does seem right to leave and kfree() that memory if there is still a waiter on that lock. The msleep() is there in case the anon_vma_free() caller has the highest priority and the waiter never gets scheduled. XXX Signed-off-by: Sebastian Andrzej Siewior --- mm/rmap.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) --- a/mm/rmap.c +++ b/mm/rmap.c @@ -89,8 +89,10 @@ static inline struct anon_vma *anon_vma_ return anon_vma; } -static inline void anon_vma_free(struct anon_vma *anon_vma) +#include +static void anon_vma_free(struct anon_vma *anon_vma) { + int cnt = 0; VM_BUG_ON(atomic_read(&anon_vma->refcount)); /* @@ -111,9 +113,17 @@ static inline void anon_vma_free(struct * happen _before_ what follows. */ might_sleep(); +retry: if (rwsem_is_locked(&anon_vma->root->rwsem)) { anon_vma_lock_write(anon_vma); anon_vma_unlock_write(anon_vma); + + if (rwsem_is_locked(&anon_vma->root->rwsem)) { + cnt++; + if (cnt > 3) + msleep(1); + } + goto retry; } kmem_cache_free(anon_vma_cachep, anon_vma);