- 博客(173)
- 资源 (7)
- 收藏
- 关注
原创 HWUI源码剖析(二) - 终于讲清楚OpenGL渲染的MVP矩阵的来龙去脉
研究android8.1 HWUI源码的过程中,发现OpenGL是绕不过的一个知识点,不理解OpenGL的绘制基础,必然无法很好的理解Hwui基本原理,同时熟悉OpenGL之后,HWUI也是一个非常优秀的OpenGL 2D渲染的代码,本文将介绍一下OpenGL绘制图形的重要原理,为学习HWUI源码扫清障碍,本文我们将以会一直一个白色的矩形为例,结合代码实践加以说明。
2023-10-22 21:57:22 379
原创 HWUI源码剖析(一) - 渲染中RenderProxy视角看一种很有用的编程模式
实际的工程项目中,往往都是多线程编程,也就是必然有某些业务逻辑或者功能要运行在特定的线程,比如android开发中常见的IO线程,UI线程,Render线程,这样会涉及从线程A向这些工作线程通信或者函数调用的代码编程,具体实现上可以有多种多样,但是他们的核心思想其实都是一致的,Android Handler/Looper视角看UI线程的原理_nginux的博客-CSDN博客。
2023-10-15 19:45:44 205
原创 Android Handler/Looper视角看UI线程的原理
Handler/Looper机制是android系统非重要且基础的机制,即使在rtos或者linux操作系统上开发应用框架时,也经常借鉴这个机制。通过该机制机制可以让一个线程循环处理事件,事件处理逻辑即在Handler的handleMessge种。本文建议android8.1源码分析这套机制的实现原理。
2023-10-14 16:46:49 740
原创 multi-generation lru系列 - workingset的适配
Linux 内存workingset Refault Distance算法源码及源码解析-CSDN博wen一文中我们分析了workingset算法的实现原理,内核引入mglru之后workingset算法也要做相应的适配,因为mglru算法使用了PID控制反馈算法,这其中就要统计refaulted次数和eviction次数,这些数据的统计就在workingset.c中实现的,接下来我们以v6.1源码分析workingset对于mglru的适配更新。
2023-10-03 20:46:46 227
原创 Linux回收内存的时候遇到PageWriteback和PageDirty脏页怎么处理?
我们知道内存回收会遇到各种情况的page,比如正在回写的page(PageWriteback)和脏页(PageDirty)的page,内核会等待PageWriteback完成回写呢,还是说直接跳过正在回写的页面。这两种选择各有优劣,如果等待Writeback完成会影响内存分配性能;如果直接跳过呢可能影响内存回收的效率。PageDirty的page也面临类似的问题,所以我们来看下内核v4-14源码中是如何处理这两种情况的。
2023-10-03 09:39:30 355
原创 multi-generation lru系列 - 怎么决定回收anon还是file
Linux 回收内存到底怎么计算anon/file回收比例,只是swappiness这么简单?-CSDN博客。
2023-10-02 23:26:31 220
原创 Linux 回收内存到底怎么计算anon/file回收比例,只是swappiness这么简单?
Linux内核为了区分冷热内存,将page以链表的形式保存,主要分为5个链表,除去evictable,我们主要关注另外四个链表:active file/inactive file,active anon和inactive anon链表,可以看到这主要分为两类,file和anon page,内存紧张的时候,内核开始从inactive tail定量回收page,那么这里面就有个很重要的选择:inactive file和inactive anon lru链表的回收比例到底怎么确定?
2023-09-29 22:36:29 298
转载 LWN:多代LRU方案的未来!
当一个 page 被访问时,它们会从较老的一代 list 移动到较新的一代,当需要回收内存时,会先从最古老的一代来开始回收 page。每一代的 page 都会随着时间的推移而变得老化,当最老的一代中的 page 都被回收掉了的时候,就会创造出新的一代。自这项工作的第一次发布以来最大的变动是在 "tier" (层)的定义上,tier 这个词现在被用来细分各代 page,这反过来又可以帮助更好地决定哪些 page 需要回收(reclaim),特别是在那些需要使用大量 buffered I/O 的系统中。
2023-09-24 22:34:44 169
原创 Linux 内存workingset Refault Distance算法源码及源码解析
内核mm子系统中有一个workingset.c实现了refault distance算法,发现网络逻辑介绍该算法的文章主要是黏贴自奔跑吧内核一书中的内容,军比较雷同,讲述的角度比较难以理解,我第一看到的时候琢磨了2天才明白,本文希望从更容易理解的角度来分析何为refault distance算法,以及内核引入该算法的原因,这就要从内核回收page面临的挑战说起。本文源码:v5.9。
2023-09-24 22:26:11 401
原创 Linux qemu启动内核rootfs挂载失败VFS: Cannot open root device问题解决方案
【代码】Linux qemu启动内核rootfs挂载失败VFS: Cannot open root device问题解决方案。
2023-09-22 08:26:17 701
原创 Linux关于memory cgroup的几个要点
进程的内存可以分很多类型,比如page cache,slab,anon memory等,到底是限制的哪些内存?如果进程A已经运行起来占用了一些内存,之后,再将A加入memory cgroup限制,原来占用的内存会统计入新的memory cgroup?memory cgroup有memory.soft_limit_in_bytes和memory.limit_in_bytes,假设进程使用内存超过这两个限制,内存回收时机和路径是怎么样的?
2023-09-17 17:59:53 683
原创 Linux mmap读/写触发共享文件页生命周期
Linux的mm内存子系统的核心功能就要要管理各种类型的page,确保能高效分配和释放,让物理内存得以最大化使用。初识内存系统往往关注的是page的申请和管理流程,容易忽略page的释放回收流程,其实理解mm中的内存回收和释放也是最核心的机制。
2023-09-11 23:52:07 314
原创 linux的dirty page回写磁盘过程中是否允许并发写入更新page?
众所周知Linux内核write系统调用采用pagecache机制加速写入过程,避免write系统调用长时间block应用进程,用户态进程执行write调用的时候,内核只是将用户态buffer copy到内核的pagecache当中,write系统调用就返回了,完全不需要等待数据完全写入存储设备,因为存储设备是的写入可能是个耗时很长的过程。内核正在回写page到存储设备的过程中,是否允许应用层同时更新page内容?应用层更新page是否会被block?本文将从理论和内核源码两个方面彻底分析该问题。
2023-09-10 07:59:17 500
原创 Linux page migration源码分析
Linux 内核page migration设计文档_nginux的博客-CSDN博客前文介绍了page migration迁移的设计思路,且内核文档介绍得知,总计需要20个steps完成迁移过程,本文目标是以源码视角对应到这20个step上面,加深对于页面迁移的理解。内核源码版本:Linux-5.9。下面再贴一下内核描述的20个step:__unmap_and_move函数//page:需要迁移的page//newPage: 迁移的目标page。
2023-08-27 10:41:38 324
原创 Linux 内核page migration设计文档
page migration设计之初是在numa system的各个node之间迁移physical pages,意味着进程页面的虚拟地址不会变化,物理地址发生改变,migration的目的将page迁移到临近的cpu上降低内存访问延迟。
2023-08-26 20:44:10 392
转载 自旋锁 spin_lock、 spin_lock_irq 以及 spin_lock_irqsave 的区别
能够停留下来认真读这篇文章的人大部分都已经了解了什么是自旋锁,至少知道自旋锁就是不停的询问资源有没有准备好的一把锁,这个从概念上很容易理解,当然他的内在也是很容易实现。
2023-08-23 11:10:53 187
原创 Linux源码剖析struct page结构体flags成员
/跟page reclaim的二次机会法有关//page缓存内存和磁盘数据一致//代表是脏页PG_dirty,//page在lru链表中PG_lru,//page在active lru链表中PG_active,//IO错误PG_error,//page是对应的是slab内存PG_slab,PG_arch_1,//不能换出//正在回写//马上开始回收,回收前设置//匿名页和shmem page设置该条件//被mlock了#endifPG_young,PG_idle,
2023-08-13 23:26:21 231
原创 Linux源码剖析匿名共享内存shmem原理
进程间共享匿名内存有两种重要的方式,其一是mmap设置MAP_SHARED | PRIVATE创建的虚拟地址区域,这片区域fork执行之后,由父子进程共享。其二是主动调用shmget/shmat相关接口。此外android操作系统的ashmem匿名共享内存也是基于linux内核的shmem实现。本文我们将从源码角度剖析内核shmem的设计和实现原理。
2023-08-13 17:18:43 1029 1
原创 Linux mmap系统调用视角看缺页中断
实际开发过程中经常使用或者看到mmap函数,具体细节可以man mmap查看相关细节。这个系统调用是个多面手,应用空间申请内存(比如glibc库申请大内存使用的是mmap),还是读写大文件,链接动态库,多进程间共享内存都可以看到mmap的身影,要想真正的理解这个系统一方面是从这几种使用场景的需求上理解mmap,更重要的必须基于内核源码,深入剖析其每个参数具体对应的内核实现。内存拷贝次数以mmap映射文件场景来讲,mmap读写文件与read/write的相比少一次内存拷贝。
2023-08-07 22:16:35 463
原创 linux页框回收之shrink_node函数源码剖析
Linux内存回收入口_nginux的博客-CSDN博客》前文我们概略的描述了几种内存回收入口,我们知道几种回收入口最终都会调用进入shrink_node函数,本文将以Linux 5.9源码来描述shrink_node函数的源码实现。
2023-07-30 11:31:37 482
原创 Linux内存回收入口
内存回收主要是有kswapd异步回收和direct reclaim同步回收两种入口,其中逻辑非常复杂,本文主要只概要描述不同回收场景下内核设计的主要思想,源码细节不同版本有不少区别,具体的分析后续会有专门的文章分析。
2023-07-29 14:27:00 236
原创 搞懂sparsemem稀疏内存模型
随着大内存和内存热插拔技术发展,内核物理内存越来越不连续,内核管理这种非连续物理内存的元数据metadata也需要随之发展,避免内存浪费,内核的sparse mem稀疏内存模型就是解决该问题。数据结构mmzone.h//根据sec number计算属于哪个root,即mem_section二位数组第一维的index//2048//相当于是[2048][256]的二维数组,每个数组元素是struct mem_section//为了节省空间,这个字段包含很多信息,具体见下面源码的解释/*
2023-07-28 23:00:00 431
原创 page _refcount和_mapcount字段
linux page有两个非常重要的引用计数字段_refcount和_mapcount,都是atomic_t类型,其中,_refcount表示内核中应用该page的次数。当_refcount = 0时,表示该page为空闲或者将要被释放。当_refcount > 0,表示该page页面已经被分配且内核正在使用,暂时不会被释放。
2023-07-24 22:59:08 481
原创 ext4 mballoc之buddy算法
ext4_mb_init_cache,而是ext4_mb_load_buddy就会调用ext4_mb_init_cache,这里init cache就是指保存磁盘data block bitmap的pagecache和buddy bitmap。ext4_mb_init_group和ext4_mb_load_buddy都会调用ext4_mb_init_cache,我们就以ext4_mb_init_group调用为启动分析。
2023-07-23 15:55:53 404
原创 ext4 delay allocation之ext4_writepages页回写源码剖析
ext4 write写入pagecache之后,再合适的时机会回写到磁盘,ext4文件系统中是通过ext4_writepages写入磁盘,本来将在源码角度分析该过程。建议先参照ext4 - delay allocation数据结构_nginux的博客-CSDN博客看下涉及的重要数据结构。
2023-07-23 01:03:21 364
原创 ext4 - delay allocation数据结构
延迟分配delay allocation是ext4非常重要的特性,启用该特性write系统将用户空间buffer写入内存page cache中即返回,此时也不会真正进行磁盘block分配,而是延迟到磁盘回写时(比如dirty ratio达到一定值,定时刷新,主动sync等) 才开始映射磁盘block(map block)进行块分配,好处就是可以将连续的块进行合并merge,结合ext4的mballoc多块分配机制,可以一次性分配多个物理block,降低cpu使用率和碎片化问题。
2023-07-22 15:22:12 624
原创 Linux pagecache writeback的一个性能优化patch分析
用来主要降低设备IO拥塞时,由于jdb transaction commit引起的性能问题,如果page cache不需要执行block allocation和extent conversion逻辑,就先将这部分dirty page submit交给块设备层,然后复用一个transcation即可。buffer_unwritten(bh)逻辑,命中map->m_len = 0逻辑返回true。mpage_add_bh_to_extent会返回true,会进入的mpage_submit_page逻辑。
2023-07-17 16:10:59 176
原创 Ext4文件系统介绍 - 实战篇
红框的f30a对应上图的extent_header,根据ext4理论篇中的定义我们知道extent_header数据结构如下:正好f30A对应extent_header的magic number。我们知道inode是存储在inode table中,每个inode size 是256B,所以我们怎么找到inode table的block号?dumpe2fs命令!本文主要通过dd,hexdump和dumpe2fs工具分析ext4的磁盘二进制数据,加深对ext4文件系统的印象,要想理解本建议先阅读下。
2023-07-14 21:34:31 496
原创 Android代码解读之渲染机制揭秘
本文从代码层面,把应用进程启动和渲染的流程走读了一遍,理解了Android的渲染原理对于理解其他UI框架或者引擎有比较好的借鉴意义,比如研究google的flutter框架时会更轻松:flutter的渲染流程(图来自网络上图从网络上搜到的flutter 框架的流程图,这个流程是不是有点像套娃战术,同样是vsync信号、UI线程,GPU线程(也就是android的renderthread)两线程加速性能。
2023-07-11 20:53:20 343
原创 Ext4文件系统介绍 - 理论篇
但是,ext4_inode_info没有定义指向ext4_inode的字段,只是拷贝了ext4_inode的i_block,i_flags等字段;ext4_sb_info和ext4_super_block中的很多字段相似,但也有区别,ext4_sb_info中的很多字段是根据ext4_super_block的字段计算而得,虽然可以通过 ext4_super_block计算而得到,但是定义在ext4_sb_info定义可以省去重复计算的时间。磁盘数据的每个inode通过ext4_inode数据结构表示。
2023-07-09 21:46:39 2115
转载 Linux iowait到底是什么含义
IOwait 一个迷之参数,top/iostat/mpstat/sar 都会统计的关键数据,字面理解是系统等待IO的时间,经常用于反映系统IO压力。IOwait时候CPU在干什么?什么时间才算IOwait,到底在wait什么?
2023-07-08 07:56:50 505
原创 Linux bio数据结构
代码中newblock=map->m_lblk - ee_block + ee_start即是起始逻辑地址映射的磁盘块地址,allocated = ee_len - (map->m_lblk - ee_block)是成功映射的block数,注意未必等于map.m_len,有可能小于map.m_len,因为磁盘block未必有map.m_len个连续的块。ext4_mpage_readpages函数就会读取磁盘数据就会构建一个个的bio,如上面描述我们知道bio指向的是一块连续的磁盘数据,
2023-07-08 01:43:15 622
原创 Linux 读文件 - readahead预读算法
根据ondemand_readahead中initial_readahead label处逻辑看,ra->size是由get_init_ra_size函数计算,该函数第一个参数是应用read的数据页(每个数据页4K)的数量,该场景每次读取4K bytes,相当于调用get_init_ra_size(1,32)返回4。这里async readahead就是指generic_file_buffered_read函数中的:page_cache_async_readahead函数调用。: 开始预读的数据页索引,
2023-07-02 22:46:16 658
原创 Linux read的核心函数generic_file_buffered_read
【代码】Linux read的核心函数generic_file_buffered_read。
2023-07-02 16:19:27 439
原创 buffer_head数据结构
buffer_head用来将一个单独的block映射到一个page,一般80x86体系结构上,根据block size大小,一个page可以包含1-8个block,比如如果block size = 1K,那么一个缓存page缓存4个block,且buffer_head是文件系统和block layer的io基本单位。假设page size = 4K, block size = 1K。bio取代了buffer_head作为io基本单位。
2023-07-01 16:55:28 728
原创 Linux源码编译开启cgroup blk限制io性能
经过上面的mout之后就可以看到/sys/fs/cgroup/blkio中出现了各种控制节点。
2023-07-01 13:47:14 471
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人