分配内存一.kmalloc函数和vmalloc函数1.kmalloc      Driver中常用的内存分配函数,void *kmalloc(size_t size, gfp_tflags)参数:分配到的内存空间在物理上是连续的, size是想要分配的内存空间大小, flags是分配掩码. 常用掩码为GFP_ATOMIC和GFP_KERNEL.成功:返回低端物理内存页面所对应的线性内核虚拟地址失败:返回NULL(因内存不足导致分配失败)其他:用kmalloc分配的内存, 释放用kfree函数 /  kzalloc: 用0来填充分配出来的内存空间.2.vmalloc      void *vmalloc(unsigned long size). 特点: 在vmalloc区分配一段连续的虚拟地址空间, 其所映射的物理地址可能不连续, 通过伙伴系统获取内存页时,使用了GFP_KERNEL |_GFP_HIGHMEM标志, 不能保证原子性, 且在ZONE_HIGHMEM分配物理页面.释放:  voidvfree(const void *addr)3.kmalloc和vmalloc的联系和区别 kmalloc可以通过GFP_ATOMIC达到分配内存的原子性; vmalloc不能保证原子性,不能在中断上下文中使用. vmalloc涉及对页表项的操作,     vmalloc区虚拟地址与高端内存的映射, 所以效率不如kmolloc, linux driver中优先考虑kmalloc. 需要分配一段大内存, 系统中能满足要求的连续物理页面不一定存在, 用vmalloc分配一段连续的虚拟地址空间, 然后映射到分 散的物理页面来满足要求4.内存区段Linux内核把内存分为三个区段:      可用于DMA的内存:通常的内存分配都是发生在常规内存区      常规内存:存在于特别地址范围内的内存,外设可以利用这些内存执行DMA访问      高端内存:32位平台为了访问相对大量的内存而存在的一种机制二.后备高速缓存      反复使用的块变成某些特殊的内存池,内核中确实有,被称为后备高速缓存。      1.指定mempool对象,即创建内存池:mempool_create2.分配对象函数:mempool_alloc3.释放对象函数:mempool_free4.调整mempool大小:mempool_resize5.销毁内存池:mempool_destroy三.get_free_pages和相关函数如果模块需要分配大块的内存,使用面向页的分配技术会更好一些。  分配页面:get_zeroed_page: 返回指向新页面的指针并将页面清零释放页面:free_page(s): 不加s的是一个宏,是对加s的函数的调用四.per-CPU1.定义建立一个per-CPU变量时, 系统中的每个CPU都会拥有该变量的特有副本. 每个处理器访问自己的副本无需加锁, 可以放入自己的cache中,极大地提高了访问与更新效率.常用于计数器.2. API: DEFINE_PER_CPU(type, name) //定义per-CPU变量DECLARE_PER_CPU(type, name) //声明per-CPU变量3.访问静态声明的per-CPU变量:get_cpu_var(variable)   put_cpu_var(variable)由于CPU在访问并修改某个per-CPU变量的临界区时, 应避免内核抢占,  所以调用get_cpu_var宏, 该宏会使用preempt_disable()禁止抢占, 访问结束后调用put_cpu_var, 恢复内核调度器的可抢占性. 访问其他per-CPU: per_cpu(variable, cpu_id)4.动态per-cpu产生:alloc_percpu(type)释放:free_percpu(void *variable)访问:per_cpu_ptr(void *variable, int cpu_id)  
点赞 4
评论 0
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务