]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/blob - rt-patches/0072-mm-rmap-retry-lock-check-in-anon_vma_free.patch
rt_patches: required rebase due to printk change
[hercules2020/nv-tegra/linux-4.4.git] / rt-patches / 0072-mm-rmap-retry-lock-check-in-anon_vma_free.patch
1 From e67b68a651b89851c6a97d0bf32bae603c62cdc3 Mon Sep 17 00:00:00 2001
2 From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
3 Date: Tue, 1 Dec 2015 17:57:02 +0100
4 Subject: [PATCH 072/366] mm/rmap: retry lock check in anon_vma_free()
5
6 anon_vma_free() checks if the rwsem is locked and if so performs a
7 rw lock + unlock operation. It seems the purpose is to flush the current
8 reader out.
9 From testing it seems that after the anon_vma_unlock_write() there is
10 the rt_mutex's owner field has the waiter bit set. It does seem right to
11 leave and kfree() that memory if there is still a waiter on that lock.
12 The msleep() is there in case the anon_vma_free() caller has the highest
13 priority and the waiter never gets scheduled.
14
15 XXX
16
17 Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
18 ---
19  mm/rmap.c | 12 +++++++++++-
20  1 file changed, 11 insertions(+), 1 deletion(-)
21
22 diff --git a/mm/rmap.c b/mm/rmap.c
23 index b577fbb..950d797 100644
24 --- a/mm/rmap.c
25 +++ b/mm/rmap.c
26 @@ -89,8 +89,10 @@ static inline struct anon_vma *anon_vma_alloc(void)
27         return anon_vma;
28  }
29  
30 -static inline void anon_vma_free(struct anon_vma *anon_vma)
31 +#include <linux/delay.h>
32 +static void anon_vma_free(struct anon_vma *anon_vma)
33  {
34 +       int cnt = 0;
35         VM_BUG_ON(atomic_read(&anon_vma->refcount));
36  
37         /*
38 @@ -111,9 +113,17 @@ static inline void anon_vma_free(struct anon_vma *anon_vma)
39          * happen _before_ what follows.
40          */
41         might_sleep();
42 +retry:
43         if (rwsem_is_locked(&anon_vma->root->rwsem)) {
44                 anon_vma_lock_write(anon_vma);
45                 anon_vma_unlock_write(anon_vma);
46 +
47 +               if (rwsem_is_locked(&anon_vma->root->rwsem)) {
48 +                       cnt++;
49 +                       if (cnt > 3)
50 +                               msleep(1);
51 +               }
52 +               goto retry;
53         }
54  
55         kmem_cache_free(anon_vma_cachep, anon_vma);
56 -- 
57 1.9.1
58