在 ramfs 中,如何根据 NUMA 节点跟踪文件访问模式?
Posted
技术标签:
【中文标题】在 ramfs 中,如何根据 NUMA 节点跟踪文件访问模式?【英文标题】:in ramfs, how can i trace file access pattern in terms of NUMA node? 【发布时间】:2017-05-09 16:46:35 【问题描述】:由于Ramfs
将文件存储到内存中并且该内存绑定到某个NUMA
节点,我认为有一些方法可以跟踪请求文件的nodes
(例如a.txt
)。
例如,如果有 4 个 NUMA 节点及其本地内存,则访问 a.txt
的节点列表可能是 0 0 0 1 1 0 2 2 2 0 3 3 3 3 3
。
一种可能的解决方案如下:
-
查找低级
ramfs
文件操作函数(如read
或write
)
获取正在执行该函数的线程的节点号
将该节点号存储到某处(例如 a.txt 的 inode
或其他内容)
但是我没有找到ramfs这么低级的功能,无法继续。
有没有办法做到这一点?
【问题讨论】:
什么是 Ramfs?是Linux吗?你的机器是 NUMA 吗(有超过 1 个插槽,每个插槽都有自己的集成内存控制器)? NUMA 放置物理 4KB(或 2MB)页面。有用于 linux 的 libnuma (man7.org/linux/man-pages/man3/numa.3.html),如果来自 Ramfs 的数据是mmap
ed,要查找数据在哪里,您可以尝试 numa_move_pages
/move_pages
(man7.org/linux/man-pages/man2/move_pages.2.html) 在节点中使用 NULL:“节点也可以为 NULL,在这种情况下 move_pages() 不会移动任何页面,而是会在状态数组中返回每个页面当前所在的节点。"
我的问题是:我怎么知道哪个节点需要数据,而不是数据驻留在哪个节点。更具体地说,我想在 Ramfs 中为每个文件(每个 inode)保留日志。日志是 NUMA 节点的列表,并会告诉我们哪些节点访问了该文件。
Bot,请多解释。是Linux(哪个内核版本)?是tmpfs吗?程序如何访问文件/文件(是读取、mmap、写入还是什么)。是你的程序(你能修改它)还是很多不是你的程序?您可以更改什么(补丁+重新编译内核,补丁 ramfs 兼容模块,FUSE;您可以使用 ftrace/stap/dprobe/strace/ltrace 吗?您不能在 inode 中存储太多。(PS 如果是您的任务)当然,告诉我们这门课程是关于什么的,内核编程还是 unix 编程还是什么?)
感谢您的好意,就像我会经常访问***一样。基本上我是研究生院的新生,我研究(未来)大规模非易失性基于内存的文件系统的 NUMA 效应。我想我需要了解一般基于内存的文件系统的文件访问模式(就 NUMA 节点而言)。所以我选择了 Ramfs(因为我不得不假设没有磁盘设备)。我的 linux 版本是 4.7.4(如果需要,我可以使用其他内核版本启动)。这只是关于 Ramfs 而不是 Tmpfs,所以我什至不需要考虑磁盘。
使用简单的读写。我想我可以尝试修补 ramfs 兼容的模块,但我对 FUSE 一无所知。我尝试使用 ftrace 来跟踪 ramfs 写入,但由于某种原因,没有看到“ramfs.write”(因为我在 ftrace 方面很差)。
【参考方案1】:
不是一个完整的解决方案,而是一些想法。
一些fs将文件存储到内存中,并且该内存绑定到某些NUMA节点,..我认为存在一些方法可以跟踪请求文件的节点
在现代 Linux(4.x 内核)中有许多方法可以跟踪文件访问(一些基本类型;open/read/write/mmap;但不是 mmaped 区域的使用)。对于单个 pid,您可以使用strace
系统调用跟踪器(或ltrace -S
,它还可以捕获库调用)。对于许多 pid(完整系统跟踪),您可以尝试 sysdig
。
也有可以使用的内核内(和树外内核模式)跟踪框架。就像基于 perf + probe / ftrace (trace-cmd) 的东西,或者更高级的跟踪解决方案,如 stap
/dtrace
/lttng
,并定义并启用了相应的跟踪点。 Gregg 在他的presentations 和site 中列出了更多工具,都是经典的(VFS 的小列表)https://www.slideshare.net/brendangregg/linux-systems-performance-2016#slide=7;和基于密件抄送/eBPF:https://www.slideshare.net/brendangregg/designing-tracing-tools-67693476#slide=3。
大多数系统范围的工具已经有很好的框架来执行时间戳和进程记帐,并将大量跟踪数据从内核模式下载到一些日志/转储文件中。其中一些(stap/dtrace/bcc + 探针)允许您编写小代码片段以在调用跟踪函数时执行。
Gregg 工具的示例是“iosnoop”(它位于debugfs & /sys/kernel/debug/tracing
之上,即ftrace 和trace-cmd
)。它显示了每个真实读/写操作的延迟(进入真实磁盘;不能访问页面缓存中已读取的数据,就像在 ramfs 中一样):
nop ftraceing
两个事件:events/block/block_rq_insert 和 events/block/block_rq_complete)
(通过将 iosnoop src 中的 cat trace
行替换为 cat trace | tee -a ~/iotrace.$$.dump
并查看它来添加原始跟踪的调试保存)
查找低级ramfs文件操作函数(如读或写)
不幸的是,ramfs 是太基本的 FS,无法实现任何有趣的东西。 ramfs有地址空间操作和文件操作:
http://elixir.free-electrons.com/linux/v4.7.4/source/fs/ramfs/inode.c#L46
static const struct address_space_operations ramfs_aops =
.readpage = simple_readpage,
.write_begin = simple_write_begin,
.write_end = simple_write_end,
.set_page_dirty = __set_page_dirty_no_writeback,
;
http://elixir.free-electrons.com/linux/v4.7.4/source/fs/ramfs/file-mmu.c#L33
const struct file_operations ramfs_file_operations =
.read_iter = generic_file_read_iter,
.write_iter = generic_file_write_iter,
.mmap = generic_file_mmap,
.fsync = noop_fsync,
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
.llseek = generic_file_llseek,
;
simple_
/ generic_file_
操作在 libfs/ 或 mm/ 中定义(对于 elixir/lxr 网站,您只需单击函数即可找到其定义和用法)http://elixir.free-electrons.com/linux/v4.7.4/source/fs/libfs.c#L409,它们还用于更多linux FS 实现,因此无条件跟踪它们可能是不安全的。
你可以尝试重写 ramfs 的实现;只需在具有不同名称的变体中定义类似的 simple_
/ generic_file_
操作即可。您将只能追踪它们。
获取正在执行该函数的线程的节点号
我认为,还有另一种方法。检测到访问时获取进程/线程的pid/tid;但不要做任何事情来查找 NUMA 节点(您可能会修改 ramfs 实现并添加您自己的 aops
变体,读取 current
ptr 并从 struct task_struct
找到 NUMA 节点;但是在哪里写它?)。
当有高级跟踪框架时更容易 - 是记录调度程序的所有操作 - 何时以及为每个 CPU 计划了哪个 pid(如在kernelshark 或在sched_
函数的 perf/stap/lttng 跟踪中 - sched_switch
可能带有参数;甚至 ftrace 也允许您在单个过滤器中组合两个跟踪,io 和 sched)。
您将有一些后处理来对输出进行排序和组合信息,但这应该可以完成任务
将该节点号存储到某处(例如 a.txt 的 inode 或其他内容)
不要重新发明***,使用跟踪框架。
【讨论】:
对于真实磁盘也可以使用 blktrace:cse.unsw.edu.au/~aaronc/iosched/doc/blktrace.html(每 CPU 跟踪到转储文件中,可以使用 blkparse 查看)以上是关于在 ramfs 中,如何根据 NUMA 节点跟踪文件访问模式?的主要内容,如果未能解决你的问题,请参考以下文章
在 linux(CentOS)/多处理器设置中,如何将 CPU 内核分配给 NUMA 节点?