kmap_atomic(9)
β¨ kmap_atomic (9) β¨
okay so real talk bestie, this is from the Kernel API Manual and it's giving "vintage, but make it deprecated" π
πΈ NAME πΈ
kmap_atomic β atomically map a page for temporary usage. and yes. it's Deprecated! π© (the exclamation mark is theirs, not mine, they're being dramatic)
π SYNOPSIS π
void * kmap_atomic (const struct page *page );
π¦ ARGUMENTS π¦
pageβ pointer to the page you wanna map, that's it, that's the whole vibe π«Ά
β RETURN β
it hands you back the virtual address of the mapping β that's your golden ticket to the page contents, no cap π
π DESCRIPTION π
so here's the tea β β kmap_atomic is in fact just a wrapper around kmap_local_page, but it also disables pagefaults and, depending on your PREEMPT_RT configuration, also CPU migration and preemption. the way that's two extra side effects for free π
heads up: because those last two (CPU migration + preemption) are config-dependent, users should not count on them. don't build your whole personality around them, they might not show up.
mappings should always be released by kunmap_atomic. always always. no leaving the map open like an unread group chat π
Do not use in new code. use kmap_local_page instead. periodt. β
π when do you actually reach for this?
it's used in atomic context when code wants to access the contents of a page that might be allocated from high memory (peep __GFP_HIGHMEM), for example a page in the pagecache. the API has two functions, and they can be used in a manner similar to the following:
// Find the page of interest.
struct page *page = find_get_page(mapping, offset);
// Gain access to the contents of that page.
void *vaddr = kmap_atomic(page);
// Do something to the contents of that page.
memset(vaddr, 0, PAGE_SIZE);
// Unmap that page.
kunmap_atomic(vaddr);
β οΈ iconic little trap: note that thekunmap_atomiccall takes the result of thekmap_atomiccall, not the argument. yes this has personally victimised people. you're welcome π
π§ the two-page situation
if you need to map two pages because you want to copy from one page to another, you need to keep the kmap_atomic calls strictly nested, like:
vaddr1 = kmap_atomic(page1); vaddr2 = kmap_atomic(page2);
memcpy(vaddr1, vaddr2, PAGE_SIZE);
kunmap_atomic(vaddr2); kunmap_atomic(vaddr1);
strictly nested meaning unmapping goes in the reverse order β last in, first out, very stack, very main character energy π
π SEE ALSO π
kernel file ./include/linux/highmem.h plus the whole friend group:
kmap(9)kunmap(9)kmap_to_page(9)kmap_flush_unused(9)kmap_local_page(9)kmap_local_folio(9)clear_user_page(9)clear_user_pages(9)clear_user_highpage(9)clear_user_highpages(9)vma_alloc_zeroed_movable_folio(9)memcpy_from_folio(9)memcpy_to_folio(9)folio_zero_tail(9)folio_fill_tail(9)memcpy_from_file_folio(9)folio_zero_segments(9)folio_zero_segment(9)folio_zero_range(9)folio_release_kmap(9)
π sign-off π
this lil page lives in ./include/linux, stamped October 2026, and it's literally titled kmap_atomic(9) β go off queen, even if you are deprecated πβ¨ bye bestie, use kmap_local_page fr fr π«Ά
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms