From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (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 0B19933A70E for ; Tue, 16 Jun 2026 13:40:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781617218; cv=none; b=mZCUoFMjEuoXgjygkGLQ4NDIC79/Btb9Y0qTbj3KOAkZzOm2OqOPjlDKQRjRMGZ/rCJaLR3XvreC0z/SIAB1H7oyZeRH1sGqIA9TFoV9tT7zB421IPqASql5QVPk61fV3HT66b5Oo6dUdQ7S2uZAktjh59EvyuUgqO2uou3kyKQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781617218; c=relaxed/simple; bh=IjrWZLt+6c2GUao89RH/uES/lGNQShLO7756+ao9/DQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=QfE53L0ibocsq/d+6BBmYZzDZPxPSeY0SDcJuKqwbJ7DyA2+VprmKrZVxCjWwab8Jbg9Sf6g3xQhwAm5+lgMqPWcMaHEXEhaHiP3jvZcKldKHdnLtsH3LEU9By7+ml/WSPUEaM9Yv0CnqxJG3xVKnBaSpt8d/WVdNQIk3/tu2vg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--praan.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=ceuacCKs; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--praan.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ceuacCKs" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-36bd4146cb2so5051763a91.1 for ; Tue, 16 Jun 2026 06:40:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1781617216; x=1782222016; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=MG2zhbOg35+KcFmkxQ6aYGhkiBRRwQXPY2Of4EsggbA=; b=ceuacCKsPxAjBnOFv6tFkpdeulUyegsgjNTlyBulqOd1U6mVNAk6j5KL8rmUwZawU9 PHGYiUAI/uifTmefLOTrZeSoZkstDH+CtKzx8t9zU5TLm91IJqzbkt2RMsibnQ+sYNxL Bj7tIq0i1s20fAlAEwRTt2prM82euFLpkuXm7HIdJxdYYKFANsYqsolrlrASzOuzdPC8 wYsCRL2BY9FZUnKAG0swvNh4QP+ibbgVO0Zk8ZeeLH1QI1j1OBJia7irnQKGsISkK1x/ Khq/P9WGcmYah7mOv+jjiPKIrnkri32/Ju/DXKosqWWpEok57fV5cQoOXlGAMnLsFM/0 i5qQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781617216; x=1782222016; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=MG2zhbOg35+KcFmkxQ6aYGhkiBRRwQXPY2Of4EsggbA=; b=Lofl2guTaJjamm4CcOHgWV9ghYvdMJUdsYStas+0xP/x4zqiYTlHR5NqUJSTZQjDHl tT4Z7Gr1YcJ2kbduFv3kLVHtHlCOSHftaJKmhQHzZ+RFm49ZW2Uo0i65hEcEW158nZGG hIM1fStrZtMvyUwyGdCvA18dOLQ8ApxhL3+YWuhkTzxQoxmIku6v5kDQPU3PTa79FTp3 dVlQ8JMqAOimziIpTCtX/56Nv3VhNWF8nUPw6jZcIN6HGhdu5RiY2PUeP9NY3nI47ESV lflMBph9zt0warlO039z+T8cYTphYtoEEMqAvar1lIxyO6llNDYFsNH2cCz7WxtI7kVB lJtQ== X-Forwarded-Encrypted: i=1; AFNElJ8SjxGtRTkHklii2/rHTC530bNY0fcBAjVH+htea0DdfdHyNE/BbEyXWpA++/mwMIGklIH7Vg1IXuoQuUE=@vger.kernel.org X-Gm-Message-State: AOJu0YwtE9zDP7ANZJiFqnJ177hiRGu9Ow4pjJ5mJNIjU2kIrqVtxPtj c4MsjiMIlzLt6tAX5v8JJ3PZ8qRGvkBUXlaYvKqarVX/8n8RSWv43R7DNJxyOsK4U+V+VzQQl7n IPA== X-Received: from pgbcz8.prod.google.com ([2002:a05:6a02:2308:b0:c85:b213:8d9d]) (user=praan job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:2f0e:b0:368:864:62ad with SMTP id 98e67ed59e1d1-37c52336492mr3374252a91.3.1781617215938; Tue, 16 Jun 2026 06:40:15 -0700 (PDT) Date: Tue, 16 Jun 2026 13:39:59 +0000 In-Reply-To: <20260616134000.2733403-1-praan@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260616134000.2733403-1-praan@google.com> X-Mailer: git-send-email 2.54.0.1136.gdb2ca164c4-goog Message-ID: <20260616134000.2733403-7-praan@google.com> Subject: [PATCH v2 6/7] nfs: Optimize direct I/O to use folios for requests From: Pranjal Shrivastava To: linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Trond Myklebust , Anna Schumaker , Christoph Hellwig , Christoph Hellwig , Shivaji Kant , Pranjal Shrivastava Content-Type: text/plain; charset="UTF-8" Optimize nfs_direct_extract_pages() to group contiguous pages from the same folio into single nfs_page structures. This effectively migrates NFS Direct I/O from being page-based to being folio-based. Reduce the number of nfs_page allocations and subsequent iterations by utilizing nfs_page_create_from_folio() to create aggregated requests. Signed-off-by: Pranjal Shrivastava --- fs/nfs/direct.c | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index e2a93cfb6c72..ddc6b27f5315 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -194,23 +194,45 @@ static ssize_t nfs_direct_extract_pages(struct nfs_direct_req *dreq, return result; npages = (result + pgbase + PAGE_SIZE - 1) >> PAGE_SHIFT; - for (i = 0; i < npages; i++) { + for (i = 0; i < npages; ) { + unsigned int chunk_len, folio_offset; + unsigned int nr_to_add = 1; struct nfs_page *req; - unsigned int req_len = min_t(size_t, result - bytes, PAGE_SIZE - pgbase); + struct folio *folio; - req = nfs_page_create_from_page(dreq->ctx, pagevec[i], - pinned, pgbase, *pos, - req_len); + folio = page_folio(pagevec[i]); + folio_offset = (folio_page_idx(folio, pagevec[i]) << PAGE_SHIFT) + pgbase; + chunk_len = min_t(size_t, result - bytes, PAGE_SIZE - pgbase); + + while (i + nr_to_add < npages) { + struct page *next_page = pagevec[i + nr_to_add]; + struct page *prev_page = pagevec[i + nr_to_add - 1]; + + if (page_folio(next_page) != folio || + next_page != prev_page + 1) + break; + + chunk_len += min_t(size_t, result - bytes - chunk_len, PAGE_SIZE); + nr_to_add++; + } + + req = nfs_page_create_from_folio(dreq->ctx, folio, + pinned, folio_offset, + chunk_len); if (IS_ERR(req)) { if (!bytes) bytes = PTR_ERR(req); break; } + req->wb_index = *pos >> PAGE_SHIFT; + req->wb_offset = offset_in_page(*pos); + list_add_tail(&req->wb_list, list); pgbase = 0; - bytes += req_len; - *pos += req_len; + bytes += chunk_len; + *pos += chunk_len; + i += nr_to_add; } if (i < npages) { @@ -403,9 +425,9 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq, if (result < 0) break; - requested_bytes += result; while (!list_empty(&nfs_page_list)) { struct nfs_page *req = nfs_list_entry(nfs_page_list.next); + size_t req_len = req->wb_bytes; nfs_list_remove_request(req); if (!nfs_pageio_add_request(&desc, req)) { @@ -414,6 +436,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq, nfs_release_request_list(&nfs_page_list); break; } + requested_bytes += req_len; } if (result < 0) break; @@ -922,19 +945,22 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, if (result < 0) break; - requested_bytes += result; while (!list_empty(&nfs_page_list)) { struct nfs_page *req = nfs_list_entry(nfs_page_list.next); + size_t req_len = req->wb_bytes; nfs_list_remove_request(req); if (defer) { nfs_mark_request_commit(req, NULL, &cinfo, 0); + requested_bytes += req_len; continue; } nfs_lock_request(req); - if (nfs_pageio_add_request(&desc, req)) + if (nfs_pageio_add_request(&desc, req)) { + requested_bytes += req_len; continue; + } /* Exit on hard errors */ if (desc.pg_error < 0 && desc.pg_error != -EAGAIN) { @@ -951,6 +977,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, spin_unlock(&dreq->lock); nfs_unlock_request(req); nfs_mark_request_commit(req, NULL, &cinfo, 0); + requested_bytes += req_len; desc.pg_error = 0; defer = true; } -- 2.54.0.1136.gdb2ca164c4-goog