54 lines
1.6 KiB
Diff
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);
|