mm/highmem.c
Source file repositories/reference/linux-study-clean/mm/highmem.c
File Facts
- System
- Linux kernel
- Corpus path
mm/highmem.c- Extension
.c- Size
- 20857 bytes
- Lines
- 827
- Domain
- Core OS
- Bucket
- Memory Management
- 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.
- 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/export.hlinux/swap.hlinux/bio.hlinux/pagemap.hlinux/mempool.hlinux/init.hlinux/hash.hlinux/highmem.hlinux/kgdb.hasm/tlbflush.hlinux/vmalloc.hasm/kmap_size.h
Detected Declarations
struct page_address_mapfunction Copyrightfunction arefunction get_next_pkmap_nrfunction regionfunction get_pkmap_entries_countfunction __nr_free_highpagesfunction for_each_populated_zonefunction __totalhigh_pagesfunction for_each_populated_zonefunction flush_all_zero_pkmapsfunction __kmap_flush_unusedfunction map_new_virtualfunction kunmap_highfunction kunmap_highfunction zero_user_segmentsfunction kmap_local_idx_pushfunction kmap_local_idxfunction kmap_local_idx_popfunction kmap_high_unmap_localfunction kunmap_local_indexedfunction switch_tofunction __kmap_local_sched_infunction kmap_local_forkfunction list_for_each_entryfunction set_page_addressfunction list_for_each_entryfunction page_address_initexport __totalhigh_pagesexport __kmap_to_pageexport kmap_highexport kunmap_highexport zero_user_segmentsexport __kmap_local_pfn_protexport __kmap_local_page_protexport kunmap_local_indexedexport page_address
Annotated Snippet
struct page_address_map {
struct page *page;
void *virtual;
struct list_head list;
};
static struct page_address_map page_address_maps[LAST_PKMAP];
/*
* Hash table bucket
*/
static struct page_address_slot {
struct list_head lh; /* List of page_address_maps */
spinlock_t lock; /* Protect this bucket's list */
} ____cacheline_aligned_in_smp page_address_htable[1<<PA_HASH_ORDER];
static struct page_address_slot *page_slot(const struct page *page)
{
return &page_address_htable[hash_ptr(page, PA_HASH_ORDER)];
}
/**
* page_address - get the mapped virtual address of a page
* @page: &struct page to get the virtual address of
*
* Returns the page's virtual address.
*/
void *page_address(const struct page *page)
{
unsigned long flags;
void *ret;
struct page_address_slot *pas;
if (!PageHighMem(page))
return lowmem_page_address(page);
pas = page_slot(page);
ret = NULL;
spin_lock_irqsave(&pas->lock, flags);
if (!list_empty(&pas->lh)) {
struct page_address_map *pam;
list_for_each_entry(pam, &pas->lh, list) {
if (pam->page == page) {
ret = pam->virtual;
break;
}
}
}
spin_unlock_irqrestore(&pas->lock, flags);
return ret;
}
EXPORT_SYMBOL(page_address);
/**
* set_page_address - set a page's virtual address
* @page: &struct page to set
* @virtual: virtual address to use
*/
void set_page_address(struct page *page, void *virtual)
{
unsigned long flags;
struct page_address_slot *pas;
struct page_address_map *pam;
BUG_ON(!PageHighMem(page));
pas = page_slot(page);
if (virtual) { /* Add */
pam = &page_address_maps[PKMAP_NR((unsigned long)virtual)];
pam->page = page;
pam->virtual = virtual;
spin_lock_irqsave(&pas->lock, flags);
list_add_tail(&pam->list, &pas->lh);
spin_unlock_irqrestore(&pas->lock, flags);
} else { /* Remove */
spin_lock_irqsave(&pas->lock, flags);
list_for_each_entry(pam, &pas->lh, list) {
if (pam->page == page) {
list_del(&pam->list);
break;
}
}
spin_unlock_irqrestore(&pas->lock, flags);
}
}
void __init page_address_init(void)
Annotation
- Immediate include surface: `linux/mm.h`, `linux/export.h`, `linux/swap.h`, `linux/bio.h`, `linux/pagemap.h`, `linux/mempool.h`, `linux/init.h`, `linux/hash.h`.
- Detected declarations: `struct page_address_map`, `function Copyright`, `function are`, `function get_next_pkmap_nr`, `function region`, `function get_pkmap_entries_count`, `function __nr_free_highpages`, `function for_each_populated_zone`, `function __totalhigh_pages`, `function for_each_populated_zone`.
- Atlas domain: Core OS / Memory Management.
- Implementation status: integration 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.