Linux内核学习
参考:
- https://makelinux.github.io/kernel/map/
- https://www.cnblogs.com/xuxinkun/p/5541894.html
- https://www.cnblogs.com/zhengchunyuan/p/9639245.html
- https://github.com/plantegg/programmer_case
- https://github.com/dendibakh/perf-ninja/tree/main
- https://easyperf.net/notes/
- LKP:https://github.com/intel/lkp-tests
学习笔记
性能优化
-
Disk I/O issues: Understanding and fixing them to boost system performance
-
https://github.com/scottchiefbaker/dool#dool
- Dool is a Python3 compatible fork of Dstat
OS Noise
Linux内核技术实战课
内核文档
- https://lwn.net/Kernel/Index/
- https://www.kernel.org/doc/html/latest/
- linux新手:Kernel Newbies regional pages
- 论文:
- Man手册:https://kernel.org/doc/man-pages/
- 内存管理相关:
- Understanding the Linux Virtual Memory Manager, online book by Mel Gorman.
- What every programmer should know about memory, article series by Ulrich Drepper, parts:
one two three four five - Ars technica ram guide, article series by Jon "Hannibal" Stokes, parts:
one two three Cacheing Bandwidth and Latency
- 内核数据结构
- 并发
- 调度
- 块设备
- 内核启动参数(kernel boot parameters)
零碎知识
-
获得内核编译过程中的某个.c文件的预处理后的文件,比如kernel/cgroup/cgroup.c
make kernel/cgroup/cgroup.i
类似的,可以获取对应的.s文件或者.o文件:
make kernel/cgroup/cgroup.s
或者make kernel/cgroup/cgroup.o
-
驱动黑名单
-
log延迟输出
通过bmc连接服务器,有时由于log输出太快来不及抓到想要的信息,那么可以用这个方式增加log输出的时延。
boot_delay= Milliseconds to delay each printk during boot.
Values larger than 10 seconds (10000) are changed to
no delay (0).
Format: integer
比如每个log输出时延迟10ms:
... boot_delay=10
内存
- 查看系统中有哪些slab被合并了,或者称为slab alias
cd tools/vm
make
./slabinfo -a
- 查看page的状态,系统或者进程视图
cd tools/vm
make
tools/vm/page-types.c
这个功能以来内核在/proc文件中导出的三个文件节点:fs\proc\page.c
/proc/kpagecgroup # 获取page的memcg信息
/proc/kpagecount # 获取page_mapcount(page),前提比如是文件或者匿名页
/proc/kpageflags # 获取page的flags,会转换为include\uapi\linux\kernel-page-flags.h中对应的标志位
Linux中的内存消耗数据
- http://linuxperf.com/?p=142
- /proc/meminfo之谜完全揭秘
- https://blog.csdn.net/whbing1471/article/details/105468139
- 根据/proc/meminfo了解统计主机内存使用
- 查看进程的内存使用信息
- linux中的内核消耗图解
进程
- 判断一个用户进程是不是主线程:对于主线程,task_struct的pid和tgid相等,对于其他线程,pid表示线程自己的pid,tgid表示这个线程所属的线程组的主线程的pid。线程组中所有线程的task_struct通过thread_group节点链在一起
- linux 查看线程数的方法
IO
原子操作
常用节点
/proc
参考:
- https://man7.org/linux/man-pages/man5/proc.5.html
- https://www.kernel.org/doc/html/latest/admin-guide/sysctl/index.html#documentation-for-proc-sys
- http://www.wowotech.net/memory_management/meminfo_1.html
- 内核文档:The /proc Filesystem
内存
/proc/iomem 和 /proc/ioport
文件:kernel/resource.c
iomem:查看当前注册的物理地址
ioport:查看当前注册的IO端口信息
相关代码
struct resource ioport_resource = {
.name = "PCI IO",
.start = 0,
.end = IO_SPACE_LIMIT,
.flags = IORESOURCE_IO,
};
EXPORT_SYMBOL(ioport_resource);
struct resource iomem_resource = {
.name = "PCI mem",
.start = 0,
.end = -1,
.flags = IORESOURCE_MEM,
};
EXPORT_SYMBOL(iomem_resource);
static int r_show(struct seq_file *m, void *v)
{
struct resource *root = PDE_DATA(file_inode(m->file));
struct resource *r = v, *p;
unsigned long long start, end;
int width = root->end < 0x10000 ? 4 : 8;
int depth;
/*计算子节点的缩进量*/
for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent)
if (p->parent == root)
break;
/* 权限检查,如果不是超级用户,那么看到的起始和结束物理地址都是0 */
if (file_ns_capable(m->file, &init_user_ns, CAP_SYS_ADMIN)) {
start = r->start;
end = r->end;
} else {
start = end = 0;
}
seq_printf(m, "%*s%0*llx-%0*llx : %s\n",
depth * 2, "",
width, start,
width, end,
r->name ? r->name : "<BAD>");
return 0;
}
static int __init ioresources_init(void)
{
proc_create_seq_data("ioports", 0, NULL, &resource_op,
&ioport_resource);
proc_create_seq_data("iomem", 0, NULL, &resource_op, &iomem_resource);
return 0;
}
__initcall(ioresources_init);
/proc/meminfo
/sys/
/sys/kernel/debug
- /sys/kernel/debug/kernel_page_talbes
代码位置:arch/arm/mm/dump.c
通过这个节点可以查看linux内核页表的映射信息,如虚拟地址范围以及地址属性。
本文来自博客园,作者:摩斯电码,未经同意,禁止转载