内核 kmap_atomic分析
1、为什么会有这个函数?
我想主要的原因就是kmap_atomic在效率上要比kmap提升不少。
在kmap函数中,会有如下几个比较耗时的部分:
1)、page_address函数
2)、Sleep for somebody else to unmap their entries
代码如下:
171 ____________DECLARE_WAITQUEUE(wait, current);
173 ______________set_current_state(TASK_UNINTERRUPTIBLE);
174____________add_wait_queue(&pkmap_map_wait,&wait);
175 ____________unlock_kmap();
176 ____________schedule();
177 ____________remove_wait_queue(&pkmap_map_wait, &wait);
3)、lock_kmap函数,需要加锁啊!!!
相反kmap_atomic函数,从名字就能看出,原子操作一气呵成。。没有sleep,没有锁。
2、怎么实现的?需要考虑什么问题?
首先得知道这个函数的主要目的是实现page 到 vaddr的转化。
其次我们得考虑多cpu和多任务,大家知道 kernel可以在多个cpu上同时运行不同的task,然而它们共同使用一个内存地址空间,因此如何能保证N个cpu调用kmap_atomic不会将page映射到一个虚拟地址(vaddr)呢?
我们来看看kmap_atomic是如何实现的?
1)、定义一个percpu变量__kmap_atomic_idx,同时在当前cpu上禁用抢占,直到unmap的时候才开启,这样就保证了同一cpu其它任务不会调用该函数。除非该进程在unmap之前睡眠,如果真的那样,别的进程就很可能在同一cpu重入kmap_atomic函数了,然后就可能映射到同一虚拟地址,因此在原子映射期间最好不要休眠。
2)、设计了一个完美的公式
type = kmap_atomic_idx_push(); //递增一个percpu变量,返回递增后的结果,增加一个计算type的函数表示kmap_atomic函数可以重入,就是上面说的该进程在unmap之前睡眠情况,但一般情况下不会发生冲入,所以该值应该是1,unmap时该值会--。当然重入的次数是有限制的,不会超过KM_TYPE_NR。
idx = type + KM_TYPE_NR*smp_processor_id();//不同的cpusmp_processor_id()的值是不同的,因此,不同的cpu得到的idx不同。
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);//不同的idx得到的vaddr就不同了。
set_pte(kmap_pte-idx, mk_pte(page, prot)); //设置页表
return (void *)vaddr;
总结,通过percpu变量+禁抢占+加计算公式,就实现了,不同cpu的不同进程调用kmap_atomic函数得到的vaddr是不同的。同时这也给我们实现atomic提供了一种思路,实际上atomic一般都会有一个percpu变量。
3、得到vaddr之后,页表的建立。
我们就以arm为例,来说明一下,arm初始化的时候,会通过create_mapping来创建一些页表,比如map_lowmem就会调用 create_mapping函数来建立整个低端内存的映射。
同样地在函数devicemaps_init中会有如下代码:
967 ____map.pfn = __phys_to_pfn(virt_to_phys(vectors_page));
968 ____map.virtual = 0xffff0000;
969 ____map.length = PAGE_SIZE;
970 ____map.type = MT_HIGH_VECTORS;
971 ____create_mapping(&map);
这里有一点需要说明一点,虽然只映射了一个PAGE_SIZE,但是如果内核采用的二级页表(即存在pgd,pte),而不是一级页表(只有pgd)的话,会在create_mapping函数中,分配512个pte项(即512个pte指针ptep),远远大于KM_TYPE_NR个数。但是如果采用一级页表的话,这就会有问题,这种情况应该不能用kmap_atomic函数,因为通过TOP_PTE(vaddr)宏是得不到ptep的,因此目前代码中有如下保护:
67 #ifdef CONFIG_DEBUG_HIGHMEM
68 ____/*
69 ____ * With debugging enabled, kunmap_atomic forces that entry to 0.
70 ____ * Make sure it was indeed properly unmapped.
71 ____ */
72____BUG_ON(!pte_none((TOP_PTE(vaddr))));
73 #endif
由此,我们可以看到kmap_atomic使用的是地址空间顶部的一小段地址空间(0xffff0000开始),内核逻辑将这一小段地址空间分成了若干个节(slot),每一节的大小是一个page的大小,可以用来映射一个page。虽然总共可用512个slot,但是只能用KM_TYPE_NR个,有点遗憾!!!
原文地址: http://blog.chinaunix.net/uid-26817832-id-3358944.html
内核 kmap_atomic分析相关推荐
- 《LINUX3.0内核源代码分析》第一章:内存寻址
https://blog.csdn.net/ekenlinbing/article/details/7613334 摘要:本章主要介绍了LINUX3.0内存寻址方面的内容,重点对follow_page ...
- 从源码和内核角度分析redis和nginx以及java NIO可以支持多大的并发
有人询问我网上一篇关于"redis为什么单线程这么快"的文章,我建议他不要看了,因为redis是单进程不是单线程,后面的意见不用看了,文章质量肯定不会很好,他也说了自己看了很久源码 ...
- linux内核自解压,Linux的初始内核自解压分析
Linux的初始内核自解压分析 (2009-03-27 19:46:46) 标签: it Linux的初始内核解压 2007-09-19 15:02 来源:论坛整理 作者:lucian_yao [网友 ...
- 重载内核全程分析笔记
标 题: [原创]重载内核全程分析笔记 作 者: Speeday 时 间: 2013-08-20,20:19:46 链 接: http://bbs.pediy.com/showthread.php?t ...
- Linux2.6 内核进程调度分析
Linux2.6 内核进程调度分析 进程的调度时机与引起进程调度的原因和进程调度的方式有关.在 2.6 中,除核心应用 主动调用调度器之外, 核心还在应用不完全感知的情况下在以下三种时机 ...
- windows 内核情景分析
原文很长:先转部分过来,有时间看一下: 一 windows 内核情景分析---说明 说明 本文结合<Windows内核情景分析>(毛德操著).<软件调试>(张银奎著).< ...
- Windows内核系统调用分析
系统调用 进程 --> 调用OS API:OS进程管理 --> 调配进程. 仅从用户进程角度,OS就像是一个被动响应的运行时库.Windows提供了一个系统调用界面作为外层,即Win32A ...
- Gloomy对Windows内核的分析
/Files/ddlzq/Gloomy对Windows内核的分析.pdf 转载于:https://www.cnblogs.com/ddlzq/archive/2010/09/03/1817244.ht ...
- 《LINUX3.0内核源代码分析》第二章:中断和异常 【转】
转自:http://blog.chinaunix.net/uid-25845340-id-2982887.html 摘要:第二章主要讲述linux如何处理ARM cortex A9多核处理器的中断.异 ...
最新文章
- linux挂载分区失败,Ubuntu分区挂载错误与Grub引导错误的修复
- asp.net控件开发基础(21)
- mysql left join on_mysql,left join on
- 【转】MyBatis缓存机制
- 时间戳转中国人能看得懂的日期格式 yy-mm-dd
- 域domain user用户对本地NTFS磁盘的写入权限问题
- AD如何清理过期电脑
- 小规模纳税人季度申报流程指导
- 内存——CPU、内存以及磁盘是如何交互的
- 陕西年内建成1万个5G基站,实现全省所有地级市覆盖5G网络
- oracle表分区设计_论oracle分区表的创建与维护
- 服务器定时关机 修改时间,服务器每周 设置定时关机
- 产品读书《极简生活法则》
- android listview 美化,Android界面美化 -- 自定义ListView分割线
- 我的物联网大学【第六章】:个人英雄主义和组织效率的矛盾
- 以太坊:Web3.js 0.20 使用说明
- 如何用matlab画紫罗兰,[转载]基于MATLAB的快速傅立叶分析程序设计
- 大学计算机基础实用教程重点知识,大学计算机基础实用操作教程
- 数据结构之快速排序算法(C语言版)
- 原子核的加法wy.xuexi.biz
热门文章
- [iphone]XML 解析 之 TBXML 介绍
- DLL动态链接库的工作原理
- 常见缓存算法和LRU与LFU的c++实现
- [云炬创业基础笔记]第七张创业团队测试9
- 科大星云诗社动态20210319
- 干货 | 机器学习正在面临哪些主要挑战?
- Ubuntu通过windows代理上网
- c++中的 单例模式(singleton)和双检测锁(Double-Checked Locking)
- 面向对象的C语言编程-DynamicLinkageGenericFunctions--C语言中的偷梁换柱
- 基于STM32,无人船岸基信息处理代码--python实现