kernel/watch_queue.c
Source file repositories/reference/linux-study-clean/kernel/watch_queue.c
File Facts
- System
- Linux kernel
- Corpus path
kernel/watch_queue.c- Extension
.c- Size
- 17893 bytes
- Lines
- 707
- Domain
- Core OS
- Bucket
- Scheduler, Processes, Timers, Sync, And Syscalls
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/module.hlinux/init.hlinux/sched.hlinux/slab.hlinux/printk.hlinux/miscdevice.hlinux/fs.hlinux/mm.hlinux/pagemap.hlinux/poll.hlinux/uaccess.hlinux/vmalloc.hlinux/file.hlinux/security.hlinux/cred.hlinux/sched/signal.hlinux/watch_queue.hlinux/pipe_fs_i.h
Detected Declarations
function lock_wqueuefunction unlock_wqueuefunction watch_queue_pipe_buf_releasefunction post_one_notificationfunction filter_watch_notificationfunction hlist_for_each_entry_rcufunction watch_queue_set_sizefunction watch_queue_set_filterfunction __put_watch_queuefunction put_watch_queuefunction free_watchfunction __put_watchfunction put_watchfunction init_watchfunction add_one_watchfunction hlist_for_each_entryfunction add_watch_to_objectfunction remove_watch_from_objectfunction watch_queue_clearfunction watch_queue_initexport __post_watch_notificationexport put_watch_queueexport add_watch_to_objectexport remove_watch_from_objectexport get_watch_queue
Annotated Snippet
if (lock_wqueue(wqueue)) {
post_one_notification(wqueue, n);
unlock_wqueue(wqueue);
}
}
rcu_read_unlock();
}
EXPORT_SYMBOL(__post_watch_notification);
/*
* Allocate sufficient pages to preallocation for the requested number of
* notifications.
*/
long watch_queue_set_size(struct pipe_inode_info *pipe, unsigned int nr_notes)
{
struct watch_queue *wqueue = pipe->watch_queue;
struct page **pages;
unsigned long *bitmap;
unsigned long user_bufs;
int ret, i, nr_pages;
if (!wqueue)
return -ENODEV;
if (wqueue->notes)
return -EBUSY;
if (nr_notes < 1 ||
nr_notes > 512) /* TODO: choose a better hard limit */
return -EINVAL;
nr_pages = (nr_notes + WATCH_QUEUE_NOTES_PER_PAGE - 1);
nr_pages /= WATCH_QUEUE_NOTES_PER_PAGE;
user_bufs = account_pipe_buffers(pipe->user, pipe->nr_accounted, nr_pages);
if (nr_pages > pipe->max_usage &&
(too_many_pipe_buffers_hard(user_bufs) ||
too_many_pipe_buffers_soft(user_bufs)) &&
pipe_is_unprivileged_user()) {
ret = -EPERM;
goto error;
}
nr_notes = nr_pages * WATCH_QUEUE_NOTES_PER_PAGE;
ret = pipe_resize_ring(pipe, roundup_pow_of_two(nr_notes));
if (ret < 0)
goto error;
/*
* pipe_resize_ring() does not update nr_accounted for watch_queue
* pipes, because the above vastly overprovisions. Set nr_accounted on
* and max_usage this pipe to the number that was actually charged to
* the user above via account_pipe_buffers.
*/
pipe->max_usage = nr_pages;
pipe->nr_accounted = nr_pages;
ret = -ENOMEM;
pages = kzalloc_objs(struct page *, nr_pages);
if (!pages)
goto error;
for (i = 0; i < nr_pages; i++) {
pages[i] = alloc_page(GFP_KERNEL);
if (!pages[i])
goto error_p;
pages[i]->private = i * WATCH_QUEUE_NOTES_PER_PAGE;
}
bitmap = bitmap_alloc(nr_notes, GFP_KERNEL);
if (!bitmap)
goto error_p;
bitmap_fill(bitmap, nr_notes);
wqueue->notes = pages;
wqueue->notes_bitmap = bitmap;
wqueue->nr_pages = nr_pages;
wqueue->nr_notes = nr_notes;
return 0;
error_p:
while (--i >= 0)
__free_page(pages[i]);
kfree(pages);
error:
(void) account_pipe_buffers(pipe->user, nr_pages, pipe->nr_accounted);
return ret;
}
/*
Annotation
- Immediate include surface: `linux/module.h`, `linux/init.h`, `linux/sched.h`, `linux/slab.h`, `linux/printk.h`, `linux/miscdevice.h`, `linux/fs.h`, `linux/mm.h`.
- Detected declarations: `function lock_wqueue`, `function unlock_wqueue`, `function watch_queue_pipe_buf_release`, `function post_one_notification`, `function filter_watch_notification`, `function hlist_for_each_entry_rcu`, `function watch_queue_set_size`, `function watch_queue_set_filter`, `function __put_watch_queue`, `function put_watch_queue`.
- Atlas domain: Core OS / Scheduler, Processes, Timers, Sync, And Syscalls.
- Implementation status: integration implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.