From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.223.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2B67C3E556C for ; Mon, 20 Jul 2026 14:29:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=195.135.223.130 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784557763; cv=none; b=XXE0AqB9xsI2UyfNbzNxz6c6brFDk3JFMnttme7QcOBoJe901f1foOqNwHvOgWFNxSbYb0w51J8iBAs1dm77Ca3yEn+ROB+QLrhLv1geZHdhMYYxmy6l9lxOKuohtmFb9hgCjfNWMJwVq20TBsukR8i5UvjYcAz/vN0gOz9y9HQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784557763; c=relaxed/simple; bh=gyvSiIGuRLHd6UDTi0IQLcFYLN1XH4/td0kN6u5KqKQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=h2YOAxvcZ0gT4MtbootGfdEW1Dn5e/G3w7Smek2clwqasl0HFquLA0chDhCF20wIQwR2GjE9oQTzwhgHEpAMhJCFc5pXh72pg0UtBJraTE/M3uTLQuuR4GhR0mwrPGO7tU/ra9DqTNdR/YB5AviZTcEE3WvCHzVMf9sjBlYMrI8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=suse.de; spf=pass smtp.mailfrom=suse.de; arc=none smtp.client-ip=195.135.223.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=suse.de Received: from imap1.dmz-prg2.suse.org (imap1.dmz-prg2.suse.org [IPv6:2a07:de40:b281:104:10:150:64:97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 5229D79FCB; Mon, 20 Jul 2026 14:29:19 +0000 (UTC) Authentication-Results: smtp-out1.suse.de; none Received: from imap1.dmz-prg2.suse.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id 4B27D779AA; Mon, 20 Jul 2026 14:29:18 +0000 (UTC) Received: from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167]) by imap1.dmz-prg2.suse.org with ESMTPSA id wC8BD74wXmrKTQAAD6G6ig (envelope-from ); Mon, 20 Jul 2026 14:29:18 +0000 From: Pedro Falcato To: Andrew Morton , David Hildenbrand , Lorenzo Stoakes Cc: Pedro Falcato , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Barry Song , Lance Yang , Usama Arif , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/8] mm/khugepaged: factor out page cache folio reading Date: Mon, 20 Jul 2026 15:29:07 +0100 Message-ID: <20260720142913.846902-3-pfalcato@suse.de> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260720142913.846902-1-pfalcato@suse.de> References: <20260720142913.846902-1-pfalcato@suse.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Rspamd-Pre-Result: action=no action; module=replies; Message is reply to one we originated X-Rspamd-Queue-Id: 5229D79FCB X-Spam-Flag: NO X-Spam-Score: -4.00 X-Spam-Level: X-Rspamd-Action: no action X-Rspamd-Server: rspamd1.dmz-prg2.suse.org X-Rspamd-Pre-Result: action=no action; module=replies; Message is reply to one we originated X-Spamd-Result: default: False [-4.00 / 50.00]; REPLY(-4.00)[] The two mechanisms (shmem, filemap) are quite similar and only change in subtleties. There is no need to have two variants. Factor this out into its own separate function, shared by both paths. Signed-off-by: Pedro Falcato --- mm/khugepaged.c | 67 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/mm/khugepaged.c b/mm/khugepaged.c index d4de507ac001..4cc6917a55c7 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -2230,42 +2230,63 @@ struct collapse_file_state { unsigned int is_shmem : 1; }; +static struct folio *collapse_read_folio(pgoff_t index, struct collapse_file_state *state) +{ + const bool may_bring_uptodate = state->is_shmem; + struct folio *folio = state->folio; + + if (!folio || xa_is_value(folio) || + (may_bring_uptodate && !folio_test_uptodate(folio))) { + xas_unlock_irq(state->xas); + if (state->is_shmem) { + /* swap in or instantiate fallocated page */ + if (shmem_get_folio(state->mapping->host, index, 0, + &folio, SGP_NOALLOC)) + return NULL; + } else { + page_cache_sync_readahead(state->mapping, &state->file->f_ra, + state->file, index, + state->end - index); + folio = filemap_lock_folio(state->mapping, index); + if (IS_ERR(folio)) + return NULL; + } + } + + return folio; +} + static enum scan_result prepare_collapse_file_folio(pgoff_t index, struct collapse_file_state *state) { struct address_space *mapping = state->mapping; enum scan_result result = SCAN_SUCCEED; const int is_shmem = state->is_shmem; - struct folio *folio = state->folio; + struct folio *folio; + + folio = collapse_read_folio(index, state); + if (!folio) + return SCAN_FAIL; + if (folio != state->folio) { + /* + * collapse_read_folio() got a new folio. This folio is locked + * and ref'd up. Nothing tricky (dirty, writeback, etc) can + * happen, so bail now. But before that, drain the local LRU + * add batch. Otherwise, it's very possible folio_isolate_lru() + * will not succeed. + */ + lru_add_drain(); + goto xa_unlocked; + } if (is_shmem) { - if (xa_is_value(folio) || !folio_test_uptodate(folio)) { - xas_unlock_irq(state->xas); - /* swap in or instantiate fallocated page */ - if (shmem_get_folio(mapping->host, index, 0, - &folio, SGP_NOALLOC)) - result = SCAN_FAIL; - /* drain lru cache to help folio_isolate_lru() */ - lru_add_drain(); - goto xa_unlocked; - } else if (folio_trylock(folio)) { + if (folio_trylock(folio)) { folio_get(folio); } else { result = SCAN_PAGE_LOCK; goto xa_locked; } } else { /* !is_shmem */ - if (!folio || xa_is_value(folio)) { - xas_unlock_irq(state->xas); - page_cache_sync_readahead(mapping, &state->file->f_ra, - state->file, index, - state->end - index); - /* drain lru cache to help folio_isolate_lru() */ - lru_add_drain(); - folio = filemap_lock_folio(mapping, index); - if (IS_ERR(folio)) - result = SCAN_FAIL; - goto xa_unlocked; - } else if (folio_test_dirty(folio)) { + if (folio_test_dirty(folio)) { /* * This page is dirty because it hasn't * been flushed since first write. -- 2.55.0