guard mm->rss with page_table_lock (241p11)
Subsystems (6)
PATCH 1/1 guard mm->rss with page_table_lock (241p11)
Hi.
This patch tries to fix the potential rss accounting race where we fiddle with mm->rss without holding the page_table_lock.
In addition to the places this patch touches there are some places in fs/ where mm->rss is touched. But I am not sure of the finer points of this code, so perhaps somebody else could have a look? The files are binfmt_aout.c, binfmt_elf.c, and exec.c.
It applies against ac12 and 241p11.
Please comment. Or else I will continue to sumbit it :)
mm/memory.c +7 -1
@@ -377,7 +377,6 @@ address = (address +PGDIR_SIZE ) &PGDIR_MASK ; dir++; }while (address && (address < end)); -spin_unlock (&mm->page_table_lock);/* * Update rss for the mm_struct (not necessarily current->mm) * Notice that rss is an unsigned long.
@@ -386,6 +385,7 @@ mm->rss -= freed; else mm->rss = 0; +spin_unlock (&mm->page_table_lock); }
@@ -1038,7 +1038,9 @@flush_icache_page (vma, page); } +spin_lock (&mm->page_table_lock); mm->rss++; +spin_unlock (&mm->page_table_lock); pte =mk_pte (page, vma->vm_page_prot);
@@ -1072,7 +1074,9 @@return -1 ;clear_user_highpage (page, addr); entry =pte_mkwrite (pte_mkdirty (mk_pte (page, vma->vm_page_prot))); +spin_lock (&mm->page_table_lock); mm->rss++; +spin_unlock (&mm->page_table_lock);flush_page_to_ram (page); }set_pte (page_table, entry);
@@ -1111,7 +1115,9 @@return 0 ;if (new_page ==NOPAGE_OOM )return -1 ; +spin_lock (&mm->page_table_lock); ++mm->rss; +spin_unlock (&mm->page_table_lock);/* * This silly early PAGE_DIRTY setting removes a race * due to the bad i386 page protection. But it's valid
mm/mmap.c +1 -1
@@ -879,8 +879,8 @@spin_lock (&mm->page_table_lock); mpnt = mm->mmap; mm->mmap = mm->mmap_avl = mm->mmap_cache =NULL ; -spin_unlock (&mm->page_table_lock); mm->rss =0 ; +spin_unlock (&mm->page_table_lock); mm->total_vm =0 ; mm->locked_vm =0 ;while (mpnt) {
mm/swapfile.c +2 -0
@@ -231,7 +231,9 @@set_pte (dir,pte_mkdirty (mk_pte (page, vma->vm_page_prot)));swap_free (entry);get_page (page); +spin_lock (&vma->vm_mm->page_table_lock); ++vma->vm_mm->rss; +spin_unlock (&vma->vm_mm->page_table_lock); } static inline void unuse_pmd(struct vm_area_struct * vma, pmd_t *dir,
mm/vmscan.c +2 -0
@@ -72,7 +72,9 @@swap_duplicate (entry);set_pte (page_table,swp_entry_to_pte (entry)); drop_pte: +spin_lock (&mm->page_table_lock); mm->rss--; +spin_unlock (&mm->page_table_lock);if (!page->age)deactivate_page (page);UnlockPage (page);
Signature · 9 lines
Regards,
Rasmus([email protected])
I've never had major knee surgery on any other part of my body.
-Winston Bennett, University of Kentucky basketball forward
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/Quoted 1 line · Rasmus Andersen
Please comment. Or else I will continue to sumbit it :)
The following will hang the kernel on SMP, since you're already holding the spinlock here. Try compiling with CONFIG_SMP and see what happens...
mm/vmscan.c line 80
Quoted 13 lines
diff -aur
linux-2.4.1-pre11-clean/mm/vmscan.clinux/mm/vmscan.cmm/vmscan.c +2
-0@@ -72,7 +72,9 @@swap_duplicate (entry);set_pte (page_table,swp_entry_to_pte (entry)); drop_pte: +spin_lock (&mm->page_table_lock); mm->rss--; +spin_unlock (&mm->page_table_lock);if (!page->age)deactivate_page (page);UnlockPage (page);
regards,
Rik
--
Virtual memory is like a game you can't win; However, without VM there's truly nothing to lose...
http://www.surriel.com/
http://www.conectiva.com/ http://distro.conectiva.com.br/
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/
Quoted 7 lines · Rik van Riel
Quoted 1 line · Rasmus Andersen
Please comment. Or else I will continue to sumbit it :)
The following will hang the kernel on SMP, since you're already holding the spinlock here. Try compiling with
CONFIG_SMPand see what happens...
You are right. Sloppy research by me :(
New patch below with the vmscan part removed.
mm/memory.c +7 -1
@@ -377,7 +377,6 @@ address = (address +PGDIR_SIZE ) &PGDIR_MASK ; dir++; }while (address && (address < end)); -spin_unlock (&mm->page_table_lock);/* * Update rss for the mm_struct (not necessarily current->mm) * Notice that rss is an unsigned long.
@@ -386,6 +385,7 @@ mm->rss -= freed; else mm->rss = 0; +spin_unlock (&mm->page_table_lock); }
@@ -1038,7 +1038,9 @@flush_icache_page (vma, page); } +spin_lock (&mm->page_table_lock); mm->rss++; +spin_unlock (&mm->page_table_lock); pte =mk_pte (page, vma->vm_page_prot);
@@ -1072,7 +1074,9 @@return -1 ;clear_user_highpage (page, addr); entry =pte_mkwrite (pte_mkdirty (mk_pte (page, vma->vm_page_prot))); +spin_lock (&mm->page_table_lock); mm->rss++; +spin_unlock (&mm->page_table_lock);flush_page_to_ram (page); }set_pte (page_table, entry);
@@ -1111,7 +1115,9 @@return 0 ;if (new_page ==NOPAGE_OOM )return -1 ; +spin_lock (&mm->page_table_lock); ++mm->rss; +spin_unlock (&mm->page_table_lock);/* * This silly early PAGE_DIRTY setting removes a race * due to the bad i386 page protection. But it's valid
mm/mmap.c +1 -1
@@ -879,8 +879,8 @@spin_lock (&mm->page_table_lock); mpnt = mm->mmap; mm->mmap = mm->mmap_avl = mm->mmap_cache =NULL ; -spin_unlock (&mm->page_table_lock); mm->rss =0 ; +spin_unlock (&mm->page_table_lock); mm->total_vm =0 ; mm->locked_vm =0 ;while (mpnt) {
mm/swapfile.c +2 -0
@@ -231,7 +231,9 @@set_pte (dir,pte_mkdirty (mk_pte (page, vma->vm_page_prot)));swap_free (entry);get_page (page); +spin_lock (&vma->vm_mm->page_table_lock); ++vma->vm_mm->rss; +spin_unlock (&vma->vm_mm->page_table_lock); } static inline void unuse_pmd(struct vm_area_struct * vma, pmd_t *dir,
Signature · 5 lines
Rasmus([email protected]) -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux.eu.org/Linux-MM/
Quoted 5 lines · Rasmus Andersen
Quoted 4 lines · Rik van Riel
Quoted 1 line · Rasmus Andersen
Please comment. Or else I will continue to sumbit it :)
Quoted 7 lines
Quoted 3 lines
The following will hang the kernel on SMP, since you're already holding the spinlock here. Try compiling with
CONFIG_SMPand see what happens...You are right. Sloppy research by me :(
New patch below with the vmscan part removed.
Have you bothered to also check the rest?
Don't be surprised if there are more places
like this. Please compile your kernel withCONFIG_SMP and test if your changes work
before submitting them into the stable kernel.
regards,
Rik
--
Virtual memory is like a game you can't win; However, without VM there's truly nothing to lose...
http://www.surriel.com/
http://www.conectiva.com/ http://distro.conectiva.com.br/
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/
mm/memory.c line 1043
Quoted 5 lines
...
mm/memory.c +2
-0+spin_lock (&mm->page_table_lock); mm->rss++; +spin_unlock (&mm->page_table_lock);
Would it not be better to use some sort of atomic add/subtract/clear operation rather than a spinlock? (Which would also give you fewer atomic memory access cycles).
David
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/
Quoted 9 lines · David Howells
mm/memory.c line 1043
Quoted 5 lines
...
mm/memory.c +2
-0+spin_lock (&mm->page_table_lock); mm->rss++; +spin_unlock (&mm->page_table_lock);Would it not be better to use some sort of atomic add/subtract/clear operation rather than a spinlock? (Which would also give you fewer atomic memory access cycles).
This will unfortunately not do for all platforms. Please read
http://marc.theaimsgroup.com/?t=97630768100003&w=2&r=1 for the last discussion of this.
Regards,
Rasmus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/
Quoted 9 lines
Quoted 8 lines
mm/memory.c line 1043
Quoted 4 lines
mm/memory.c +2
-0+spin_lock (&mm->page_table_lock); mm->rss++; +spin_unlock (&mm->page_table_lock);Would it not be better to use some sort of atomic add/subtract/clear operation rather than a spinlock? (Which would also give you fewer atomic memory access cycles).
Quoted 3 lines
This will unfortunately not do for all platforms. Please read
http://marc.theaimsgroup.com/?t=97630768100003&w=2&r=1 for the last discussion of this.
which can be summarized as "yet another way sparc support screws Linux, and DMiller didn't want to fix his mess close to 2.4.0". it's ridiculous for an inconsequential arch like sparc32 to cause fairly noticable problems for all other arches.
if noone beats me, I'll be submitting a patch to fix this silliness in 2.5.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/
Quoted 17 lines · Mark Hahn
Quoted 6 lines
Quoted 6 lines
mm/memory.c line 1043
Quoted 4 lines
mm/memory.c +2
-0+spin_lock (&mm->page_table_lock); mm->rss++; +spin_unlock (&mm->page_table_lock);Would it not be better to use some sort of atomic add/subtract/clear
operation
Quoted 1 line
Quoted 1 line
rather than a spinlock? (Which would also give you fewer atomic memory
access
Quoted 5 lines
Quoted 1 line
cycles).
This will unfortunately not do for all platforms. Please read
http://marc.theaimsgroup.com/?t=97630768100003&w=2&r=1 for the last discussion of this.
Quoted 6 lines
which can be summarized as "yet another way sparc support screws Linux, and DMiller didn't want to fix his mess close to 2.4.0". it's ridiculous for an inconsequential arch like sparc32 to cause fairly noticable problems for all other arches.
if noone beats me, I'll be submitting a patch to fix this silliness in 2.5.
The thing is we need a spinlock to actually change the page tables to change the rss. We pretty much get the accounting of rss under the same spinlock for free.
Eric
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/
Quoted 3 lines · David Howells
Would it not be better to use some sort of atomic add/subtract/clear operation rather than a spinlock? (Which would also give you fewer atomic memory access cycles).
Please see older threads about this, it has been discussed to death already (hint: sizeof(atomic_t), sizeof(unsigned long)).
Later,
David S. Miller
[email protected]
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/
On Tue, Jan 30, 2001 at 12:39:24AM -0800, David S. Miller wrote:
Please see older threads about this, it has been discussed to death already (hint: sizeof(atomic_t), sizeof(unsigned long)).
can we not define a macro so architectures that can do do atomically inc/dec with unsigned long will? otherwise it uses the spinlock?
--cw
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/
Quoted 7 lines · Chris Wedgwood
On Tue, Jan 30, 2001 at 12:39:24AM -0800, David S. Miller wrote:
Please see older threads about this, it has been discussed to death already (hint:
sizeof(atomic_t), sizeof(unsigned long)).can we not define a macro so architectures that can do do atomically inc/dec with unsigned long will? otherwise it uses the spinlock?
Why bother ?
In most places where we update mm->rss, we are *already* holding the spinlock anyway, this correction is just for a few places.
The big patch Rasmus made seems to contain spin_lock(&foo) in places where we already have the lock, leading to instant SMP deadlock. I suspect Rasmus' patch should be about half the size it is currently...
regards,
Rik
--
Virtual memory is like a game you can't win; However, without VM there's truly nothing to lose...
http://www.surriel.com/
http://www.conectiva.com/ http://distro.conectiva.com.br/
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/
Quoted 10 lines · Rik van Riel
Why bother ?
In most places where we update
mm->rss, we are *already* holding the spinlock anyway, this correction is just for a few places.The big patch Rasmus made seems to contain
spin_lock(&foo)in places where we already have the lock, leading to instant SMP deadlock. I suspect Rasmus' patch should be about half the size it is currently...
After donning my brown paper bag yesterday I looked at the call-paths again and removed one more lock pair (the one in swapfile). The others seemed OK so I made a SMP-on-UP kernel and ran my usual stuff (X, mozilla, kernel compiles) alongside mmap001, mmap002 and misc001 with no ill effects.
I will beat on it some more today and tomorrow, but if real SMP is needed for testing I need some help to do that.
Regards,
Rasmus
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/
Excuse me if I am off base here, but wouldn't an atomic operation be better here. There are atomic inc/dec and add/sub macros for this. It just seems that that is all that is needed here (from inspection of the patch).
George
Quoted 93 lines · Rasmus Andersen
Quoted 7 lines · Rik van Riel
Quoted 1 line · Rasmus Andersen
Please comment. Or else I will continue to sumbit it :)
The following will hang the kernel on SMP, since you're already holding the spinlock here. Try compiling with
CONFIG_SMPand see what happens...You are right. Sloppy research by me :(
New patch below with the vmscan part removed.
diff -aur
linux-2.4.1-pre11-clean/mm/memory.clinux/mm/memory.cmm/memory.c Sun Jan 28 22:43:04 2001 renamed from mm/memory.c Sun Jan 28 20:53:13 2001 +7
-1@@ -377,7 +377,6 @@ address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); - spin_unlock(&mm->page_table_lock); /* * Update rss for the mm_struct (not necessarily current->mm) * Notice that rss is an unsigned long.@@ -386,6 +385,7 @@ mm->rss -= freed; else mm->rss = 0; + spin_unlock(&mm->page_table_lock); }@@ -1038,7 +1038,9 @@ flush_icache_page(vma, page); } + spin_lock(&mm->page_table_lock); mm->rss++; + spin_unlock(&mm->page_table_lock); pte = mk_pte(page, vma->vm_page_prot);@@ -1072,7 +1074,9 @@ return -1; clear_user_highpage(page, addr); entry = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))); + spin_lock(&mm->page_table_lock); mm->rss++; + spin_unlock(&mm->page_table_lock); flush_page_to_ram(page); } set_pte(page_table, entry);@@ -1111,7 +1115,9 @@ return 0; if (new_page == NOPAGE_OOM) return -1; + spin_lock(&mm->page_table_lock); ++mm->rss; + spin_unlock(&mm->page_table_lock); /* * This silly early PAGE_DIRTY setting removes a race * due to the bad i386 page protection. But it's validdiff -aur
linux-2.4.1-pre11-clean/mm/mmap.clinux/mm/mmap.cmm/mmap.c Sun Jan 28 22:43:04 2001 renamed from mm/mmap.c Sat Dec 30 18:35:19 2000 +1
-1@@ -879,8 +879,8 @@ spin_lock(&mm->page_table_lock); mpnt = mm->mmap; mm->mmap = mm->mmap_avl = mm->mmap_cache = NULL; - spin_unlock(&mm->page_table_lock); mm->rss = 0; + spin_unlock(&mm->page_table_lock); mm->total_vm = 0; mm->locked_vm = 0; while (mpnt) {diff -aur
linux-2.4.1-pre11-clean/mm/swapfile.clinux/mm/swapfile.cmm/swapfile.c Sun Jan 28 22:43:04 2001 renamed from mm/swapfile.c Fri Dec 29 23:07:24 2000 +2
-2@@ -231,7 +231,9 @@ set_pte(dir, pte_mkdirty(mk_pte(page, vma->vm_page_prot))); swap_free(entry); get_page(page); + spin_lock(&vma->vm_mm->page_table_lock); ++vma->vm_mm->rss; + spin_unlock(&vma->vm_mm->page_table_lock); } static inline void unuse_pmd(struct vm_area_struct * vma, pmd_t *dir, -- Rasmus([email protected]) -
Quoted 3 lines
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
Please read the FAQ at http://www.tux.org/lkml/
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/
Quoted 4 lines · george anzinger
Excuse me if I am off base here, but wouldn't an atomic operation be better here. There are atomic inc/dec and add/sub macros for this. It just seems that that is all that is needed here (from inspection of the patch).
Most functions which touch mm->rss already hold mm->page_table_lock (also this functions are called more often and they use more CPU).
Making those functions use an atomic instruction just to optimize the functions which do not lock mm->page_table_lock is not a good tradeoff.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/
Hi,
Quoted 4 lines · george anzinger
Excuse me if I am off base here, but wouldn't an atomic operation be better here. There are atomic inc/dec and add/sub macros for this. It just seems that that is all that is needed here (from inspection of the patch).
The counter-argument is that we already hold the page table lock in the vast majority of places where the rss is modified, so overall it's cheaper to avoid the extra atomic update.
Cheers,
Stephen
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux.eu.org/Linux-MM/