zoukankan      html  css  js  c++  java
  • 高端内存(临时内存映射)

    先看相关的变量的意思:

    enum km_type {
    D(
    0) KM_BOUNCE_READ,
    D(
    1) KM_SKB_SUNRPC_DATA,
    D(
    2) KM_SKB_DATA_SOFTIRQ,
    D(
    3) KM_USER0,
    D(
    4) KM_USER1,
    D(
    5) KM_BIO_SRC_IRQ,
    D(
    6) KM_BIO_DST_IRQ,
    D(
    7) KM_PTE0,
    D(
    8) KM_PTE1,
    D(
    9) KM_IRQ0,
    D(
    10) KM_IRQ1,
    D(
    11) KM_SOFTIRQ0,
    D(
    12) KM_SOFTIRQ1,
    D(
    13) KM_TYPE_NR
    };

    还有一个是:



    enum fixed_addresses {
    FIX_HOLE,
    FIX_VDSO,
    FIX_DBGP_BASE,
    FIX_EARLYCON_MEM_BASE,
    #ifdef CONFIG_X86_LOCAL_APIC
    FIX_APIC_BASE,
    /* local (CPU) APIC) -- required for SMP or not */
    #endif
    #ifdef CONFIG_X86_IO_APIC
    FIX_IO_APIC_BASE_0,
    FIX_IO_APIC_BASE_END
    = FIX_IO_APIC_BASE_0 + MAX_IO_APICS-1,
    #endif
    #ifdef CONFIG_X86_VISWS_APIC
    FIX_CO_CPU,
    /* Cobalt timer */
    FIX_CO_APIC,
    /* Cobalt APIC Redirection Table */
    FIX_LI_PCIA,
    /* Lithium PCI Bridge A */
    FIX_LI_PCIB,
    /* Lithium PCI Bridge B */
    #endif
    #ifdef CONFIG_X86_F00F_BUG
    FIX_F00F_IDT,
    /* Virtual mapping for IDT */
    #endif
    #ifdef CONFIG_X86_CYCLONE_TIMER
    FIX_CYCLONE_TIMER,
    /*cyclone timer register*/
    #endif
    #ifdef CONFIG_HIGHMEM
    FIX_KMAP_BEGIN,
    /* reserved pte's for temporary kernel mappings */
    FIX_KMAP_END
    = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
    #endif
    #ifdef CONFIG_ACPI
    FIX_ACPI_BEGIN,
    FIX_ACPI_END
    = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
    #endif
    #ifdef CONFIG_PCI_MMCONFIG
    FIX_PCIE_MCFG,
    #endif
    #ifdef CONFIG_PARAVIRT
    FIX_PARAVIRT_BOOTMAP,
    #endif
    __end_of_permanent_fixed_addresses,
    #define NR_FIX_BTMAPS 64
    #define FIX_BTMAPS_NESTING 4
    FIX_BTMAP_END
    =
    __end_of_permanent_fixed_addresses
    + 512 -
    (__end_of_permanent_fixed_addresses
    & 511),
    FIX_BTMAP_BEGIN
    = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1,
    FIX_WP_TEST,
    #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
    FIX_OHCI1394_BASE,
    #endif
    __end_of_fixed_addresses
    };

    下面进入正题,临时映射的入口:

    # define kmap_atomic(page, type)        __kmap_atomic(page, type)
    /* 临时映射的入口 */
    void *__kmap_atomic(struct page *page, enum km_type type)
    {
    return kmap_atomic_prot(page, type, kmap_prot);
    }

    具体实现的代码(有些地方还不是非常清楚,以后弄清楚来再来补充):

    # define kmap_atomic_prot(page, type, prot)     __kmap_atomic_prot(page, type, prot)
    /* 和kmap相比会快一点,应为不需要全局锁,并且不需要处理global tlb(并且kmap是不能睡眠的,这里type没什么用) */
    void *__kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
    {
    /* 编译期间特别的线性地址 */
    enum fixed_addresses idx;
    unsigned
    long vaddr;
    /*
    * 原子映射是基于每个CPU的,因此在当前cpu上禁止抢占,直到unmap
    * 的时候才开启,这样就不会到时原子映射的重入,毕竟如果禁用抢占
    * 的话,调用者进程就很可能在同一cpu重入kmap_atomic_prot,然后就
    * 映射到同一虚拟地址。一次不允许睡眠。
    */
    preempt_disable();
    pagefault_disable();
    /* 如果不是高端内存 */
    if (!PageHighMem(page))
    return page_address(page);

    /* 递增type,保证下面公式起作用 */
    debug_kmap_atomic_prot(type);

    /* 下面的两行用来保证N个CPU调用kmap_atomic不会将page映射到一个地址 */
    idx
    = type + KM_TYPE_NR*smp_processor_id();
    vaddr
    = __fix_to_virt(FIX_KMAP_BEGIN + idx);

    WARN_ON_ONCE(
    !pte_none(*(kmap_pte-idx)));
    set_pte(kmap_pte
    -idx, mk_pte(page, prot));
    arch_flush_lazy_mmu_mode();

    return (void *)vaddr;
    }
  • 相关阅读:
    如何去掉流氓网站http://www.2345.com/?177
    『ExtJS』01 004. ExtJS 4 确定函数的作用域
    『Java』Servlet 最简教程
    『Java』最简教程
    『ExtJS』01 002. ExtJS 4 类的继承
    『ExtJS』01 003. ExtJS 4 类的混合
    『ExtJS』01 006. ExtJS 4 组件的别名
    『ExtJS』01 007. ExtJS 4 查找组件
    『ExtJS』01 005. ExtJS 4 类的‘Import’
    『ExtJS』01 001. ExtJS 4 类的定义
  • 原文地址:https://www.cnblogs.com/ggzwtj/p/2133672.html
Copyright © 2011-2022 走看看