[PATCH 4/4] VM/RMAP: Move avc freeing outside the lock

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Andi Kleen <ak@xxxxxxxxxxxxxxx>

Now that the avc locking is batched move the freeing of AVCs
outside the lock. This lowers lock contention somewhat more on
a fork/exit intensive workload.

Acked-by: Rik van Riel<riel@xxxxxxxxxx>
Signed-off-by: Andi Kleen <ak@xxxxxxxxxxxxxxx>
---
 mm/rmap.c |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/mm/rmap.c b/mm/rmap.c
index d4d3680..57f8ba9 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -302,7 +302,6 @@ static void anon_vma_unlink(struct anon_vma_chain *anon_vma_chain,
 			    struct anon_vma_lock_state *avs)
 {
 	struct anon_vma *anon_vma = anon_vma_chain->anon_vma;
-	int empty;
 
 	/* If anon_vma_fork fails, we can get an empty anon_vma_chain. */
 	if (!anon_vma)
@@ -310,19 +309,14 @@ static void anon_vma_unlink(struct anon_vma_chain *anon_vma_chain,
 
 	anon_vma_lock_batch(anon_vma, avs);
 	list_del(&anon_vma_chain->same_anon_vma);
-
-	/* We must garbage collect the anon_vma if it's empty */
-	empty = list_empty(&anon_vma->head);
-
-	if (empty)
-		put_anon_vma(anon_vma);
 }
 
 void unlink_anon_vmas(struct vm_area_struct *vma)
 {
 	struct anon_vma_chain *avc, *next;
 	struct anon_vma_lock_state avs;
-	
+	LIST_HEAD(avmas);
+
 	/*
 	 * Unlink each anon_vma chained to the VMA.  This list is ordered
 	 * from newest to oldest, ensuring the root anon_vma gets freed last.
@@ -330,10 +324,20 @@ void unlink_anon_vmas(struct vm_area_struct *vma)
 	anon_vma_lock_batch_init(&avs);
 	list_for_each_entry_safe(avc, next, &vma->anon_vma_chain, same_vma) {
 		anon_vma_unlink(avc, &avs);
-		list_del(&avc->same_vma);
-		anon_vma_chain_free(avc);
+		list_move(&avc->same_vma, &avmas);
 	}
 	anon_vma_unlock_batch(&avs);
+
+	/* Now free them outside the lock */
+	list_for_each_entry_safe(avc, next, &avmas, same_vma) {
+		/* 
+		 * list_empty check can be done lockless because
+		 * once it is empty noone will readd.
+		 */
+		if (list_empty(&avc->anon_vma->head))
+			put_anon_vma(avc->anon_vma);
+		anon_vma_chain_free(avc);		
+	}
 }
 
 static void anon_vma_ctor(void *data)
-- 
1.7.4.4

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@xxxxxxxxxx  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@xxxxxxxxx";> email@xxxxxxxxx </a>


[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]