io_uring/poll.c
Source file repositories/reference/linux-study-clean/io_uring/poll.c
File Facts
- System
- Linux kernel
- Corpus path
io_uring/poll.c- Extension
.c- Size
- 26695 bytes
- Lines
- 973
- Domain
- Kernel Services
- Bucket
- io_uring
- Inferred role
- Kernel Services: implementation source
- Status
- source implementation candidate
Why This File Exists
Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/errno.hlinux/fs.hlinux/file.hlinux/mm.hlinux/slab.hlinux/poll.hlinux/hashtable.hlinux/io_uring.htrace/events/io_uring.huapi/linux/io_uring.hio_uring.halloc_cache.hrefs.hnapi.hopdef.hkbuf.hpoll.hcancel.h
Detected Declarations
struct io_poll_updatestruct io_poll_tablefunction wqe_is_doublefunction io_poll_get_ownership_slowpathfunction io_poll_get_ownershipfunction io_poll_mark_cancelledfunction io_poll_req_insertfunction io_init_poll_iocbfunction io_poll_remove_waitqfunction io_poll_remove_entryfunction io_poll_remove_entriesfunction __io_poll_executefunction io_poll_executefunction io_poll_check_eventsfunction io_poll_task_funcfunction io_poll_cancel_reqfunction io_pollfree_wakefunction io_poll_wakefunction io_poll_double_preparefunction io_poll_wakefunction __io_queue_procfunction io_poll_queue_procfunction io_poll_can_finish_inlinefunction io_poll_add_hashfunction __io_arm_poll_handlerfunction io_async_queue_procfunction io_arm_apollfunction io_arm_poll_handlerfunction io_poll_remove_allfunction hlist_for_each_entry_safefunction hlist_for_each_entryfunction hlist_for_each_entryfunction io_poll_disarmfunction __io_poll_cancelfunction io_poll_cancelfunction io_poll_parse_eventsfunction io_poll_remove_prepfunction io_poll_add_prepfunction io_poll_addfunction io_poll_remove
Annotated Snippet
struct io_poll_update {
struct file *file;
u64 old_user_data;
u64 new_user_data;
__poll_t events;
bool update_events;
bool update_user_data;
};
struct io_poll_table {
struct poll_table_struct pt;
struct io_kiocb *req;
int nr_entries;
int error;
bool owning;
/* output value, set only if arm poll returns >0 */
__poll_t result_mask;
};
#define IO_POLL_CANCEL_FLAG BIT(31)
#define IO_POLL_RETRY_FLAG BIT(30)
#define IO_POLL_REF_MASK GENMASK(29, 0)
/*
* We usually have 1-2 refs taken, 128 is more than enough and we want to
* maximise the margin between this amount and the moment when it overflows.
*/
#define IO_POLL_REF_BIAS 128
#define IO_WQE_F_DOUBLE 1
static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
void *key);
static inline struct io_kiocb *wqe_to_req(struct wait_queue_entry *wqe)
{
unsigned long priv = (unsigned long)wqe->private;
return (struct io_kiocb *)(priv & ~IO_WQE_F_DOUBLE);
}
static inline bool wqe_is_double(struct wait_queue_entry *wqe)
{
unsigned long priv = (unsigned long)wqe->private;
return priv & IO_WQE_F_DOUBLE;
}
static bool io_poll_get_ownership_slowpath(struct io_kiocb *req)
{
int v;
/*
* poll_refs are already elevated and we don't have much hope for
* grabbing the ownership. Instead of incrementing set a retry flag
* to notify the loop that there might have been some change.
*/
v = atomic_fetch_or(IO_POLL_RETRY_FLAG, &req->poll_refs);
if (v & IO_POLL_REF_MASK)
return false;
return !(atomic_fetch_inc(&req->poll_refs) & IO_POLL_REF_MASK);
}
/*
* If refs part of ->poll_refs (see IO_POLL_REF_MASK) is 0, it's free. We can
* bump it and acquire ownership. It's disallowed to modify requests while not
* owning it, that prevents from races for enqueueing task_work's and b/w
* arming poll and wakeups.
*/
static inline bool io_poll_get_ownership(struct io_kiocb *req)
{
if (unlikely((unsigned int)atomic_read(&req->poll_refs) >= IO_POLL_REF_BIAS))
return io_poll_get_ownership_slowpath(req);
return !(atomic_fetch_inc(&req->poll_refs) & IO_POLL_REF_MASK);
}
static void io_poll_mark_cancelled(struct io_kiocb *req)
{
atomic_or(IO_POLL_CANCEL_FLAG, &req->poll_refs);
}
static struct io_poll *io_poll_get_double(struct io_kiocb *req)
{
/* pure poll stashes this in ->async_data, poll driven retry elsewhere */
if (req->opcode == IORING_OP_POLL_ADD)
return req->async_data;
return req->apoll->double_poll;
}
static struct io_poll *io_poll_get_single(struct io_kiocb *req)
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/errno.h`, `linux/fs.h`, `linux/file.h`, `linux/mm.h`, `linux/slab.h`, `linux/poll.h`, `linux/hashtable.h`.
- Detected declarations: `struct io_poll_update`, `struct io_poll_table`, `function wqe_is_double`, `function io_poll_get_ownership_slowpath`, `function io_poll_get_ownership`, `function io_poll_mark_cancelled`, `function io_poll_req_insert`, `function io_init_poll_iocb`, `function io_poll_remove_waitq`, `function io_poll_remove_entry`.
- Atlas domain: Kernel Services / io_uring.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.