Chinaunix首页 | 论坛 | 博客
  • 博客访问: 365811
  • 博文数量: 166
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2013-03-21 17:29
文章分类

全部博文(166)

文章存档

2015年(60)

2014年(99)

2013年(7)

我的朋友

分类: LINUX

2014-07-08 14:59:40

原文地址:linux meminfo 代码解析 作者:KYlinux

上篇文章对meminfo里的信息做出简单的解释了
那么内核怎么把meminfo信息动态反应到meminfo文件中呢
在内核 linux/fs/proc/proc_misc.c中

static int meminfo_read_proc(char *page, char **start, off_t off,
                     int count, int *eof, void *data)
{
     struct sysinfo i;
     int len;
     unsigned long committed;
     unsigned long allowed;                                                                           
     struct vmalloc_info vmi;
     long cached;

#define K(x) ((x) << (PAGE_SHIFT - 10))          
/**
 *该宏作用把存储单位传换成 kb
 */

     si_meminfo(&i);
     si_swapinfo(&i);
     /**
      *这两个函数是对struct sysinfo结构进行初始化的
      */

     committed = atomic_read(&vm_committed_space);
     allowed = ((totalram_pages - hugetlb_total_pages())
          * sysctl_overcommit_ratio / 100) + total_swap_pages;
          
      /**
      *其中这项根据上篇文章CommitLimit解释计算的
      */

     cached = global_page_state(NR_FILE_PAGES) -
               total_swapcache_pages - i.bufferram;
     if (cached < 0)
          cached = 0;

     get_vmalloc_info(&vmi);
     /*
      * Tagged format, for easy grepping and expansion.
      */

     len = sprintf(page,
          "MemTotal: %8lu kB\n"
          "MemFree: %8lu kB\n"
          "Buffers: %8lu kB\n"
          "Cached: %8lu kB\n"
          "SwapCached: %8lu kB\n"
          "Active: %8lu kB\n"
          "Inactive: %8lu kB\n"
#ifdef CONFIG_HIGHMEM
          "HighTotal: %8lu kB\n"
          "HighFree: %8lu kB\n"
          "LowTotal: %8lu kB\n"
          "LowFree: %8lu kB\n"
#endif
          "SwapTotal: %8lu kB\n"
          "SwapFree: %8lu kB\n"
          "Dirty:     %8lu kB\n"
          "Writeback: %8lu kB\n"
          "AnonPages: %8lu kB\n"
          "Mapped: %8lu kB\n"
          "Slab:      %8lu kB\n"
          "SReclaimable: %8lu kB\n"
          "SUnreclaim: %8lu kB\n"
          "PageTables: %8lu kB\n"
          "NFS_Unstable: %8lu kB\n"
          "Bounce: %8lu kB\n"
          "CommitLimit: %8lu kB\n"
          "Committed_AS: %8lu kB\n"
          "VmallocTotal: %8lu kB\n"
          "VmallocUsed: %8lu kB\n"
          "VmallocChunk: %8lu kB\n",
          K(i.totalram),
          K(i.freeram),
          K(i.bufferram),
          K(cached),
          K(total_swapcache_pages),
          K(global_page_state(NR_ACTIVE)),
          K(global_page_state(NR_INACTIVE)),
#ifdef CONFIG_HIGHMEM
          K(i.totalhigh),
          K(i.freehigh),
          K(i.totalram-i.totalhigh),
          K(i.freeram-i.freehigh),
#endif
          K(i.totalswap),
          K(i.freeswap),
          K(global_page_state(NR_FILE_DIRTY)),
          K(global_page_state(NR_WRITEBACK)),
          K(global_page_state(NR_ANON_PAGES)),
          K(global_page_state(NR_FILE_MAPPED)),
          K(global_page_state(NR_SLAB_RECLAIMABLE) +
                    global_page_state(NR_SLAB_UNRECLAIMABLE)),
          K(global_page_state(NR_SLAB_RECLAIMABLE)),
          K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
          K(global_page_state(NR_PAGETABLE)),
          K(global_page_state(NR_UNSTABLE_NFS)),
          K(global_page_state(NR_BOUNCE)),
          K(allowed),
          K(committed),
          (unsigned long)VMALLOC_TOTAL >> 10,
          vmi.used >> 10,
          vmi.largest_chunk >> 10
          );
          len += hugetlb_report_meminfo(page + len);

     return proc_calc_metrics(page, start, off, count, eof, len);
#undef K
}

其中sysinfo结构在 linux/kernel.h  定义:

struct sysinfo {
    long uptime; /* 启动到现在经过的时间 */
    unsigned long loads[3];
    /* 1, 5, and 15 minute load averages */
    unsigned long totalram; /* 总的可用的内存大小 */
    unsigned long freeram; /* 还未被使用的内存大小 */
    unsigned long sharedram; /* 共享的存储器的大小*/
    unsigned long bufferram; /* 的存储器的大小 */
    unsigned long totalswap; /* 交换区大小 */
    unsigned long freeswap; /* 还可用的交换区大小 */
    unsigned short procs; /* 当前进程数目 */
    unsigned short pad; /* explicit padding for m68k */
    unsigned long totalhigh; /* 总的高内存大小 */
    unsigned long freehigh; /* 可用的高内存大小 */
    unsigned int mem_unit; /* 以字节为单位的内存大小 */
    char _f[20-2*sizeof(long)-sizeof(int)];
};

而global_page_state()函数中的常量定义在 linux/mmzone.h

enum zone_stat_item {
     /* First 128 byte cacheline (assuming 64 bit words) */
     NR_FREE_PAGES,
     NR_INACTIVE,
     NR_ACTIVE,
     NR_ANON_PAGES, /* Mapped anonymous pages */
     NR_FILE_MAPPED, /* pagecache pages mapped into pagetables.
                only modified from process context */

     NR_FILE_PAGES,
     NR_FILE_DIRTY,
     NR_WRITEBACK,
     /* Second 128 byte cacheline */
     NR_SLAB_RECLAIMABLE,
     NR_SLAB_UNRECLAIMABLE,
     NR_PAGETABLE,      /* used for pagetables */
     NR_UNSTABLE_NFS,     /* NFS unstable pages */
     NR_BOUNCE,
     NR_VMSCAN_WRITE,
#ifdef CONFIG_NUMA
     NUMA_HIT,      /* allocated in intended node */
     NUMA_MISS,      /* allocated in non intended node */
     NUMA_FOREIGN,      /* was intended here, hit elsewhere */
     NUMA_INTERLEAVE_HIT, /* interleaver preferred this zone */
     NUMA_LOCAL,      /* allocation from local node */
     NUMA_OTHER,      /* allocation from other node */
#endif
     NR_VM_ZONE_STAT_ITEMS
};

其中通过global_page_state()函数根据 zone_stat_item 结构的常量得到不同区大小,会跟 vm_stat[NR_VM_ZONE_STAT_ITEMS]对应起来。
vm_stat[]是统计各区的大小。

内核 linux/vmstat.h定义:

static inline unsigned long global_page_state(enum zone_stat_item item)    
{
    long x = atomic_long_read(&vm_stat[item]);
#ifdef CONFIG_SMP
    if (x < 0)
        x = 0;
#endif
    return x;
}

下面根据struct sysinfo结构,简单分析CPU和内存使用信息。
#include <stdio.h>
#include <linux/unistd.h> /* 包含调用 _syscallX 宏等相关信息*/
#include <linux/kernel.h> /* 包含sysinfo结构体信息*/
int main(int argc, char *agrv[])
{
    struct sysinfo s_info;
    int error;
    error = sysinfo(&s_info);
    printf("\n\ncode error=%d\n",error);
    printf("Uptime = %ds\nLoad: 1 min%d / 5 min %d / 15 min %d\n"
     "RAM: total %d / free %d /shared%d\n"
     "Memory in buffers = %d\nSwap:total%d/free%d\n"
     "Number of processes = %d\n",
     s_info.uptime, s_info.loads[0],
     s_info.loads[1], s_info.loads[2],
     s_info.totalram, s_info.freeram,
     s_info.totalswap, s_info.freeswap,
     s_info.procs);
    return 0;
}
结果:
code error=0
Uptime = 8329s
Load: 1 min37152 / 5 min 37792 / 15 min 48672
RAM: total 519659520 / free 9031680 /shared1003474944
Memory in buffers = 937451520
Swap:total223/free-1078732672
Number of processes = -1078732608
阅读(810) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~