something about memory management经典!

高端内存相关? 

Pages
//内核把物理页面当做内存管理的基本单元 


The kernel represents every physical page on the system with a struct page structure. This structure is defined in <linux/mm.h>:
//内核用struct page 结构体 代表每个物理页面
struct page {
        page_flags_t          flags;
        atomic_t              _count;
        atomic_t              _mapcount;
        unsigned long         private;
        struct address_space  *mapping;
        pgoff_t               index;
        struct list_head      lru;
        void                  *virtual;
};

主要域的解析:
FLAGS:
The flags field stores the status of the page. Such flags include whether the page is dirty or whether it is locked in memory. Bit flags represent the various values, so at least 32 different flags are simultaneously available. The flag values are defined in <linux/page-flags.h>.
_COUNT:
The _count field stores the usage count of the pagethat is, how many references there are to this page.
VIRTUAL:
The virtual field is the page's virtual address. Normally, this is simply the address of the page in virtual memory. Some memory (called high memory) is not permanently mapped in the kernel's address space. In that case, this field is NULL and the page must be dynamically mapped when needed

 

Zones
Because of hardware limitations, the kernel cannot treat all pages as identical. Some pages, because of their physical address in memory, cannot be used for certain tasks. Because of this limitation, the kernel divides pages into different zones. The kernel uses the zones to group pages of similar properties.
there are three memory zones in Linux:

ZONE_DMA This zone contains pages that are capable of undergoing DMA.

ZONE_NORMAL This zone contains normal, regularly mapped, pages.

ZONE_HIGHMEM This zone contains "high memory," which are pages not permanently mapped into the kernel's address space.

These zones are defined in <linux/mmzone.h>.

 

一些分配内存的函数!!!

在下面的函数中 :

page structure 即返回的是直接指向物理内存中的内存空间的指针

logical address 即返回的是指向虚拟内存空间的内存的指针

注意!:

This function works the same as alloc_pages(), except that it directly returns the logical address of the first requested page. Because the pages are contiguous, the other pages simply follow from the first.

 

 

Table 11.2. Low-Level Page Allocations Methods

Flag

Description

alloc_page(gfp_mask)

Allocate a single page and return a pointer to its page structure

alloc_pages(gfp_mask, order)

Allocate 2order pages and return a pointer to the first page's page structure

__get_free_page(gfp_mask)

Allocate a single page and return a pointer to its logical address

__get_free_pages(gfp_mask, order)

Allocate 2order pages and return a pointer to the first page's logical address

get_zeroed_page(gfp_mask)

Allocate a single page, zero its contents, and return a pointer to its logical address

 

 

 

分配与释放内存空间!!!
unsigned long page;

page = __get_free_pages(GFP_KERNEL, 3);
if (!page) {
        /* insufficient memory: you must handle this error! */
        return ENOMEM;
}

/* 'page' is now the address of the first of eight contiguous pages ... */

free_pages(page, 3);

/*
 * our pages are now freed and we should no
 * longer access the address stored in 'page'
 */

The function is declared in <linux/slab.h>:

void * kmalloc(size_t size, int flags)

参数FLAG的使用!!!!

GFP_KERNEL 可能会引起阻塞,使reached!所以不能用在..........

GFP_AROMIC就解决了这个问题

Table 11.7. Which Flag to Use When

Situation

Solution

Process context, can sleep

Use GFP_KERNEL

Process context, cannot sleep

Use GFP_ATOMIC, or perform your allocations with GFP_KERNEL at an earlier or later point when you can sleep

Interrupt handler

Use GFP_ATOMIC

Softirq

Use GFP_ATOMIC

Tasklet

Use GFP_ATOMIC

Need DMA-able memory, can sleep

Use (GFP_DMA | GFP_KERNEL)

Need DMA-able memory, cannot sleep

Use (GFP_DMA | GFP_ATOMIC), or perform your allocation at an earlier point when you can sleep

.

char *buf;

buf = kmalloc(BUF_SIZE, GFP_ATOMIC);
if (!buf)
        /* error allocting memory ! */


Later, when you no longer need the memory, do not forget to free it:

kfree(buf);
VMALLOC()
The kmalloc() function guarantees that the pages are physically 
contiguous (and virtually contiguous).
 The vmalloc() function only ensures that the pages are contiguous within 
the virtual address space.
一般硬件要求的则是连续的物理地址!!!!
For the most part, only hardware devices require physically 
contiguous memory allocations.
 
/**********************************************************

下面的红字是TLB的解释:
The TLB (translation lookaside buffer) is a hardware cache used by
 most architectures to cache the mapping of virtual addresses to physical 
addresses. This greatly improves the performance of the system, 
because most memory access is done via virtual addressing.
 
般在内核代码中,都是使用

 

kmalloc申请的内存空间物理地址和虚拟地址都是连续的!

vmalloc申请的内存空间虚拟地址连续,而物理地址不是连续的!

 

必须建立一个页表的入口(page table entries),而且,物理内存需要一页一页的(因为不是连续的!)映射到虚拟内存空间。这样与一整块物理内存直接映射相比,TLB要做多的多的工作。所以vmalloc()函数开销大 ,所以,它一般用做于申请一大块的内存空间

kmalloc() ,因为使用vmalloc() 的开销比它大。 为了使物理内存中不连续的页在虚拟内存中是连续的,

 
于上面文字对应的英语正文如下:
most kernel code uses kmalloc() and not vmalloc() 
to obtain memory. Primarily, this is for performance. 
The vmalloc() function, to make nonphysically contiguous 
pages contiguous in the virtual address space, must specifically set up 
the page table entries. Worse, pages obtained via vmalloc() must be mapped by
 their individual pages (because they are not physically contiguous), 
which results in much greater TLB[4] thrashing than you see when directly 
mapped memory is used. Because of these concerns, vmalloc() is used only 
when absolutely necessary typically, to obtain very large regions of memory. 
For example, when modules are dynamically inserted into the kernel, 
they are loaded into memory created via vmalloc().
一个运用vmalloc函数的例子: 当动态插入驱动模块时!!!!!!!!!
使用例子:
char *buf;

buf = vmalloc(16 * PAGE_SIZE); /* get 16 pages */
if (!buf)
        /* error! failed to allocate memory */

/*
 * buf now points to at least a 16*PAGE_SIZE bytes
 * of virtually contiguous block of memory
 */

After you are finished with the memory, make sure to free it by using

vfree(buf);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值