
linux内核
文章平均质量分 69
kaka__55
这个作者很懒,什么都没留下…
展开
-
page_ref_freeze浅析
有了get_page_unless_zero(page)的保障,page_ref_freeze()的逻辑就完备了,因为如果page_ref_freeze()成功,那肯定能杜绝后续对这个页的pin的动作,而如果page_cache_get_speculative()成功,那page_ref_freeze()就绝不可能成功。初看实现,无非就是,page_ref_freeze将page->_refcount变成了0,而page_ref_unfreeze将page->_refcount变回了count。原创 2024-12-27 20:35:02 · 470 阅读 · 0 评论 -
hugetlbfs内存释放
结合先前的分析,private映射的页会在这个流程中就被释放掉了,而shared映射的页,由于加入radix tree时将引用计数又加了一,故这个流程里面不会被释放,而是在删除hugetlbfs文件的时候,从radix tree里面删除的时候才把相关内存页释放。从函数中我们可以看到,hugetlbfs对于共享映射以及private映射的实现是有区分的,共享映射时,会把相关的内存页加入到radix tree里面,而private映射则不会加入到radix tree里。原创 2023-02-05 17:12:59 · 373 阅读 · 0 评论 -
对x86上下文切换的一点理解
根本原因就在这里,因为__switch_to_asm是一个被C语言调用的函数,作为调用者,有义务保存相关寄存器,至于保存哪些寄存器,是由x86的函数调用约定规定的,因而,作为被调用方,只需要保存相关的没有被调用方保存的寄存器即可,剩下的寄存器在函数结束后由调用方自行恢复,这里如果还做保存就是浪费力气了。完成寄存器及内核栈的切换。第一次看这个函数,感觉就是标准的上下文切换写法,最开始把prev进程的rbp、rbx、r12、r13、r14、r15寄存器完成保存,最后面再恢复next进程的这些寄存器。原创 2023-01-21 22:46:44 · 429 阅读 · 0 评论 -
linux内核printk的一些并发处理
我们知道,linux内核为了支持在各种位置都能使用printk,做了不少的工作,这篇文章简单介绍一下printk的一些并发处理。本文基于linux内核4.19.195.printk最终会调用到vprintk_func函数。可以看到,这个函数有三个分支:vprintk_nmi、vprintk_safe、vprintk_default。其中,vprintk_default是正常走的分支,vprintk_nmi是在nmi中断中调用printk走的分支,vprintk_safe是在不安全的上下文中调用prin原创 2022-12-03 12:18:15 · 1213 阅读 · 0 评论 -
谈谈我对volatile的理解
volatile关键字原创 2022-11-20 21:33:24 · 166 阅读 · 0 评论 -
ksm页面合并的并发处理
ksm页面合并的并发处理原创 2022-11-11 20:53:12 · 466 阅读 · 0 评论 -
一个workqueue导致的性能问题
本文代码基于linux 4.19.195笔者最近遇到了一个workqueue导致性能问题,引发了笔者对workqueue机制的探索和思考。简单的抽象后,问题是这样的:一共有两个进程,假设称之为a进程和b进程。a进程在等待b进程完成一些工作,b进程在完成工作后会调用相关接口通知a进程。b进程完成工作的流程的最末尾的位置,有如下两个关键步骤:首先调用schedule_work_on触发一个work 1,b进程只需要触发即可,无需等待work 1完成;然后再调用work_on_cpu(本质上也是sch原创 2022-03-04 21:47:11 · 1051 阅读 · 0 评论 -
percpu变量的并发操作
当工作中需要使用percpu变量,才知道自己对percpu变量的理解有多薄弱,所以趁现在把经验心得记录下来。percpu变量基础(wowotech):http://www.wowotech.net/kernel_synchronization/per-cpu.html一般来说,对于per-cpu的变量,我们一般需要通过关抢占进行并发保护操作;这其中就有几种方式:通过关中断local_irq_save来达到关抢占的效果(这样还能支持嵌套)通过this_cpu_***这类函数操作,见下图说明在hot原创 2021-09-24 21:46:19 · 915 阅读 · 0 评论 -
Linux内存回收之LRU链表和第二次机会法
一 LRU回收算法LRU算法,假定最近最少使用的页,在较短的时间内页不会使用,所以这些页成为回收的候选者.内存回收的核心是围绕LRU链表来进行操作,Linux内核实现了5种LRU链表类型不活跃匿名页表链表(LRU_INACTIVE_ANON)//shmem活跃匿名页表链表(LRU_ACTIVE_ANON)//不活跃文件映射页表链表(LRU_INACTIVE_FILE)活跃文件映射页表链表(LRU_ACTIVE_FILE)不可回收页表链表(LRU_UNEVICTA转载 2021-04-24 22:40:24 · 861 阅读 · 0 评论 -
谈谈自己对内存回收的理解
内存回收,是内核在内存不足的情况下,一种释放内存的方法,在4.4.198内核里,主要有两个函数涉及内存回收,一个是kswapd,一个是drop_cache;先说说kswapd,这是一个内核线程,每个内存节点都有一个这样的内核线程,名字是kswapd%d;在alloc_page函数中用低水位分配内存失败后,进入慢速路径的第一件事情static inline struct page *__alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,原创 2021-04-24 11:42:03 · 704 阅读 · 0 评论 -
linux内存管理子系统里的各种算法设计的初衷是什么?
首先说一下写这篇博文的初衷:我对linux的学习,是不是都过度的专注于各个模块的实现,而忘记了其背后的设计初衷呢?以下观点纯属作者个人观点,如果有写的不对的地方请指出。**伙伴算法的初衷:**为了兼顾内存分配效率以及减少外部碎片而设计出来的一种分配算法。百度百科对伙伴算法的定义:计算机算法的一种,是为了核心内存管理能够快速响应请求,尽可能地在提高内存利用率的同时减少内存碎片的一种算法。**slab算法的初衷:**为了不同大小的对象而设计的一个分配算法,并兼顾效率以及碎片化程度。另外,SLUB分配器原创 2021-04-11 18:35:57 · 167 阅读 · 0 评论 -
linux内核page结构体的PG_referenced和PG_active标志
linux内核使用了lru算法来置换内存页面,但是实际上并不是纯的lru算法,里面掺杂了很多别的思想,比如第二次机会,比如双时钟指针等等。这里着重说一下第二次机会的体现。在内核中有一个mark_page_accessed函数,它实际上体现一个状态机,这是它的实现:if (!PageActive(page) && PageReferenced(page) && PageLRU(page)) { activate_page(pa转载 2021-04-03 10:10:49 · 608 阅读 · 0 评论 -
低版本内核与高版本内核__zone_watermark_ok函数的变化
机缘巧合,最近研究了一下linux内核__zone_watermark_ok函数,发现高版本(4.4)和低版本3.14之前有所区别,特此记录一下。先上3.14版本的代码/* * Return true if free pages are above 'mark'. This takes into account the order * of the allocation. */static bool __zone_watermark_ok(struct zone *z, unsigned int原创 2020-11-22 16:58:37 · 524 阅读 · 2 评论 -
对linux内核DAX不支持arm的理解
前几天看内核代码,看到CONFIG_FS_DAX居然是depends on !(ARM || MIPS || SPARC),非常疑惑,于是简单的探究了一下:查看内核提交记录,是Commit d92576f1引入的,提交记录如下:该提交在Documentation/filesystems/dax.txt加了一句话:The DAX code does not work correctly on architectures which have virtually mapped caches such a原创 2020-11-01 16:26:48 · 543 阅读 · 0 评论 -
三个PTE标志位的含义:PTE_DIRTY,PTE_YOUNG,PTE_PRESENT
PTE_DIRTY:CPU在写操作时会设置该标志位,表示对应页面被写过,为脏页。PTE_YOUNG:CPU访问该页时会设置该标志位。在页面换出时,如果该标志位置位了,说明该页刚被访问过,页面是young的,不适合把该页换出,同时清除该标志位。PTE_PRESENT:表示页在内存中。...原创 2020-08-02 20:58:51 · 2509 阅读 · 0 评论 -
ARM中的linux页表与硬件页表(linux4.0)
https://blog.youkuaiyun.com/geshifei/article/details/89574508原创 2020-07-19 16:26:24 · 215 阅读 · 0 评论 -
JFFS2的remount过程
博主能力有限,若博文有错误,请各位大侠不吝赐教。本文代码基于linux4.4.198jffs2文件系统的remount命令为:mount -t jffs2 -o remount,*** /dev/mtdblocki /mnt这个命令最终会调用到mount系统调用,通过参数MS_REMOUNT告诉内核这是一次remount的操作,代码的调用路径为:sys_mount->do_mount...原创 2020-04-28 23:12:42 · 664 阅读 · 0 评论 -
JFFS2创建文件过程
本文内容基于内核版本linux4.4.198.JFFS2文件系统创建文件的过程,主要是通过VFS层的vfs_create()函数调用到jffs2_create()函数,由jffs2_create()函数负责文件的创建。jffs2_create()函数具体创建文件的步骤是:1.通过jffs2_new_inode()函数分配inode结构体以及jffs2_inode_info、jffs2_ino...原创 2020-04-12 22:49:25 · 661 阅读 · 0 评论 -
linux文件系统初始化流程
博主能力有限,若博文有错误,请各位大侠不吝赐教。本文分析linux文件系统的初始化过程,将从代码层面,将文件系统的初始化流程捋一捋。代码基于linux4.4.198.在start_kernel()函数中,分两个地方进行文件系统相关的初始化动作。第一个地方位于函数vfs_caches_init(),第二个地方位于rest_init(),前者为后者做必要的初始化,后者执行真正的文件系统挂载动作。下...原创 2020-04-06 23:07:44 · 1335 阅读 · 0 评论 -
jffs2的目录项查找过程
jffs2的目录项查找调用的函数是jffs2_lookup,下面一起看一下这个函数。/* We keep the dirent list sorted in increasing order of name hash, and we use the same hash function as the dentries. Makes this nice and simple*///...原创 2020-04-05 23:28:02 · 391 阅读 · 0 评论 -
JFFS2文件系统挂载过程(5)
上篇博文已经把挂载阶段讲完了,那挂载操作是不是就结束了呢?答案是否定的,还留下了一些操作给gc线程去完成,这么做的目的是为了让挂载阶段所使用的时间减少,提升用户体验(说白了就是让用户以为已经挂载完成了,实际上还有点无伤大雅的小问题需要gc线程处理一下)。那么纠结gc线程完成了什么挂载遗留下来的任务呢?...原创 2020-03-29 22:55:04 · 1282 阅读 · 0 评论 -
JFFS2文件系统挂载过程(4)
经过上一篇博文的分析之后,jffs2挂载过程的第一阶段已经完成,让我们重新回忆一下扫描的三个阶段:/* Scan plan:Scan physical nodes. Build map of inodes/dirents. Allocate inocaches as we goScan directory tree from top down, setting nlink in inocac...原创 2020-03-29 18:51:12 · 708 阅读 · 0 评论 -
JFFS2文件系统挂载过程(3)
继续接着上一篇博客分析jffs2文件系统的挂载过程。上一篇博客分析了jffs2_scan_eraseblock函数的扫描过程,函数很长,我们主要抓住扫描的逻辑就好。对于扫描到的inode节点,jffs2调用函数jffs2_scan_inode_node进行处理,对于扫描到的dirent节点,jffs2调用函数jffs2_scan_dirent_node进行处理。下面主要分析这两个函数。jff...原创 2020-03-29 18:48:29 · 818 阅读 · 0 评论 -
JFFS2文件系统挂载过程(2)
接上一篇博客,这篇博客继续讲解jffs2的挂载过程现在到了jffs2_build_filesystem函数,该函数进行对flash的扫描以及目录树的建立操作,分为三个阶段(以下来源于内核代码注释):/* Scan plan:Scan physical nodes. Build map of inodes/dirents. Allocate inocaches as we goScan d...原创 2020-03-27 23:29:41 · 1689 阅读 · 0 评论 -
JFFS2文件系统挂载过程(1)
从这篇博文开始,从代码角度梳理一下jffs2文件系统挂载的过程,整个过程主要以代码注释的形式呈现。本文内容基于linux4.4.198.请结合另一篇博客所述结构体进行阅读。入口函数:jffs2_mountjffs2_mount只是简单的调用了mount_mtd,并传入了一个函数指针jffs2_fill_super用于回调,mount_mtd函数会在适当的时候调用它static struct ...原创 2020-03-26 23:19:41 · 2222 阅读 · 0 评论 -
JFFS2文件系统(2)
上一篇文章讲述了jffs2的一些结构体,下面通过具体例子说明jffs2文件系统是如何进行文件的组织的。以下例子均通过mkfs.jffs2和jffs2dump两个工具得到的结果,前者用于制作jffs2文件系统,后者用于解析文件系统镜像。touch原有文件 : inode version + 1echo xxx >> file : inode version + 1,isize增加...原创 2020-01-31 23:16:04 · 663 阅读 · 0 评论 -
JFFS2文件系统(1)
本文内容基于linux4.4.198.最近用了下jffs2文件系统,把心得记录一下。本文将从实用性的角度介绍jffs2文件系统,关于理论及介绍性的文章,网络上已经有很多了,可以结合着看,从不同角度一起梳理一下jffs2文件系统的相关内容。直接上jffs2中重要的的数据结构和宏吧。存放在flash上的数据结构jffs2在flash上的数据均称为节点,每个节点都以struct jffs2_u...原创 2020-01-31 22:53:44 · 2555 阅读 · 0 评论 -
获得内核超级块实例信息的隐藏bug
之前写了一篇博客介绍怎么获取内核超级块实例链接: https://blog.youkuaiyun.com/kaka__55/article/details/103655728.在实际使用中,编写ko插入获取实例成功,获得了想要的信息,rmmod这个获取超级块实例的ko后,再去rmmod创建该超级块的ko,发现无法rmmod,经排查发现是该模块计数不为0,发现原来是获取内核超级块实例时将该模块的计数增加了一...原创 2020-01-29 15:05:53 · 131 阅读 · 0 评论 -
获得内核超级块实例信息
在内核的fs/super.c中,我们可以看到,通过static LIST_HEAD(super_blocks);将所有的struct super_block实例都链接到了一起,这个变量并没有通过EXPORT_SYMBOL进行导出,那么,如果我想在不修改内核代码的情况下获取这些super block的实例的信息,该怎么做?查看代码,发现通过如下方法可以做到:通过函数struct file...原创 2019-12-22 18:57:52 · 313 阅读 · 0 评论 -
Linux挂载文件系统后挂载点目录项dentry的联系
Linux内核挂载文件系统后目录项的联系第一次写博客,水平难免有限,请各位见谅。最近在看linux内核mount文件系统的相关内容,由此产生了一些疑惑,即在mount一个文件系统后,原有的目录项与被挂载的文件系统的根目录之间是如何联系的,vfs进行路径搜索的时候,是怎么知道该目录项被挂载了一个新的文件系统,新的文件系统又如何与挂载位置的目录项联系起来?通过程序验证后略知一二,特此记录。本文分...原创 2019-11-02 23:49:05 · 1165 阅读 · 0 评论