# Linux 核心 Copy On Write 實作機制 - Record contributed by < [`linD026`](https://github.com/linD026) > ###### tags: `Linux kernel COW` , `linux2021` --- [/mm/filemap.c](https://elixir.bootlin.com/linux/v5.10.38/source/mm/filemap.c#L998) ```cpp= /* * FIXME: remove all knowledge of the buffer layer from the core VM */ #include <linux/buffer_head.h> /* for try_to_free_buffers */ #include <asm/mman.h> /* * Shared mappings implemented 30.11.1994. It's not fully working yet, * though. * * Shared mappings now work. 15.8.1995 Bruno. * * finished 'unifying' the page and buffer cache and SMP-threaded the * page-cache, 21.05.1999, Ingo Molnar <mingo@redhat.com> * * SMP-threaded pagemap-LRU 1999, Andrea Arcangeli <andrea@suse.de> */ /* * Lock ordering: * * ->i_mmap_rwsem (truncate_pagecache) * ->private_lock (__free_pte->__set_page_dirty_buffers) * ->swap_lock (exclusive_swap_page, others) * ->i_pages lock * * ->i_mutex * ->i_mmap_rwsem (truncate->unmap_mapping_range) * * ->mmap_lock * ->i_mmap_rwsem * ->page_table_lock or pte_lock (various, mainly in memory.c) * ->i_pages lock (arch-dependent flush_dcache_mmap_lock) * * ->mmap_lock * ->lock_page (access_process_vm) * * ->i_mutex (generic_perform_write) * ->mmap_lock (fault_in_pages_readable->do_page_fault) * * bdi->wb.list_lock * sb_lock (fs/fs-writeback.c) * ->i_pages lock (__sync_single_inode) * * ->i_mmap_rwsem * ->anon_vma.lock (vma_adjust) * * ->anon_vma.lock * ->page_table_lock or pte_lock (anon_vma_prepare and various) * * ->page_table_lock or pte_lock * ->swap_lock (try_to_unmap_one) * ->private_lock (try_to_unmap_one) * ->i_pages lock (try_to_unmap_one) * ->pgdat->lru_lock (follow_page->mark_page_accessed) * ->pgdat->lru_lock (check_pte_range->isolate_lru_page) * ->private_lock (page_remove_rmap->set_page_dirty) * ->i_pages lock (page_remove_rmap->set_page_dirty) * bdi.wb->list_lock (page_remove_rmap->set_page_dirty) * ->inode->i_lock (page_remove_rmap->set_page_dirty) * ->memcg->move_lock (page_remove_rmap->lock_page_memcg) * bdi.wb->list_lock (zap_pte_range->set_page_dirty) * ->inode->i_lock (zap_pte_range->set_page_dirty) * ->private_lock (zap_pte_range->__set_page_dirty_buffers) * * ->i_mmap_rwsem * ->tasklist_lock (memory_failure, collect_procs_ao) */ ``` --- ## Lazy TLB ```shell <idle>-0 [001] d... 8281.860587: enter_lazy_tlb <-__schedule <...>-7615 [009] .... 8281.860587: get_close_on_exec <-do_fcntl <...>-7615 [009] .... 8281.860587: rcu_read_unlock_strict <-get_close_on_exec <...>-7615 [009] d... 8281.860588: exit_to_user_mode_prepare <-syscall_exit_to_user_mode kworker/u24:3-7503 [001] d... 8281.860588: finish_task_switch <-__schedule ``` --- ## wait_on_page_bit ```shell bash-7535 [004] .... 8473.950727: down_write <-unmap_mapping_pages bash-7535 [004] .... 8473.950727: _cond_resched <-down_write bash-7535 [004] .... 8473.950727: rcu_all_qs <-_cond_resched bash-7535 [004] .... 8473.950728: up_write <-unmap_mapping_pages bash-7535 [004] .... 8473.950728: truncate_inode_pages_range <-truncate_pagecache bash-7535 [004] .... 8473.950729: pagevec_lookup_entries <-truncate_inode_pages_range bash-7535 [004] .... 8473.950729: find_get_entries <-pagevec_lookup_entries bash-7535 [004] .... 8473.950729: rcu_read_unlock_strict <-find_get_entries bash-7535 [004] .... 8473.950730: unlock_page <-truncate_inode_pages_range bash-7535 [004] .... 8473.950730: delete_from_page_cache_batch <-truncate_inode_pages_range bash-7535 [004] .... 8473.950730: truncate_exceptional_pvec_entries.part.0 <-truncate_inode_pages_range bash-7535 [004] .... 8473.950730: __pagevec_release <-truncate_inode_pages_range bash-7535 [004] .... 8473.950731: lru_add_drain_cpu <-__pagevec_release bash-7535 [004] .... 8473.950731: release_pages <-__pagevec_release bash-7535 [004] .... 8473.950731: mem_cgroup_uncharge_list <-release_pages bash-7535 [004] .... 8473.950731: free_unref_page_list <-release_pages bash-7535 [004] .... 8473.950732: _cond_resched <-truncate_inode_pages_range bash-7535 [004] .... 8473.950732: rcu_all_qs <-_cond_resched bash-7535 [004] .... 8473.950732: pagevec_lookup_entries <-truncate_inode_pages_range bash-7535 [004] .... 8473.950732: find_get_entries <-pagevec_lookup_entries bash-7535 [004] .... 8473.950733: rcu_read_unlock_strict <-find_get_entries bash-7535 [004] .... 8473.950733: _cond_resched <-truncate_inode_pages_range bash-7535 [004] .... 8473.950733: rcu_all_qs <-_cond_resched bash-7535 [004] .... 8473.950733: pagevec_lookup_entries <-truncate_inode_pages_range bash-7535 [004] .... 8473.950734: find_get_entries <-pagevec_lookup_entries bash-7535 [004] .... 8473.950734: rcu_read_unlock_strict <-find_get_entries bash-7535 [004] .... 8473.950734: _cond_resched <-truncate_inode_pages_range bash-7535 [004] .... 8473.950734: rcu_all_qs <-_cond_resched bash-7535 [004] .... 8473.950735: wait_on_page_writeback <-truncate_inode_pages_range bash-7535 [004] .... 8473.950735: page_mapping <-wait_on_page_writeback bash-7535 [004] .... 8473.950735: wait_on_page_bit <-wait_on_page_writeback bash-7535 [004] .... 8473.950735: _raw_spin_lock_irq <-wait_on_page_bit bash-7535 [004] .... 8473.950736: io_schedule <-wait_on_page_bit bash-7535 [004] .... 8473.950736: io_schedule_prepare <-io_schedule bash-7535 [004] .... 8473.950736: schedule <-io_schedule bash-7535 [004] d... 8473.950737: rcu_note_context_switch <-__schedule bash-7535 [004] d... 8473.950737: rcu_qs <-rcu_note_context_switch bash-7535 [004] d... 8473.950737: _raw_spin_lock <-__schedule bash-7535 [004] d... 8473.950737: update_rq_clock <-__schedule bash-7535 [004] d... 8473.950738: psi_task_change <-dequeue_task bash-7535 [004] d... 8473.950738: psi_flags_change <-psi_task_change bash-7535 [004] d... 8473.950738: psi_group_change <-psi_task_change bash-7535 [004] d... 8473.950739: record_times <-psi_group_change bash-7535 [004] d... 8473.950739: psi_group_change <-psi_task_change bash-7535 [004] d... 8473.950739: record_times <-psi_group_change bash-7535 [004] d... 8473.950740: psi_group_change <-psi_task_change bash-7535 [004] d... 8473.950740: record_times <-psi_group_change bash-7535 [004] d... 8473.950740: psi_group_change <-psi_task_change bash-7535 [004] d... 8473.950741: record_times <-psi_group_change bash-7535 [004] d... 8473.950741: psi_group_change <-psi_task_change bash-7535 [004] d... 8473.950741: record_times <-psi_group_change bash-7535 [004] d... 8473.950742: psi_group_change <-psi_task_change bash-7535 [004] d... 8473.950742: record_times <-psi_group_change bash-7535 [004] d... 8473.950742: psi_group_change <-psi_task_change bash-7535 [004] d... 8473.950743: record_times <-psi_group_change bash-7535 [004] d... 8473.950743: dequeue_task_fair <-dequeue_task bash-7535 [004] d... 8473.950743: dequeue_entity <-dequeue_task_fair bash-7535 [004] d... 8473.950744: update_curr <-dequeue_entity bash-7535 [004] d... 8473.950744: update_min_vruntime <-update_curr bash-7535 [004] d... 8473.950744: cpuacct_charge <-update_curr bash-7535 [004] d... 8473.950745: rcu_read_unlock_strict <-cpuacct_charge bash-7535 [004] d... 8473.950745: __cgroup_account_cputime <-update_curr ``` ```shell <idle>-0 [004] d... 8473.954791: call_cpuidle <-do_idle <idle>-0 [004] d... 8473.954791: cpuidle_enter <-call_cpuidle <idle>-0 [004] d... 8473.954792: tick_nohz_get_next_hrtimer <-cpuidle_enter <idle>-0 [004] d... 8473.954792: cpuidle_enter_state <-cpuidle_enter <idle>-0 [004] d... 8473.954792: sched_idle_set_state <-cpuidle_enter_state <idle>-0 [004] d... 8473.954792: rcu_idle_enter <-cpuidle_enter_state <idle>-0 [004] d... 8473.954793: intel_idle <-cpuidle_enter_state <idle>-0 [004] dN.. 8473.955181: rcu_idle_exit <-cpuidle_enter_state <idle>-0 [004] dN.. 8473.955181: sched_idle_set_state <-cpuidle_enter_state <idle>-0 [004] .N.. 8473.955182: cpuidle_reflect <-do_idle <idle>-0 [004] .N.. 8473.955182: menu_reflect <-cpuidle_reflect <idle>-0 [004] .N.. 8473.955182: tick_nohz_idle_got_tick <-menu_reflect <idle>-0 [004] .N.. 8473.955182: arch_cpu_idle_exit <-do_idle <idle>-0 [004] .N.. 8473.955183: tick_nohz_idle_exit <-do_idle <idle>-0 [004] dN.. 8473.955183: ktime_get <-tick_nohz_idle_exit <idle>-0 [004] dN.. 8473.955183: update_ts_time_stats <-tick_nohz_idle_exit <idle>-0 [004] dN.. 8473.955183: nr_iowait_cpu <-update_ts_time_stats <idle>-0 [004] .N.. 8473.955184: flush_smp_call_function_from_idle <-do_idle <idle>-0 [004] .N.. 8473.955184: schedule_idle <-do_idle <idle>-0 [004] dN.. 8473.955184: rcu_note_context_switch <-__schedule <idle>-0 [004] dN.. 8473.955185: rcu_qs <-rcu_note_context_switch <idle>-0 [004] dN.. 8473.955185: _raw_spin_lock <-__schedule <idle>-0 [004] dN.. 8473.955185: update_rq_clock <-__schedule <idle>-0 [004] dN.. 8473.955186: pick_next_task_fair <-__schedule <idle>-0 [004] dN.. 8473.955186: put_prev_task_idle <-pick_next_task_fair <idle>-0 [004] dN.. 8473.955187: pick_next_entity <-pick_next_task_fair <idle>-0 [004] dN.. 8473.955187: clear_buddies <-pick_next_entity <idle>-0 [004] dN.. 8473.955187: set_next_entity <-pick_next_task_fair <idle>-0 [004] dN.. 8473.955188: __update_load_avg_se <-update_load_avg <idle>-0 [004] dN.. 8473.955188: __update_load_avg_cfs_rq <-update_load_avg <idle>-0 [004] dN.. 8473.955188: pick_next_entity <-pick_next_task_fair <idle>-0 [004] dN.. 8473.955188: clear_buddies <-pick_next_entity <idle>-0 [004] dN.. 8473.955189: set_next_entity <-pick_next_task_fair <idle>-0 [004] dN.. 8473.955189: __update_load_avg_se <-update_load_avg <idle>-0 [004] dN.. 8473.955189: __update_load_avg_cfs_rq <-update_load_avg <idle>-0 [004] d... 8473.955190: psi_task_switch <-__schedule <idle>-0 [004] d... 8473.955190: psi_flags_change <-psi_task_switch <idle>-0 [004] d... 8473.955191: psi_group_change <-psi_task_switch <idle>-0 [004] d... 8473.955191: record_times <-psi_group_change <idle>-0 [004] d... 8473.955191: psi_group_change <-psi_task_switch <idle>-0 [004] d... 8473.955192: record_times <-psi_group_change <idle>-0 [004] d... 8473.955192: psi_group_change <-psi_task_switch <idle>-0 [004] d... 8473.955192: record_times <-psi_group_change <idle>-0 [004] d... 8473.955193: psi_group_change <-psi_task_switch <idle>-0 [004] d... 8473.955193: record_times <-psi_group_change <idle>-0 [004] d... 8473.955193: psi_group_change <-psi_task_switch <idle>-0 [004] d... 8473.955194: record_times <-psi_group_change <idle>-0 [004] d... 8473.955194: psi_group_change <-psi_task_switch <idle>-0 [004] d... 8473.955194: record_times <-psi_group_change <idle>-0 [004] d... 8473.955195: psi_group_change <-psi_task_switch <idle>-0 [004] d... 8473.955195: record_times <-psi_group_change <idle>-0 [004] d... 8473.955196: switch_mm_irqs_off <-__schedule bash-7535 [004] d... 8473.955197: finish_task_switch <-__schedule bash-7535 [004] .... 8473.955197: finish_wait <-wait_on_page_bit ``` --- ## wake_up_page_bit ```shell bash-7535 [004] .... 8473.952905: bio_add_page <-ext4_bio_write_page bash-7535 [004] .... 8473.952906: __bio_try_merge_page <-bio_add_page bash-7535 [004] .... 8473.952906: __bio_add_page <-bio_add_page bash-7535 [004] .... 8473.952906: wbc_account_cgroup_owner <-ext4_bio_write_page bash-7535 [004] .... 8473.952906: unlock_page <-ext4_bio_write_page bash-7535 [004] .... 8473.952907: wake_up_page_bit <-unlock_page bash-7535 [004] .... 8473.952907: _raw_spin_lock_irqsave <-wake_up_page_bit bash-7535 [004] d... 8473.952907: __wake_up_locked_key_bookmark <-wake_up_page_bit bash-7535 [004] d... 8473.952908: __wake_up_common <-__wake_up_locked_key_bookmark bash-7535 [004] d... 8473.952908: wake_page_function <-__wake_up_common bash-7535 [004] d... 8473.952908: wake_up_state <-wake_page_function bash-7535 [004] d... 8473.952909: try_to_wake_up <-wake_up_state bash-7535 [004] d... 8473.952909: _raw_spin_lock_irqsave <-try_to_wake_up bash-7535 [004] d... 8473.952909: select_task_rq_fair <-try_to_wake_up bash-7535 [004] d... 8473.952910: available_idle_cpu <-select_task_rq_fair ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up