[haiku-commits] r36197 - haiku/trunk/src/system/kernel/arch/x86

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 12 Apr 2010 22:30:49 +0200 (CEST)

Author: bonefish
Date: 2010-04-12 22:30:49 +0200 (Mon, 12 Apr 2010)
New Revision: 36197
Changeset: http://dev.haiku-os.org/changeset/36197/haiku

Modified:
   haiku/trunk/src/system/kernel/arch/x86/arch_vm_translation_map.cpp
Log:
axeld + bonefish: X86VMTranslationMap::Protect():
* Removed rounding up the end address to page alignment. It's not necessary
  and could cause an overflow.
* Fixed possible infinite loop triggered by a rare race condition: When two
  threads of a team were accessing the same unmapped page at the same time
  each would trigger a page fault. One thread would map the page again, the
  second would wait until the first one was done and update the page
  protection (unnecessarily but harmlessly). If the first thread accessed the
  page again at an unfortunate time, it would implicitly change the
  accessed/dirty flags of the page's PTE, which was a situation the loop in
  Protect() didn't consider and thus run forever.
  Seen the problem twice today in form of an app server freeze.


Modified: haiku/trunk/src/system/kernel/arch/x86/arch_vm_translation_map.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/arch_vm_translation_map.cpp  
2010-04-12 20:13:40 UTC (rev 36196)
+++ haiku/trunk/src/system/kernel/arch/x86/arch_vm_translation_map.cpp  
2010-04-12 20:30:49 UTC (rev 36197)
@@ -976,7 +976,6 @@
        page_directory_entry *pd = fArchData->pgdir_virt;
 
        start = ROUNDDOWN(start, B_PAGE_SIZE);
-       end = ROUNDUP(end, B_PAGE_SIZE);
 
        TRACE("protect_tmap: pages 0x%lx to 0x%lx, attributes %lx\n", start, 
end,
                attributes);
@@ -1022,12 +1021,15 @@
                // set the new protection flags -- we want to do that 
atomically,
                // without changing the accessed or dirty flag
                page_table_entry oldEntry;
-               do {
+               while (true) {
                        oldEntry = test_and_set_page_table_entry(&pt[index],
                                (entry & ~(X86_PTE_WRITABLE | X86_PTE_USER))
                                        | newProtectionFlags,
                                entry);
-               } while (oldEntry != entry);
+                       if (oldEntry == entry)
+                               break;
+                       entry = oldEntry;
+               }
 
                if ((oldEntry & X86_PTE_ACCESSED) != 0) {
                        // Note, that we only need to invalidate the address, 
if the


Other related posts:

  • » [haiku-commits] r36197 - haiku/trunk/src/system/kernel/arch/x86 - ingo_weinhold