User: Password:
Subscribe / Log in / New account

Another reason for kmap_atomic()

Another reason for kmap_atomic()

Posted Feb 22, 2007 8:50 UTC (Thu) by pbreuer (guest, #43542)
In reply to: Another reason for kmap_atomic() by giraffedata
Parent article: On not getting burned by kmap_atomic()

Are you SURE kmap can sleep? This is said also by Rubini in LDD ( "kmap returns a kernel virtual address for any page in the system. For low-memory pages, it just returns the logical address of the page; for high-memory pages, kmapcreates a special mapping. Mappings created with kmap should always be freed with kunmap; a limited number of such mappings is available, so it is better not to hold on to them for too long. kmap calls are additive, so if two or more functions both call kmap on the same page the right thing happens. Note also that kmap can sleep if no mappings are available.").

However, I see no way it can. In kernel 2.6.17, for example, in highmem.h

static inline void *kmap(struct page *page) { return page_address(page); }

and page_address() is defined in mm.h:

#define page_address(page) ((page)->virtual)


#define page_address(page) \
__va( (((page) - page_zone(page)->zone_mem_map) << PAGE_SHIFT) \
+ page_zone(page)->zone_start_paddr)

OK, so you think page_zone() might sleep? No. That's also in mm.h:

static inline zone_t *page_zone(struct page *page)
return zone_table[page->flags >> ZONE_SHIFT];

so I don't see a sleep.

(Log in to post comments)

Another reason for kmap_atomic()

Posted Oct 29, 2016 21:11 UTC (Sat) by slugsur (subscriber, #110919) [Link]

kmap calls kmem_high for high memory which calls lock_kmap

275 void *kmap_high(struct page *page)
276 {
277 unsigned long vaddr;
279 /*
280 * For highmem pages, we can't trust "virtual" until
281 * after we have the lock.
282 */
283 lock_kmap();
284 vaddr = (unsigned long)page_address(page);
285 if (!vaddr)
286 vaddr = map_new_virtual(page);
287 pkmap_count[PKMAP_NR(vaddr)]++;
288 BUG_ON(pkmap_count[PKMAP_NR(vaddr)] < 2);
289 unlock_kmap();
290 return (void*) vaddr;
291 }

Copyright © 2017, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds