Drop the WQ_MEM_RECLAIM flag from the zswap global shrinker workqueue to resolve resource contention with actual kernel memory reclaim. The current zswap global shrinker and its writeback contend with acutual memory reclaim, leading to system responsiveness issues when the zswap writeback and direct reclaim run concurrently. Unlike kernel memory shrinkers, the global shrinker works in the background behind the zswap pool, which acts as a large in-memory buffer. The zswap writeback is not urgent and is not strictly necessary to reclaim kernel memory. Even when zswap shrinker cannot evict pages, zswap_store() can reject reclaimed pages, and the rejected pages have swap space preallocated. Delaying writeback or shrinker progress do not interfere page reclaim. The visible issue in the current implementation occurs when a large amount of direct reclaim happens and zswap cannot store the incoming pages. Both the zswap global shrinker and the memory reclaimer start writing back pages concurrently. This leads the entire system responsivility issue that does not occur without zswap. The shrink_worker() running on WQ_MEM_RECLAIM blocks other important works required for memory reclamation. In this case, swp_writepage() and zswap_writeback() are consuming time and contend with each other for workqueue scheduling and I/O resources, especially on slow swap devices. Note that this issue has been masked by the global shrinker failing to evict a considerable number of pages. This patch is required to fix the shrinker to continuously reduce the pool size to the acceptable threshold. The probability of this issue can be mitigated mostly by removing the WQ_MEM_RECLAIM flag from the zswap shrinker workqueue. With this change, the invocation of shrink_worker() and its writeback will be delayed while reclamation is running on WQ_MEM_RECLAIM workqueue. Signed-off-by: Takero Funaki <flintglass@xxxxxxxxx> --- mm/zswap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/zswap.c b/mm/zswap.c index 24acbab44e7a..76691ca7b6a7 100644 --- a/mm/zswap.c +++ b/mm/zswap.c @@ -1806,7 +1806,7 @@ static int zswap_setup(void) goto hp_fail; shrink_wq = alloc_workqueue("zswap-shrink", - WQ_UNBOUND|WQ_MEM_RECLAIM, 1); + WQ_UNBOUND, 1); if (!shrink_wq) goto shrink_wq_fail; -- 2.43.0