locking
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. Started Oct 1999 by Kanoj Sarcar <kanoj@sgi.com>
  2. The intent of this file is to have an uptodate, running commentary 
  3. from different people about how locking and synchronization is done 
  4. in the Linux vm code.
  5. page_table_lock & mmap_sem
  6. --------------------------------------
  7. Page stealers pick processes out of the process pool and scan for 
  8. the best process to steal pages from. To guarantee the existence 
  9. of the victim mm, a mm_count inc and a mmdrop are done in swap_out().
  10. Page stealers hold kernel_lock to protect against a bunch of races.
  11. The vma list of the victim mm is also scanned by the stealer, 
  12. and the page_table_lock is used to preserve list sanity against the
  13. process adding/deleting to the list. This also guarantees existence
  14. of the vma. Vma existence is not guaranteed once try_to_swap_out() 
  15. drops the page_table_lock. To guarantee the existence of the underlying 
  16. file structure, a get_file is done before the swapout() method is 
  17. invoked. The page passed into swapout() is guaranteed not to be reused
  18. for a different purpose because the page reference count due to being
  19. present in the user's pte is not released till after swapout() returns.
  20. Any code that modifies the vmlist, or the vm_start/vm_end/
  21. vm_flags:VM_LOCKED/vm_next of any vma *in the list* must prevent 
  22. kswapd from looking at the chain.
  23. The rules are:
  24. 1. To scan the vmlist (look but don't touch) you must hold the
  25.    mmap_sem with read bias, i.e. down_read(&mm->mmap_sem)
  26. 2. To modify the vmlist you need to hold the mmap_sem with
  27.    read&write bias, i.e. down_write(&mm->mmap_sem)  *AND*
  28.    you need to take the page_table_lock.
  29. 3. The swapper takes _just_ the page_table_lock, this is done
  30.    because the mmap_sem can be an extremely long lived lock
  31.    and the swapper just cannot sleep on that.
  32. 4. The exception to this rule is expand_stack, which just
  33.    takes the read lock and the page_table_lock, this is ok
  34.    because it doesn't really modify fields anybody relies on.
  35. 5. You must be able to guarantee that while holding page_table_lock
  36.    or page_table_lock of mm A, you will not try to get either lock
  37.    for mm B.
  38. The caveats are:
  39. 1. find_vma() makes use of, and updates, the mmap_cache pointer hint.
  40. The update of mmap_cache is racy (page stealer can race with other code
  41. that invokes find_vma with mmap_sem held), but that is okay, since it 
  42. is a hint. This can be fixed, if desired, by having find_vma grab the
  43. page_table_lock.
  44. Code that add/delete elements from the vmlist chain are
  45. 1. callers of insert_vm_struct
  46. 2. callers of merge_segments
  47. 3. callers of avl_remove
  48. Code that changes vm_start/vm_end/vm_flags:VM_LOCKED of vma's on
  49. the list:
  50. 1. expand_stack
  51. 2. mprotect
  52. 3. mlock
  53. 4. mremap
  54. It is advisable that changes to vm_start/vm_end be protected, although 
  55. in some cases it is not really needed. Eg, vm_start is modified by 
  56. expand_stack(), it is hard to come up with a destructive scenario without 
  57. having the vmlist protection in this case.
  58. The page_table_lock nests with the inode i_shared_lock and the kmem cache
  59. c_spinlock spinlocks. This is okay, since code that holds i_shared_lock 
  60. never asks for memory, and the kmem code asks for pages after dropping
  61. c_spinlock. The page_table_lock also nests with pagecache_lock and 
  62. pagemap_lru_lock spinlocks, and no code asks for memory with these locks
  63. held.
  64. The page_table_lock is grabbed while holding the kernel_lock spinning monitor.
  65. The page_table_lock is a spin lock.
  66. swap_list_lock/swap_device_lock
  67. -------------------------------
  68. The swap devices are chained in priority order from the "swap_list" header. 
  69. The "swap_list" is used for the round-robin swaphandle allocation strategy.
  70. The #free swaphandles is maintained in "nr_swap_pages". These two together
  71. are protected by the swap_list_lock. 
  72. The swap_device_lock, which is per swap device, protects the reference 
  73. counts on the corresponding swaphandles, maintained in the "swap_map"
  74. array, and the "highest_bit" and "lowest_bit" fields.
  75. Both of these are spinlocks, and are never acquired from intr level. The
  76. locking hierarchy is swap_list_lock -> swap_device_lock.
  77. To prevent races between swap space deletion or async readahead swapins
  78. deciding whether a swap handle is being used, ie worthy of being read in
  79. from disk, and an unmap -> swap_free making the handle unused, the swap
  80. delete and readahead code grabs a temp reference on the swaphandle to
  81. prevent warning messages from swap_duplicate <- read_swap_cache_async.
  82. Swap cache locking
  83. ------------------
  84. Pages are added into the swap cache with kernel_lock held, to make sure
  85. that multiple pages are not being added (and hence lost) by associating
  86. all of them with the same swaphandle.
  87. Pages are guaranteed not to be removed from the scache if the page is 
  88. "shared": ie, other processes hold reference on the page or the associated 
  89. swap handle. The only code that does not follow this rule is shrink_mmap,
  90. which deletes pages from the swap cache if no process has a reference on 
  91. the page (multiple processes might have references on the corresponding
  92. swap handle though). lookup_swap_cache() races with shrink_mmap, when
  93. establishing a reference on a scache page, so, it must check whether the
  94. page it located is still in the swapcache, or shrink_mmap deleted it.
  95. (This race is due to the fact that shrink_mmap looks at the page ref
  96. count with pagecache_lock, but then drops pagecache_lock before deleting
  97. the page from the scache).
  98. do_wp_page and do_swap_page have MP races in them while trying to figure
  99. out whether a page is "shared", by looking at the page_count + swap_count.
  100. To preserve the sum of the counts, the page lock _must_ be acquired before
  101. calling is_page_shared (else processes might switch their swap_count refs
  102. to the page count refs, after the page count ref has been snapshotted).
  103. Swap device deletion code currently breaks all the scache assumptions,
  104. since it grabs neither mmap_sem nor page_table_lock.