GFP_KERNEL 不一直是使用的正确分配标志; 有时 kmalloc 从一个进程的上下文的外部调用. 例如, 这类的调用可能发生在中断处理, tasklet, 和内核定时器中. 在这个情况下, 当前进程不应当被置为睡眠, 并且驱动应当使用一个 GFP_ATOMIC 标志来代替. 内核正常地试图保持一些空闲页以便来满足原子的分配. 当使用 GFP_...
1.1 kmalloc函数原型: static__always_inlinevoid*kmalloc(size_tsize,gfp_tflags); 1.1.1 gpf flags含义 |– 在进程上下文,可以睡眠 GFP_KERNEL |– 在进程上下文,不可以睡眠,如: GFP_ATOMIC | |– 中断处理程序 GFP_ATOMIC | |– 软中断 GFP_ATOMIC | |– Tasklet GFP_ATOMIC |– 用于DMA的内存,可以...
|– 用于DMA的内存,不可以睡眠 GFP_DMA |GFP_ATOMIC 对应的内存释放函数为: voidkfree(constvoid*objp); kzalloc /** * kzalloc - allocate memory. The memory is set to zero. * @size: how many bytes of memory are required. * @flags: the type of memory to allocate (see kmalloc). */stati...
void *kmalloc(size_t size, gfp_t flags);void kfree(const void *objp); 较常用的 flags(分配内存的方法):GFP_ATOMIC —— 分配内存的过程是一个原子过程,分配内存的过程不会被(高优先级进程或中断)打断;GFP_KERNEL —— 正常分配内存;GFP_DMA ——给 DMA 控制器分配内存,需要使用该标志(DMA要求分配...
kmalloc 分配内存的过程可以是原子过程(使用 GFP_ATOMIC),而 vmalloc 分配内存时则可能产生阻塞; kmalloc 分配内存的开销小,因此 kmalloc 比 vmalloc 要快; 一般情况下,内存只有在要被 DMA 访问的时候才需要物理上连续,但为了性能上的考虑,内核中一般使用 kmalloc(),而只有在需要获得大块内存时才使用 vmalloc()。
kmalloc 分配内存的过程可以是原子过程(使用 GFP_ATOMIC),而 vmalloc 分配内存时则可能产生阻塞; kmalloc 分配内存的开销小,因此 kmalloc 比 vmalloc 要快; 一般情况下,内存只有在要被 DMA 访问的时候才需要物理上连续,但为了性能上的考虑,内核中一般使用 kmalloc(),而只有在需要获得大块内存时才使用 vmalloc()。
GFP_KERNEL —— 正常分配内存; GFP_DMA ——给 DMA 控制器分配内存,需要使用该标志(DMA要求分配虚拟地址和物理地址连续)。 flags 的参考用法: |–进程上下文,可以睡眠 GFP_KERNEL |– 进程上下文,不可以睡眠 GFP_ATOMIC |– 中断处理程序 GFP_ATOMIC ...
所以,在中断处理函数、tasklet 和内核定时器等非进程上下文中不能阻塞,此时驱动应当使用 GFP_ATOMIC 标志来申请内存。当使用 GFP_ATOMIC 标志申请内存时,若不存在空闲页,则不等待,直接返回。 除了上述表格所列标志外,还包括如下: _ _GFP_DMA(要求分配在能够 DMA 的内存区)...
GFP_ATOMIC 用于在中断处理例程或其他运行于进程上下文之外的代码中分配内存,不会休眠。GFP_HIGHUSER用于为用户空间分配内存,指高端内存分配,可能会休眠。GFP_NOIO禁止任何I/O的初始化(主要在虚拟内存代码中使用)。GFP_NOFS分配不允许执行任何文件系统调用(主要在文件系统代码中使用)。***分割线以上的flag可以和分割...
//include/linux/slab.hstatic__always_inlinevoid*kmalloc(size_t size, gfp_t flags)voidkfree(constvoid*x) GFP_USER: 由user发起的内存申请,可以休眠。 GFP_KERNEL: 由内核发起的内存申请,可以休眠。 GFP_ATOMIC: 不能休眠的内存申请请求,比如在中断处理函数中申请内存。