portal_devfs: blocking poll for plugin-backed char devices (fix #77)#78
Merged
Conversation
The devfs poll fop was wired straight to the Python-modeled poll (out->poll = ops->poll) and the driver never called poll_wait(). So a from_plugin char device could not block a poll()/select() reader: a data-aware poll reporting 'not ready' had no wait queue to sleep on, and the legacy always-ready poll made poll()->read() readers busy-loop on 0-byte reads (one core pegged under TCG). Add a per-entry wait queue and route poll/write through proxies: - struct portal_devfs_entry gains poll_wq + python_poll/python_write. - igloo_devfs_proxy_poll() calls poll_wait(file, &pe->poll_wq, pt) then defers the readiness mask to the Python poll (falls back to the legacy always-ready mask if none is modeled). - igloo_devfs_proxy_write() forwards to the Python write then wake_up_interruptible(&pe->poll_wq): a write commonly queues a response on the host side, so a reader blocked in poll() is woken promptly instead of waiting out a poll timeout. - The block queue_rq path calls python_write directly (NULL file), bypassing the char-only write proxy. Pairs with rehosting/penguin#843 (data-aware poll): with both, a from_plugin serial-style device delivers responses to a blocked reader with no idle spin. Note: write_iter is not yet proxied (no wake); add if a backing models it.
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.
Summary
Fixes #77. A
from_plugin-backed/devchar device could not block apoll()/select()reader.igloo_convert_ops_to_fops()wired the devfs poll fopstraight to the Python-modeled poll (
out->poll = ops->poll) and the driver nevercalled
poll_wait(), so there was no wait queue for a "not ready" poll to sleep on:poll()->read()readers busy-loop on 0-bytereads — pinning a core under TCG.
(Companion to rehosting/penguin#843, which adds the data-aware poll on the Python side.
With both, a
from_pluginserial-style device delivers responses to a blocked readerwith no idle spin.)
Change
src/portal/portal_devfs.c:struct portal_devfs_entrygainswait_queue_head_t poll_wqpluspython_poll/python_write(the Python-modeled fops, kept so the proxies can forward to them andthe block path can call them directly).
igloo_devfs_proxy_poll()— recovers the entry viacontainer_of(inode->i_cdev),calls
poll_wait(file, &pe->poll_wq, pt), then defers the readiness mask to thePython poll. Falls back to the legacy always-ready mask when no Python poll is modeled,
so existing always-ready nodes are unchanged.
igloo_devfs_proxy_write()— forwards to the Python write, thenwake_up_interruptible(&pe->poll_wq). A write commonly queues a response on the hostside (request/response serial devices), so a reader blocked in
poll()is wokenpromptly instead of waiting out a poll timeout.
out->poll/out->writeare routed through these proxies; the entry is created withinit_waitqueue_head(&pe->poll_wq)and the captured Python fops.queue_rqpath callspython_writedirectly (it has nostruct file),bypassing the char-only write proxy.
Behavior
pollmodeled → always-ready mask (unchanged from today).poll(returns POLLIN only when data is queued) → a reader blocks inpoll()when idle (no spin) and is woken by the next write that queues a reply.Testing notes
Not yet built in CI from this branch / not runtime-tested in the combo with penguin#843
(no kernel-devel in my working tree). The change mirrors the existing
proxy_releasepattern (same
container_of/forwarding shape and the sameunsigned intpoll signaturethat
out->poll = ops->pollalready used). Reviewers: please confirm the CI module build,and the end-to-end behavior with penguin#843's data-aware poll.
Follow-ups
write_iteris not proxied (no wake) — add if a backing models it.unsolicited data, e.g. modem URCs) would cover the async case; wake-on-write covers
the request/response pattern.