热门标签 | HotTags
当前位置:  开发笔记 > 人工智能 > 正文

LinuxKernel内存分配方式

文章标题:LinuxKernel内存分配方式。Linux是中国IT实验室的一个技术频道。包含桌面应用,Linux系统管理,内核研究,嵌入式系统和开源等一些基本分类

  这周BSP那边碰到一个蛮严重的issue:

  循环放电影,v4l2 output driver的 dma_alloc很容易就失败,kernel panic,dump出当前buddy系统的状态。

  初步分析是由于内存fragment导致没有足够大的连续内存分配给v4l output driver。开始debug

  首先通过/proc/buddyinfo 在播放电影时候不间断的dump buddy状态,发现大块内存块:256K - 4MB block

  减少的很迅速,1-2小时后,buddy中就不存在大块连续内存。这证明了初步分析是正确的,但是还不知道

  是谁导致了fragment,是应用层,还是v4l2 driver本身?

  接下来添加一个NORMAL zone(arm体系中就DMA一个zone,所以application和dma都使用一个buddy系统),

  让普通内存分配和dma隔开。继续测试,发现dma zone中的内存块状态在最初很正常,但NORMAL zone的内存

  却在急剧减少,最终NORMAL zone已经没有足够内存给application,kernel转而向DMA zone申请,

  最终issue重现。

  现在问题很清楚了,application发生内存leak,很严重的leak。但是dma_alloc这边会没有问题马?

  Fred在看了我描述的问题后,指出了dma_alloc中算法的一些问题:当向buddy申请完足够size的2^的内存块后,

  该函数会释放在申请块中多余的page,加速了fragment。后来我们做了一个实验,将dma_alloc里的释放多余

  页的功能去掉,fragment的速度大大减缓。

  经过上周对这个issue的研究,我开始重新总结kernel里对内存分配的方式和方法,总结如下:

  页分配

  unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)

  直接从buddy系统中获得原始页。最原始的分配方式。

  slab分配器

  1. 通用 cache

  void *kmalloc(size_t size, gfp_t flags)

  kmalloc 基于以下几种size的mem cache:32, 64, 128, 256, 512, 1,024, 2,048, 4,096,

  8,192, 16,384, 32,768, 65,536 和 131,072 bytes。其本质也是调用kmem_cache_alloc来分配

  object。所以kmalloc一次最大可分配的size为128KB。kmalloc分配速度很快,在分配时需注意gfp flag

  参数:在不interrupt上下文(ISR, softirq, tasklet)及不可睡眠上下文使用GFP_ATOMIC。

  内核还增加了内存清零的分配函数:kzalloc。

  2. 专用 cache

  kmem_cache_create()

  void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)

  如果你需要频繁的分配和释放某个结构,建议不要采用kmalloc,而是自己在slab系统中创建memory cache。

  指定该结构的object size。分配时使用kmem_cache_alloc。同样的slab object大小也有限制,一般情况

  下一个MAX_OBJ_ORDER是5,也就是32个页,128KB。

  非连续内存分配

  void *vmalloc(unsigned long size)

  超过128KB的内存显然不能使用slab分配,并且当申请的连续内存大小不能在buddy系统中得到满足,那么

  就需要使用vmalloc。vmalloc为了把物理的非连续页一个个映射,从而导致比直接内存映射大的多的

  后援缓冲区抖动。除非需要特别大的内存,否则尽量不要使用vmalloc。

  基于DMA 分配

  void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)

  在某些arch中,可以使用dma_alloc_coherent来分配DMA专用内存。列入在arch/arm/mm/consistent.c

  中,该函数先分配最小可满足size的2^order内存,然后释放2^order-size多余的页给buddy。而arch/i386/

  kernel/pci-dma.c中,则直接分配2^order块内存。

  直接映射分配

  ioremap(unsigned long phys_addr, size_t size)

  int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,

  unsigned long pfn, unsigned long size, pgprot_t prot)

  在某些体系结构中,我们可以保留memory map段上的某一个区域,作为dma或其他设备的专有内存。

  这段内存并不在kernel buddy的控制之下(没有被放入mem_maps),你也无法从以上几种分配方式中得到

  这些内存。这个时候,你可以用ioremap和remap_pfn_range将这段内存直接映射到vm上。


推荐阅读
  • Søren Kierkegaard famously stated that life can only be understood in retrospect but must be lived moving forward. This perspective delves into the intricate relationship between our lived experiences and our reflections on them. ... [详细]
  • 计算机网络复习:第五章 网络层控制平面
    本文探讨了网络层的控制平面,包括转发和路由选择的基本原理。转发在数据平面上实现,通过配置路由器中的转发表完成;而路由选择则在控制平面上进行,涉及路由器中路由表的配置与更新。此外,文章还介绍了ICMP协议、两种控制平面的实现方法、路由选择算法及其分类等内容。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • 深入理解C++中的KMP算法:高效字符串匹配的利器
    本文详细介绍C++中实现KMP算法的方法,探讨其在字符串匹配问题上的优势。通过对比暴力匹配(BF)算法,展示KMP算法如何利用前缀表优化匹配过程,显著提升效率。 ... [详细]
  • 探讨一个显示数字的故障计算器,它支持两种操作:将当前数字乘以2或减去1。本文将详细介绍如何用最少的操作次数将初始值X转换为目标值Y。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 本文探讨如何设计一个安全的加密和验证算法,确保生成的密码具有高随机性和低重复率,并提供相应的验证机制。 ... [详细]
  • 深入解析:手把手教你构建决策树算法
    本文详细介绍了机器学习中广泛应用的决策树算法,通过天气数据集的实例演示了ID3和CART算法的手动推导过程。文章长度约2000字,建议阅读时间5分钟。 ... [详细]
  • 在金融和会计领域,准确无误地填写票据和结算凭证至关重要。这些文件不仅是支付结算和现金收付的重要依据,还直接关系到交易的安全性和准确性。本文介绍了一种使用C语言实现小写金额转换为大写金额的方法,确保数据的标准化和规范化。 ... [详细]
  • 在给定的数组中,除了一个数字外,其他所有数字都是相同的。任务是找到这个唯一的不同数字。例如,findUniq([1, 1, 1, 2, 1, 1]) 返回 2,findUniq([0, 0, 0.55, 0, 0]) 返回 0.55。 ... [详细]
  • 本文探讨了卷积神经网络(CNN)中感受野的概念及其与锚框(anchor box)的关系。感受野定义了特征图上每个像素点对应的输入图像区域大小,而锚框则是在每个像素中心生成的多个不同尺寸和宽高比的边界框。两者在目标检测任务中起到关键作用。 ... [详细]
  • 网络攻防实战:从HTTP到HTTPS的演变
    本文通过一系列日记记录了从发现漏洞到逐步加强安全措施的过程,探讨了如何应对网络攻击并最终实现全面的安全防护。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
author-avatar
LF猫咪
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有