参考:
- 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/
学习笔记
性能优化
- Linux内核性能剖析的方法学和主要工具
- 极客时间Linux性能优化实战笔记 —— 开篇
- 极客时间Linux性能优化实战笔记 —— CPU性能篇
- 极客时间Linux性能优化实战笔记 —— 内存性能篇
- 极客时间Linux性能优化实战笔记 —— IO性能篇
- 极客时间Linux性能优化实战笔记 —— 网络性能篇
- 鲲鹏性能优化十板斧
- Linux Performance Tuning: Dealing with Memory and Disk IO
- Performance Tuning on Linux — Disk I/O
- Disk I/O issues: Understanding and fixing them to boost system performance
- 0x.Tools: Always-on Profiling for Production Systems
- 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内核页表的映射信息,如虚拟地址范围以及地址属性。