#author("2025-09-11T20:07:53+09:00","default:guest","guest")
#author("2025-09-11T20:08:43+09:00","default:guest","guest")
*参照元 [#j5150125]
#backlinks

*説明 [#e531e8c6]
-パス: [[linux-5.15/mm/vmscan.c]]

-FIXME: これは何?
--説明


**引数 [#bf840f83]
--unsigned long nr_to_scan
--
-struct lruvec *lruvec
--
--[[linux-5.15/lruvec]]
-struct scan_control *sc
--
--[[linux-5.15/scan_control]]
-enum lru_list lru
--
--[[linux-5.15/lru_list]]


**返り値 [#zfccce4b]
-
--
-unsigned long
--回収したページ数。


**参考 [#b08f9718]


*実装 [#neeac27a]

 /*
  * shrink_inactive_list() is a helper for shrink_node().  It returns the number
  * of reclaimed pages
  */
 static unsigned long
 shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
 		     struct scan_control *sc, enum lru_list lru)
 {
 	LIST_HEAD(page_list);
 	unsigned long nr_scanned;
 	unsigned int nr_reclaimed = 0;
 	unsigned long nr_taken;
 	struct reclaim_stat stat;
 	bool file = is_file_lru(lru);
 	enum vm_event_item item;
 	struct pglist_data *pgdat = lruvec_pgdat(lruvec);
 	bool stalled = false;
 
-
--[[linux-5.15/LIST_HEAD()]]
--[[linux-5.15/reclaim_stat]]
--[[linux-5.15/is_file_lru()]]
--[[linux-5.15/vm_event_item]]
--[[linux-5.15/pglist_data]]
--[[linux-5.15/lruvec_pgdat()]]

 	while (unlikely(too_many_isolated(pgdat, file, sc))) {
 		if (stalled)
 			return 0;
 
 		/* wait a bit for the reclaimer. */
 		msleep(100);
 		stalled = true;
 
 		/* We are about to die and free our memory. Return now. */
 		if (fatal_signal_pending(current))
 			return SWAP_CLUSTER_MAX;
 	}
 
-
--[[linux-5.15/unlikely()]]
--[[linux-5.15/too_many_isolated()]]
--[[linux-5.15/msleep()]]
--[[linux-5.15/fatal_signal_pending()]]

 	lru_add_drain();
 
-
--[[linux-5.15/lru_add_drain()]]

 	spin_lock_irq(&lruvec->lru_lock);
 
 	nr_taken = isolate_lru_pages(nr_to_scan, lruvec, &page_list,
 				     &nr_scanned, sc, lru);
 
-
--[[linux-5.15/spin_lock_irq()]]
--[[linux-5.15/isolate_lru_pages()]]

 	__mod_node_page_state(pgdat, NR_ISOLATED_ANON + file, nr_taken);
 	item = current_is_kswapd() ? PGSCAN_KSWAPD : PGSCAN_DIRECT;
 	if (!cgroup_reclaim(sc))
 		__count_vm_events(item, nr_scanned);
 	__count_memcg_events(lruvec_memcg(lruvec), item, nr_scanned);
 	__count_vm_events(PGSCAN_ANON + file, nr_scanned);
 
 	spin_unlock_irq(&lruvec->lru_lock);
 
-
--[[linux-5.15/__mod_node_page_state()]]
--[[linux-5.15/current_is_kswapd()]]
--[[linux-5.15/cgroup_reclaim()]]
--[[linux-5.15/lruvec_memcg()]]
--[[linux-5.15/__count_vm_events()]]
--[[linux-5.15/__count_memcg_events()]]
--[[linux-5.15/spin_unlock_irq()]]

 	if (nr_taken == 0)
 		return 0;
 
 	nr_reclaimed = shrink_page_list(&page_list, pgdat, sc, &stat, false);
 
-
--[[linux-5.15/shrink_page_list()]]

 	spin_lock_irq(&lruvec->lru_lock);
 	move_pages_to_lru(lruvec, &page_list);
 
-
--[[linux-5.15/spin_lock_irq()]]
--[[linux-5.15/move_pages_to_lru()]]

 	__mod_node_page_state(pgdat, NR_ISOLATED_ANON + file, -nr_taken);
 	item = current_is_kswapd() ? PGSTEAL_KSWAPD : PGSTEAL_DIRECT;
 	if (!cgroup_reclaim(sc))
 		__count_vm_events(item, nr_reclaimed);
 	__count_memcg_events(lruvec_memcg(lruvec), item, nr_reclaimed);
 	__count_vm_events(PGSTEAL_ANON + file, nr_reclaimed);
 	spin_unlock_irq(&lruvec->lru_lock);
 
-
--[[linux-5.15/__mod_node_page_state()]]
--[[linux-5.15/current_is_kswapd()]]
--[[linux-5.15/cgroup_reclaim()]]
--[[linux-5.15/__count_vm_events()]]
--[[linux-5.15/__count_memcg_events()]]
--[[linux-5.15/lruvec_memcg()]]
--[[linux-5.15/spin_unlock_irq()]]

 	lru_note_cost(lruvec, file, stat.nr_pageout);
 	mem_cgroup_uncharge_list(&page_list);
 	free_unref_page_list(&page_list);
 
-
--[[linux-5.15/lru_note_cost()]]
--[[linux-5.15/mem_cgroup_uncharge_list()]]
--[[linux-5.15/free_unref_page_list()]]

 	/*
 	 * If dirty pages are scanned that are not queued for IO, it
 	 * implies that flushers are not doing their job. This can
 	 * happen when memory pressure pushes dirty pages to the end of
 	 * the LRU before the dirty limits are breached and the dirty
 	 * data has expired. It can also happen when the proportion of
 	 * dirty pages grows not through writes but through memory
 	 * pressure reclaiming all the clean cache. And in some cases,
 	 * the flushers simply cannot keep up with the allocation
 	 * rate. Nudge the flusher threads in case they are asleep.
 	 */
 	if (stat.nr_unqueued_dirty == nr_taken)
 		wakeup_flusher_threads(WB_REASON_VMSCAN);
 
-
--[[linux-5.15/wakeup_flusher_threads()]]

 	sc->nr.dirty += stat.nr_dirty;
 	sc->nr.congested += stat.nr_congested;
 	sc->nr.unqueued_dirty += stat.nr_unqueued_dirty;
 	sc->nr.writeback += stat.nr_writeback;
 	sc->nr.immediate += stat.nr_immediate;
 	sc->nr.taken += nr_taken;
 	if (file)
 		sc->nr.file_taken += nr_taken;
 
 	trace_mm_vmscan_lru_shrink_inactive(pgdat->node_id,
 			nr_scanned, nr_reclaimed, &stat, sc->priority, file);
 	return nr_reclaimed;
 }

-
--[[linux-5.15/trace_mm_vmscan_lru_shrink_inactive()]]


*コメント [#ya3f37e6]

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS