Repository navigation
Backport #36 to 6.18-lts: 9p/xen: reconnect to the backend on resume - #37
Merged
Merged
Conversation
A request that does not fit in its ring sleeps in io_wait_event_killable() until the backend frees space, but the event handler wakes the ring with wake_up_interruptible(), which only wakes TASK_INTERRUPTIBLE sleepers. A TASK_KILLABLE waiter therefore sleeps until it is killed, which hangs a guest that has enough large requests in flight to fill a ring. Wake the ring with wake_up() so killable waiters see the freed space. Fixes: 9523fea ("net/9p: Switch to wait_event_killable()") Signed-off-by: Alex Zenla <alex@edera.dev> (cherry picked from commit 902d221)
The frontend's resume handler only warned that suspend and resume are unsupported. After a restore its rings, grant references and event channels are gone, yet the mounted client kept writing requests into them, so every request on the mount hung. The next InitWait from the backend then allocated a second frontend instance for the same device, which no client used. On resume, collect any replies the backend left in the rings, free the rings, fail the requests that are still unanswered with -EIO, and publish Initialising so that a backend which still serves the old rings starts over. When the backend reaches InitWait, allocate and publish new rings for the existing frontend, keeping its clients. Requests that arrive while the frontend is not connected wait until it is, and a rw_semaphore keeps them off the rings while a resume replaces them. Signed-off-by: Alex Zenla <alex@edera.dev> (cherry picked from commit 9a1668b)
A forked, restored or imported domain resumes against a new backend whose fid table is empty, while the guest's 9P clients still hold the fids of the session they were suspended with. With the transport reconnected every request on those fids still fails, so even an idle mount comes back unusable. When the backend advertises feature-session-transfer, wait at suspend for the requests in flight to be answered, then ask the backend for its fid table with Tsession_save and keep the pages in guest memory, where they survive into whatever domain the guest resumes in. Once a restored frontend's new backend connects, replay the pages with Tsession_restore before any request can use the rings. The pages are opaque to the frontend; the backend validates every entry as it would a walk or open. Signed-off-by: Alex Zenla <alex@edera.dev> (cherry picked from commit e271536)
The toolstack has to know whether a guest can carry its 9P session into a new backend before it exports the domain, because a guest that cannot comes back with every open file on its mounts unusable. Until now only the backend advertised the feature, and the frontend's support was invisible from dom0. Publish feature-session-transfer = 1 in the frontend's own xenstore directory, next to version and num-rings. Signed-off-by: Alex Zenla <alex@edera.dev> (cherry picked from commit 97d826b)
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.
Backport of #36 from
edera/mainlinetoedera/6.18-lts(750906adddc6), prepared by Claude. Run log.Warning
Merge with Rebase and merge, so
edera/6.18-ltsstays linear.Independent checks
Builds: success (x86_64 and arm64 vmlinux with the Edera features built in).
750906adddc6bd6704b0b89f0a28a6fc9ca3 9p/xen: reconnect to the backend on resume9a1668bd2e37 9p/xen: reconnect to the backend on resumeAdapted commits (source +/- lines vs. backport)
Claude's report
Summary
All 4 requested commits from #36 are backported in order with
-xtrailers and unchanged subjects. Three apply unchanged: "wake ring-space waiters with wake_up()", "carry the 9P session across a restore" and "advertise session transfer to the toolstack". One commit, "reconnect to the backend on resume", is adapted because 6.18 lacks three upstream changes the mainline diff touches. None are left out.verify-backport.shreports 3 unchanged and 1 adapted, which is expected. The adaptation is explained below. Mainline's merge re-committed the PR's commits (d9dc03ab10e7,6a7cd40129aa,177888523fdf,9aa35aecaab1in PENDING).git range-diffshows them identical to the requested PR-branch commits, so nothing else in PENDING is needed.Needs a decision
UNSURE: "9p/xen: reconnect to the backend on resume" calls
xen_9pfs_front_free_rings()more than once on the same rings: on resume, again on remove or on a failed reconnect, and the rings are allocated again in between. Mainline relies on upstream72cb9ee4f6d8("9p/trans_xen: make cleanup idempotent after dataring alloc errors"), which 6.18 does not have. There are two ways to handle this:free_ringskeeps 6.18's teardown and only setspriv->rings[i].intf = NULLafter freeing each ring. A second call then stops at the first ring, as mainline's would. This is what I committed. What remains is the old 6.18 bug that72cb9ee4f6d8fixes:xen_9pfs_front_alloc_dataring()freesintfon failure but leaves the pointer set. If allocating a ring fails partway, the cleanup that follows will end the grants and free that ring's page a second time. This already happens on 6.18's first-connect (front_init) error path. With this backport the newfront_reconnecterror path can hit it too.72cb9ee4f6d8to 6.18 first, as its own upstream-stable fix outside this PR. The reconnect commit'sfree_ringscould then match mainline line for line.If option 2 is preferred, take
72cb9ee4f6d8into 6.18 first, then re-run this backport.Adapted commits
9a1668bd2e37)p9_xen_request(): mainline usesio_wait_event_killable(), which comes from upstream51ffeabe836b("9p: Track 9P RPC waiting time as IO") and is not in 6.18. I kept 6.18'swait_event_killable()and added the commit's new!READ_ONCE(priv->connected) ||condition, so the behaviour on a disconnect is the same.xen_9pfs_front_free()split intoxen_9pfs_front_free_rings(): mainline moves a teardown body that already has the idempotent changes from upstream72cb9ee4f6d8. I moved 6.18's own body instead: thepriv->rings[i]style, theirq > 0check and the unconditional grant release. I added one line,priv->rings[i].intf = NULL, so that callingfree_ringsagain after a resume is safe. See Needs a decision.xen_9pfs_front_init(): kept 6.18'skcalloc()instead of mainline'skzalloc_objs(), which 6.18 lacks. Kept 6.18'sversionsparsing; mainline's version comes from upstream8fc518e489c1. The commit's newring_orderandinit_rwsem()lines are added unchanged.e271536038f6): the checker shows it as unchanged, but two conflicts were in context lines only. The mainline-only#include <linux/fs_context.h>context line is dropped, and the newdelay.handunaligned.hincludes are added. The newINIT_LIST_HEAD/init_completionlines are placed before 6.18'skcalloc(). Everything the commit uses exists on 6.18:xenbus_driver.suspend,P9_HDRSZ,P9_NOTAG,P9_RLERROR,p9_req_try_getandlinux/unaligned.h.Left out
None.
Builds
BUILDS_PENDING