IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

Linux TASK_IO_ACCOUNTING功能以及如何使用

Erlang非业余研究 2012-03-11 22:09:56 累计浏览 3,199 次
本机暂存
    在过去我们了解系统IO的情况大多数是通过iostat来获取的,这个粒度只能精确到每个设备。通常我们会想了解每个进程,线程层面发起了多少IO,在Linux 2.6.20之前除了用systemtap这样的工具来实现是没有其他方法的,因为系统没有暴露这方面的统计。 disktop per设备per应用层面的IO读写统计,可以参考我之前写的,见这里.

    透过lxr的代码确认,在Linux 2.6.20以后引入了TASK_IO_ACCOUNTING功能,通过把每个线程和进程的io活动通过/proc/pid/io导出大大方便了用户,这里需要注意的是RHEL 5U4基于2.6.18内核但是他们backport了这个功能,并由此催生了相应的了解per进程Io活动的工具如pidstat和iotop, 这两个软件工作的时候截图如下:

    

     pidstat可以看到带层次线程IO活动

    

     iotop能看到扁平线程IO活动

    通过strace来了解到这二个软件关于IO活动部分输入源都是/proc/pid/io, 让我们来了解下这个文件:

# cat /proc/self/io
rchar: 1956
wchar: 0
syscr: 7
syscw: 0
read_bytes: 0
write_bytes: 0
cancelled_write_bytes: 0

    这个文件后三个参数是IO记账功能新添加的,我们来了解下他们的意义,摘抄从man pidstat:

     kB_rd/s

     Number of kilobytes the task has caused to be read from disk per second.

     kB_wr/s

     Number of kilobytes the task has caused, or shall cause to be written to disk per second.

     kB_ccwr/s

     Number of kilobytes whose writing to disk has been cancelled by the task. This may occur when the task truncates some dirty page-

     cache. In this case, some IO which another task has been accounted for will not be happening.

    接着我们再来看下内核如何统计这三个值的,在RHEL 5U4源码数下简单的grep下:

[linux-2.6.18.x86_64]$ grep -rin task_io_account_ .
./block/ll_rw_blk.c:3286:               task_io_account_read(bio->bi_size);
./include/linux/task_io_accounting_ops.h:8:static inline void task_io_account_read(size_t bytes)
./include/linux/task_io_accounting_ops.h:13:static inline void task_io_account_write(size_t bytes)
./include/linux/task_io_accounting_ops.h:18:static inline void task_io_account_cancelled_write(size_t bytes)
./include/linux/task_io_accounting_ops.h:30:static inline void task_io_account_read(size_t bytes)
./include/linux/task_io_accounting_ops.h:34:static inline void task_io_account_write(size_t bytes)
./include/linux/task_io_accounting_ops.h:38:static inline void task_io_account_cancelled_write(size_t bytes)
./fs/direct-io.c:671:           task_io_account_write(len);
./fs/cifs/file.c:2221:                  task_io_account_read(bytes_read);
./fs/buffer.c:965:                              task_io_account_write(PAGE_CACHE_SIZE);
./fs/buffer.c:3400:                     task_io_account_cancelled_write(PAGE_CACHE_SIZE);
./mm/truncate.c:47:             task_io_account_cancelled_write(PAGE_CACHE_SIZE);
./mm/page-writeback.c:649:                                      task_io_account_write(PAGE_CACHE_SIZE);
./mm/readahead.c:180:           task_io_account_read(PAGE_CACHE_SIZE);

    可以看出统计力度还是比较粗的。

    同时Io记账相关的proc导出位于 fs/proc/base.c:

#ifdef CONFIG_TASK_IO_ACCOUNTING
static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
{
 ...
        return sprintf(buffer,
                        "rchar: %llu\\n"
                        "wchar: %llu\\n"
                        "syscr: %llu\\n"
                        "syscw: %llu\\n"
                        "read_bytes: %llu\\n"
                        "write_bytes: %llu\\n"
                        "cancelled_write_bytes: %llu\\n",
                        rchar, wchar, syscr, syscw,
                        ioac.read_bytes, ioac.write_bytes,
                        ioac.cancelled_write_bytes);
}

    简单的分析了下TASK_IO_ACCOUNTING运作方式,对了解每个进程的IO活动还是很有帮助的。另外再罗嗦下在RHEL 5U4是可以用这个功能的。

同分类推荐文章

  1. 从零重建 macOS 开发机:可复现的环境初始化流程 (2026-06-14 20:36:00)
  2. 百度物理网络监控工具开源第二弹:毫秒级监控工具 baize,让你的网络问题无处遁形 (2026-06-11 08:10:28)
  3. How to Set Up Homebrew Tap for Private CLI Tools: A Complete Guide (2026-05-27 02:13:03)

查看更多 DevOps 文章 →

建议继续学习

  1. Linux如何统计进程的CPU利用率 (累计阅读 16,308)
  2. 我的 RHCA 之路 (累计阅读 14,013)
  3. Linux内存点滴 用户进程内存空间 (累计阅读 13,232)
  4. 给程序员新手的一些建议 (累计阅读 13,090)
  5. Linux 性能监控、测试、优化工具 (累计阅读 13,013)
  6. 关于linux内存free的一些事情 (累计阅读 12,869)
  7. ps - 按进程消耗内存多少排序 (累计阅读 12,690)
  8. Google怎么用linux (累计阅读 12,582)
  9. Linux Used内存到底哪里去了? (累计阅读 11,868)
  10. find命令的一点注意事项 (累计阅读 11,867)