Redfs ubuntu HWE improve writeback performance#184
Open
hbirth wants to merge 7 commits into
Open
Conversation
Signed-off-by: Horst Birthelmer <horst@birthelmer.de>
Writes that already match the alignment advertised via FUSE_ALIGN_PG_ORDER gain nothing from the writeback cache and can degrade into page-sized WRITE requests under dirty throttling. Send them through fuse_perform_write() instead, which packs requests up to max_write and keeps them stripe-aligned for the backend. They create no dirty pages, so no DLM write lock needs to be cached for them. Unaligned writes keep using the writeback cache. Also clarify in the uapi header that align_page_order is the log2 of the alignment in bytes, not in pages. Ported from the redfs-ubuntu-noble-writethrough-split branch and adapted to the iomap-based writeback path: the decision gates the writeback bool in fuse_cache_write_iter() (and the DLM write-lock acquisition) instead of branching to a writethrough label. Signed-off-by: Horst Birthelmer <horst@birthelmer.de>
Add a per-connection size threshold, settable via fusectl as writethrough_threshold, that sends buffered writes >= threshold through fuse_perform_write() regardless of alignment. The knob is off by default (0 == disabled) and leaves the existing alignment-based decision in place for writes below the threshold. Ported from the redfs-ubuntu-noble-writethrough-split branch; the fusectl dentry uses this branch's fuse_ctl_add_dentry() signature and the ops struct omits the now-removed no_llseek. Signed-off-by: Horst Birthelmer <horst@birthelmer.de>
fuse_readahead() batches whole folios into a single request, capped at min(fc->max_pages, fc->max_read/PAGE_SIZE) pages, but fuse_init_file_inode() let the page cache build folios up to MAX_PAGECACHE_ORDER. A large sequential read could thus produce a folio bigger than one request can carry: the first loop iteration took the folio_pages > cur_pages path, fired WARN_ON(!pages), and broke with ap->num_folios == 0. fuse_send_readpages() was still called and dereferenced a NULL ap->folios[0] via folio_pos(), oopsing at CR2=0x20 (folio->index). Cap the folio order to the per-request page limit so the page cache can never build an unserviceable folio. Signed-off-by: Horst Birthelmer <hbirthelmer@ddn.com>
Buffered writes hold the inode lock exclusively, serialising all writers even on disjoint ranges. When fc->dlm is set and the write goes through iomap writeback, the DLM already serialises cluster-wide, so the inode rwsem only needs to keep i_size stable. Add fuse_cache_wr_exclusive_lock() to detect this and take the lock shared, letting disjoint writers run in parallel (MPI-IO / IOR). Direct, appending, or i_size-extending writes still take it exclusive; re-check past-EOF under the shared lock and escalate if needed. Signed-off-by: Horst Birthelmer <hbirthelmer@ddn.com>
A FUSE server that advertises a large max_pages and max_write (e.g. max_pages=256, max_write=1MB) cannot currently obtain matching FUSE_READ request sizes from the kernel. Buffered sequential writes arrive at the server at the negotiated max_write size, but a large buffered read() is split into several smaller FUSE_READ requests. For a buffered read, filemap_get_pages() -> page_cache_sync_ra() sizes the read against ractl_max_pages(): max_pages = ractl->ra->ra_pages; if (req_size > max_pages && bdi->io_pages > max_pages) max_pages = min(req_size, bdi->io_pages); fuse leaves bdi->io_pages at the default VM_READAHEAD_PAGES (128KB), so a 1MB read() (req_size = 256 pages) is clamped to the readahead window (128KB, or 256KB for POSIX_FADV_SEQUENTIAL), producing four 256KB FUSE_READ round-trips instead of one. Set bdi->io_pages to fc->max_pages after feature negotiation. As the code above shows, io_pages only raises the limit when the request size already exceeds the readahead window, so it enlarges explicitly requested reads without enlarging the speculative readahead window. This avoids increasing speculative page-cache readahead on behalf of an unprivileged server. NFS does the same, setting io_pages from rpages while leaving ra_pages at the default. fc->max_pages is already bounded by fc->max_pages_limit (and, for virtio-fs, by the virtqueue descriptor count), so io_pages inherits the same bound. Suggested-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Jim Harris <jim.harris@nvidia.com> Assisted-by: Cursor:claude-opus-4.8
commit 0c58a97 ("fuse: remove tmp folio for writebacks and internal rb tree") removed temp folios for dirty page writeback. Consequently, fuse can now use the default writeback accounting. With switching fuse to use default writeback accounting, there are some added benefits. This updates wb->writeback_inodes tracking as well now and updates writeback throughput estimates after writeback completion. This commit also removes inc_wb_stat() and dec_wb_stat(). These have no callers anymore now that fuse does not call them. Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Reviewed-by: David Hildenbrand <david@redhat.com> Reviewed-by: Bernd Schubert <bschubert@ddn.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> (cherry picked from commit 494d2f5)
9757e36 to
98adf72
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.