Temporary Kernel Mappings

The kmap function just described must not be used in interrupt handlers because it can sleep. If there are no free positions in the pkmap array, it goes to sleep until the situation improves. The kernel therefore provides an alternative mapping function that executes atomically and is logically named kmap_atomic. A major advantage of this function is that it is faster than a normal kmap. However, it must not be used in code that can potentially go to sleep. It is therefore ideal for short code sections that quickly require a temporary page.

The definition of kmap_atomic is architecture-specific for IA-32, PPC, and Sparc32, but the three implementations differ only in very minor details. Their prototype is identical.

void *kmap_atomic(struct page *page, enum km_type type)

page is a pointer to the management structure of the highmem page, and type defines the type of mapping required.26

<asm-arch/kmap_types.h>

enum km_type {

KM_BOUNCE_READ, KM_SKB_SUNRPC_DATA,

KM_PTE0, KM_PTE1,

KM_SOFTIRQ1, KM_TYPE_NR

The fixmap mechanism discussed in Section 3.4.2 makes the memory needed to create atomic mappings available in the kernel address space. An area that can be used to map highmem pages is set up between FIX_KMAP_BEGIN and FIX_KMAP_END in the fixed_addresses array. The exact position is calculated on the basis of the CPU currently active and the desired mapping type.

idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = _fix_to_virt(FIX_KMAP_BEGIN + idx);

In the fixmap area, there is a ''window''for each processor in the system. It contains just one entry for each mapping type, as demonstrated in Figure 3-42 (km_type_nr is not a separate type but simply indicates how many entries there are in km_type). This arrangement makes it clear why functions may not block when they use kmap_atomic. If they did, another process could create a mapping of the same type behind their backs and overwrite the existing entries.

26The contents of the structure differ according to architecture, but the differences are so insignificant that they are not worth describing.

CPU 0

CPU 1

CPU n

KM_BOUNCE_READ KM_SKB_SUNRPC_DATA,

FIX_KMAP_BEGIN 2 = KM_SKB_SUNRPC_DATA,... FIX_KMAP_END

Continue reading here: Mapping Functions on Machines without Highmem

Was this article helpful?

0 0