On Thu, 06 Mar 2025, Bharata B Rao wrote:
+static int page_should_be_promoted(struct page_hotness_info *phi) +{ + struct page *page = pfn_to_online_page(phi->pfn); + unsigned long now = jiffies; + struct folio *folio; + + if (!page || is_zone_device_page(page)) + return false; + + folio = page_folio(page); + if (!folio_test_lru(folio)) { + count_vm_event(KPROMOTED_MIG_NON_LRU); + return false; + } + if (folio_nid(folio) == phi->hot_node) { + count_vm_event(KPROMOTED_MIG_RIGHT_NODE); + return false; + }
How about using the LRU age itself: if (folio_test_active()) return true;
+ + /* If the page was hot a while ago, don't promote */ + if ((now - phi->last_update) > 2 * msecs_to_jiffies(KPROMOTED_FREQ_WINDOW)) { + count_vm_event(KPROMOTED_MIG_COLD_OLD); + return false; + } + + /* If the page hasn't been accessed enough number of times, don't promote */ + if (phi->frequency < KPRMOTED_FREQ_THRESHOLD) { + count_vm_event(KPROMOTED_MIG_COLD_NOT_ACCESSED); + return false; + } + return true; +}
...
+static int kpromoted(void *p) +{ + pg_data_t *pgdat = (pg_data_t *)p; + struct task_struct *tsk = current; + long timeout = msecs_to_jiffies(KPROMOTE_DELAY); + + const struct cpumask *cpumask = cpumask_of_node(pgdat->node_id); + + if (!cpumask_empty(cpumask)) + set_cpus_allowed_ptr(tsk, cpumask);
Explicit cpumasks are not needed if you use kthread_create_on_node(). See https://web.git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=c6a566f6c1b4d5dff659acd221f95a72923f4085
+ + while (!kthread_should_stop()) { + wait_event_timeout(pgdat->kpromoted_wait, + kpromoted_work_requested(pgdat), timeout); + kpromoted_do_work(pgdat); + } + return 0; +} + +static void kpromoted_run(int nid) +{ + pg_data_t *pgdat = NODE_DATA(nid); + + if (pgdat->kpromoted) + return; + + pgdat->kpromoted = kthread_run(kpromoted, pgdat, "kpromoted%d", nid); + if (IS_ERR(pgdat->kpromoted)) { + pr_err("Failed to start kpromoted on node %d\n", nid); + pgdat->kpromoted = NULL; + } +} +