linux/debian/patches/features/all/rt/mm-rmap-retry-lock-check-in...

54 lines
1.6 KiB
Diff

From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
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 <bigeasy@linutronix.de>
---
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 <linux/delay.h>
+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);