#author("2025-09-11T13:46:16+09:00","default:guest","guest") #author("2025-09-11T13:47:08+09:00","default:guest","guest") *参照元 [#g5f1b261] #backlinks *説明 [#u580f8e1] -パス: [[linux-5.15/mm/compaction.c]] -kcompactdのスレッドメイン関数 **引数 [#kc412fe3] -void *p --メモリノード。pg_data_t型のポインタを指定する。 --[[linux-5.15/pg_data_t]] **返り値 [#h05b60fb] -int --意味はない。常に0。 --常に0、基本的に終了しないので意味は特に無い。 **参考 [#h9ea645c] *実装 [#v0fcdc16] /* * The background compaction daemon, started as a kernel thread * from the init process. */ static int kcompactd(void *p) { pg_data_t *pgdat = (pg_data_t *)p; struct task_struct *tsk = current; long default_timeout = msecs_to_jiffies(HPAGE_FRAG_CHECK_INTERVAL_MSEC); long timeout = default_timeout; const struct cpumask *cpumask = cpumask_of_node(pgdat->node_id); if (!cpumask_empty(cpumask)) set_cpus_allowed_ptr(tsk, cpumask); set_freezable(); - --[[linux-5.15/pg_data_t]] --[[linux-5.15/task_struct]] --[[linux-5.15/msecs_to_jiffies()]] --[[linux-5.15/cpumask]] --[[linux-5.15/cpumask_of_node()]] --[[linux-5.15/cpumask_empty()]] --[[linux-5.15/set_cpus_allowed_ptr()]] --[[linux-5.15/set_freezable()]] pgdat->kcompactd_max_order = 0; pgdat->kcompactd_highest_zoneidx = pgdat->nr_zones - 1; while (!kthread_should_stop()) { unsigned long pflags; /* * Avoid the unnecessary wakeup for proactive compaction * when it is disabled. */ if (!sysctl_compaction_proactiveness) timeout = MAX_SCHEDULE_TIMEOUT; trace_mm_compaction_kcompactd_sleep(pgdat->node_id); if (wait_event_freezable_timeout(pgdat->kcompactd_wait, kcompactd_work_requested(pgdat), timeout) && !pgdat->proactive_compact_trigger) { - --[[linux-5.15/kthread_should_stop()]] --[[linux-5.15/trace_mm_compaction_kcompactd_sleep()]] --[[linux-5.15/wait_freezable_timeout()]] --[[linux-5.15/kcompactd_work_requested()]] psi_memstall_enter(&pflags); kcompactd_do_work(pgdat); psi_memstall_leave(&pflags); /* * Reset the timeout value. The defer timeout from * proactive compaction is lost here but that is fine * as the condition of the zone changing substantionally * then carrying on with the previous defer interval is * not useful. */ timeout = default_timeout; continue; } - --[[linux-5.15/psi_memstall_enter()]] --[[linux-5.15/kcompactd_do_work()]] --[[linux-5.15/psi_memstall_leave()]] /* * Start the proactive work with default timeout. Based * on the fragmentation score, this timeout is updated. */ timeout = default_timeout; if (should_proactive_compact_node(pgdat)) { unsigned int prev_score, score; prev_score = fragmentation_score_node(pgdat); proactive_compact_node(pgdat); score = fragmentation_score_node(pgdat); /* * Defer proactive compaction if the fragmentation * score did not go down i.e. no progress made. */ if (unlikely(score >= prev_score)) timeout = default_timeout << COMPACT_MAX_DEFER_SHIFT; } if (unlikely(pgdat->proactive_compact_trigger)) pgdat->proactive_compact_trigger = false; - --[[linux-5.15/should_proactive_compact_node()]] --[[linux-5.15/fragmentation_score_node()]] --[[linux-5.15/proactive_compact_node()]] --[[linux-5.15/unlikely()]] } return 0; } *コメント [#cbc2437f]