Hi, reading the source code of kmap_atomic() and kunmap_atomic() as below, I would like to ask: a. noticed that pagefault_disable() and pagefault_enable() is called across two different function - why is that necessary? b. basically, I would like to create a new page, and assign the PTE to point to that page, and change the page attributes in the PTE - so all these operation MUST ALWAYS BE done with pagefault disabled? c. Since within an interrupt, the interrupt is disabled, therefore, I can always do these above operation inside the pagefault handler context as well? d. After I get a new page with __get_free_page(__GFP_HIGHMEM), and returned value is not null, it means that PTE mapping has already been allocated to it, right? e. So if I want to change the page attributes inside the PTE from (d), it should be done within pagefault_disabled mode? f. After I set the _PAGE_PRESENT bit of the PTE to invalid, and since __get_free_page() derive the page from a free_list, will the page ever be reused by the kernel, either for another allocation, or for some other purposes? Sorry, if these questions are confusing..... ============================================================================== /* * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because * no global lock is needed and because the kmap code must perform a global TLB * invalidation when the kmap pool wraps. * * However when holding an atomic kmap is is not legal to sleep, so atomic * kmaps are appropriate for short, tight code paths only. */ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) { enum fixed_addresses idx; unsigned long vaddr; /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ pagefault_disable(); if (!PageHighMem(page)) return page_address(page); debug_kmap_atomic_prot(type); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); BUG_ON(!pte_none(*(kmap_pte-idx))); set_pte(kmap_pte-idx, mk_pte(page, prot)); arch_flush_lazy_mmu_mode(); return (void *)vaddr; } void *kmap_atomic(struct page *page, enum km_type type) { return kmap_atomic_prot(page, type, kmap_prot); } void kunmap_atomic(void *kvaddr, enum km_type type) { unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); /* * Force other mappings to Oops if they'll try to access this pte * without first remap it. Keeping stale mappings around is a bad idea * also, in case the page changes cacheability attributes or becomes * a protected page in a hypervisor. */ if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) kpte_clear_flush(kmap_pte-idx, vaddr); else { #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(vaddr < PAGE_OFFSET); BUG_ON(vaddr >= (unsigned long)high_memory); #endif } arch_flush_lazy_mmu_mode(); pagefault_enable(); } -- Regards, Peter Teoh -- To unsubscribe from this list: send an email with "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ