Re: [PATCH 1/5] mm/vmscan: Throttle reclaim until some writeback completes if congested
From: Hillf Danton <hidden>
Date: 2021-09-22 12:16:39
On Mon, 20 Sep 2021 09:54:32 +0100 Mel Gorman wrote:
+static void
+reclaim_throttle(pg_data_t *pgdat, enum vmscan_throttle_state reason,
+ long timeout)
+{
+ wait_queue_head_t *wqh =3D &pgdat->reclaim_wait;
+ unsigned long start =3D jiffies;
+ long ret;
+ DEFINE_WAIT(wait);
+
+ atomic_inc(&pgdat->nr_reclaim_throttled);
+ WRITE_ONCE(pgdat->nr_reclaim_start,
+ node_page_state(pgdat, NR_THROTTLED_WRITTEN));Missing wakeup could happen if the current sleeper overwrites pgdat->nr_reclaim_start set by the existing sleeper. if (1 == atomic_inc_and_return(&pgdat->nr_reclaim_throttled)) WRITE_ONCE(pgdat->nr_reclaim_start, node_page_state(pgdat, NR_THROTTLED_WRITTEN));
+
+ prepare_to_wait(wqh, &wait, TASK_INTERRUPTIBLE);
+ ret =3D schedule_timeout(timeout);
+ finish_wait(wqh, &wait);
+ atomic_dec(&pgdat->nr_reclaim_throttled);
+
+ trace_mm_vmscan_throttled(pgdat->node_id, jiffies_to_usecs(timeout),
+ jiffies_to_usecs(jiffies - start),
+ reason);
+}
+
+/*
+ * Account for pages written if tasks are throttled waiting on dirty
+ * pages to clean. If enough pages have been cleaned since throttling
+ * started then wakeup the throttled tasks.
+ */
+void __acct_reclaim_writeback(pg_data_t *pgdat, struct page *page)
+{
+ unsigned long nr_written;
+ int nr_throttled =3D atomic_read(&pgdat->nr_reclaim_throttled);
+
+ __inc_node_page_state(page, NR_THROTTLED_WRITTEN);
+ nr_written =3D node_page_state(pgdat, NR_THROTTLED_WRITTEN) -
+ READ_ONCE(pgdat->nr_reclaim_start);
+
+ if (nr_written > SWAP_CLUSTER_MAX * nr_throttled)
+ wake_up_interruptible_all(&pgdat->reclaim_wait);
+}