mm/page_io.c
Source file repositories/reference/linux-study-clean/mm/page_io.c
File Facts
- System
- Linux kernel
- Corpus path
mm/page_io.c- Extension
.c- Size
- 18739 bytes
- Lines
- 717
- Domain
- Core OS
- Bucket
- Memory Management
- Inferred role
- Core OS: implementation source
- Status
- source 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.
- 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/mm.hlinux/kernel_stat.hlinux/gfp.hlinux/pagemap.hlinux/swap.hlinux/bio.hlinux/swapops.hlinux/writeback.hlinux/blkdev.hlinux/psi.hlinux/uio.hlinux/sched/task.hlinux/delayacct.hlinux/zswap.hswap.hswap_table.h
Detected Declarations
struct swap_iocbfunction Copyrightfunction end_swap_bio_writefunction __end_swap_bio_readfunction end_swap_bio_readfunction generic_swapfile_activatefunction is_folio_zero_filledfunction swap_zeromap_folio_setfunction swap_zeromap_folio_clearfunction swap_writeoutfunction count_swpout_vm_eventfunction bio_associate_blkg_from_pagefunction sio_pool_initfunction sio_write_completefunction swap_writepage_fsfunction swap_writepage_bdev_syncfunction swap_writepage_bdev_asyncfunction __swap_writepagefunction swap_write_unplugfunction sio_read_completefunction swap_zeromap_batchfunction swap_read_folio_zeromapfunction swap_read_folio_fsfunction swap_read_folio_bdev_syncfunction swap_read_folio_bdev_asyncfunction swap_read_foliofunction __swap_read_unplug
Annotated Snippet
struct swap_iocb {
struct kiocb iocb;
struct bio_vec bvecs[SWAP_CLUSTER_MAX];
int nr_bvecs;
int len;
};
static mempool_t *sio_pool;
int sio_pool_init(void)
{
if (!sio_pool) {
mempool_t *pool = mempool_create_kmalloc_pool(
SWAP_CLUSTER_MAX, sizeof(struct swap_iocb));
if (cmpxchg(&sio_pool, NULL, pool))
mempool_destroy(pool);
}
if (!sio_pool)
return -ENOMEM;
return 0;
}
static void sio_write_complete(struct kiocb *iocb, long ret)
{
struct swap_iocb *sio = container_of(iocb, struct swap_iocb, iocb);
struct page *page = sio->bvecs[0].bv_page;
int p;
if (ret != sio->len) {
/*
* In the case of swap-over-nfs, this can be a
* temporary failure if the system has limited
* memory for allocating transmit buffers.
* Mark the page dirty and avoid
* folio_rotate_reclaimable but rate-limit the
* messages.
*/
pr_err_ratelimited("Write error %ld on dio swapfile (%llu)\n",
ret, swap_dev_pos(page_swap_entry(page)));
for (p = 0; p < sio->nr_bvecs; p++) {
page = sio->bvecs[p].bv_page;
set_page_dirty(page);
ClearPageReclaim(page);
}
}
for (p = 0; p < sio->nr_bvecs; p++)
end_page_writeback(sio->bvecs[p].bv_page);
mempool_free(sio, sio_pool);
}
static void swap_writepage_fs(struct folio *folio, struct swap_iocb **swap_plug)
{
struct swap_iocb *sio = swap_plug ? *swap_plug : NULL;
struct swap_info_struct *sis = __swap_entry_to_info(folio->swap);
struct file *swap_file = sis->swap_file;
loff_t pos = swap_dev_pos(folio->swap);
count_swpout_vm_event(folio);
folio_start_writeback(folio);
folio_unlock(folio);
if (sio) {
if (sio->iocb.ki_filp != swap_file ||
sio->iocb.ki_pos + sio->len != pos) {
swap_write_unplug(sio);
sio = NULL;
}
}
if (!sio) {
sio = mempool_alloc(sio_pool, GFP_NOIO);
init_sync_kiocb(&sio->iocb, swap_file);
sio->iocb.ki_complete = sio_write_complete;
sio->iocb.ki_pos = pos;
sio->nr_bvecs = 0;
sio->len = 0;
}
bvec_set_folio(&sio->bvecs[sio->nr_bvecs], folio, folio_size(folio), 0);
sio->len += folio_size(folio);
sio->nr_bvecs += 1;
if (sio->nr_bvecs == ARRAY_SIZE(sio->bvecs) || !swap_plug) {
swap_write_unplug(sio);
sio = NULL;
}
if (swap_plug)
*swap_plug = sio;
}
static void swap_writepage_bdev_sync(struct folio *folio,
struct swap_info_struct *sis)
{
Annotation
- Immediate include surface: `linux/mm.h`, `linux/kernel_stat.h`, `linux/gfp.h`, `linux/pagemap.h`, `linux/swap.h`, `linux/bio.h`, `linux/swapops.h`, `linux/writeback.h`.
- Detected declarations: `struct swap_iocb`, `function Copyright`, `function end_swap_bio_write`, `function __end_swap_bio_read`, `function end_swap_bio_read`, `function generic_swapfile_activate`, `function is_folio_zero_filled`, `function swap_zeromap_folio_set`, `function swap_zeromap_folio_clear`, `function swap_writeout`.
- Atlas domain: Core OS / Memory Management.
- 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.