Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Data gathering module for Linux-VM Monitor Stream, Stage 1.
0004  * Collects data related to memory management.
0005  *
0006  * Copyright IBM Corp. 2003, 2006
0007  *
0008  * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <linux/init.h>
0013 #include <linux/errno.h>
0014 #include <linux/kernel_stat.h>
0015 #include <linux/pagemap.h>
0016 #include <linux/swap.h>
0017 #include <linux/slab.h>
0018 #include <asm/io.h>
0019 
0020 #include "appldata.h"
0021 
0022 
0023 #define P2K(x) ((x) << (PAGE_SHIFT - 10))   /* Converts #Pages to KB */
0024 
0025 /*
0026  * Memory data
0027  *
0028  * This is accessed as binary data by z/VM. If changes to it can't be avoided,
0029  * the structure version (product ID, see appldata_base.c) needs to be changed
0030  * as well and all documentation and z/VM applications using it must be
0031  * updated.
0032  */
0033 struct appldata_mem_data {
0034     u64 timestamp;
0035     u32 sync_count_1;       /* after VM collected the record data, */
0036     u32 sync_count_2;   /* sync_count_1 and sync_count_2 should be the
0037                    same. If not, the record has been updated on
0038                    the Linux side while VM was collecting the
0039                    (possibly corrupt) data */
0040 
0041     u64 pgpgin;     /* data read from disk  */
0042     u64 pgpgout;        /* data written to disk */
0043     u64 pswpin;     /* pages swapped in  */
0044     u64 pswpout;        /* pages swapped out */
0045 
0046     u64 sharedram;      /* sharedram is currently set to 0 */
0047 
0048     u64 totalram;       /* total main memory size */
0049     u64 freeram;        /* free main memory size  */
0050     u64 totalhigh;      /* total high memory size */
0051     u64 freehigh;       /* free high memory size  */
0052 
0053     u64 bufferram;      /* memory reserved for buffers, free cache */
0054     u64 cached;     /* size of (used) cache, w/o buffers */
0055     u64 totalswap;      /* total swap space size */
0056     u64 freeswap;       /* free swap space */
0057 
0058 // New in 2.6 -->
0059     u64 pgalloc;        /* page allocations */
0060     u64 pgfault;        /* page faults (major+minor) */
0061     u64 pgmajfault;     /* page faults (major only) */
0062 // <-- New in 2.6
0063 
0064 } __packed;
0065 
0066 
0067 /*
0068  * appldata_get_mem_data()
0069  *
0070  * gather memory data
0071  */
0072 static void appldata_get_mem_data(void *data)
0073 {
0074     /*
0075      * don't put large structures on the stack, we are
0076      * serialized through the appldata_ops_mutex and can use static
0077      */
0078     static struct sysinfo val;
0079     unsigned long ev[NR_VM_EVENT_ITEMS];
0080     struct appldata_mem_data *mem_data;
0081 
0082     mem_data = data;
0083     mem_data->sync_count_1++;
0084 
0085     all_vm_events(ev);
0086     mem_data->pgpgin     = ev[PGPGIN] >> 1;
0087     mem_data->pgpgout    = ev[PGPGOUT] >> 1;
0088     mem_data->pswpin     = ev[PSWPIN];
0089     mem_data->pswpout    = ev[PSWPOUT];
0090     mem_data->pgalloc    = ev[PGALLOC_NORMAL];
0091     mem_data->pgalloc    += ev[PGALLOC_DMA];
0092     mem_data->pgfault    = ev[PGFAULT];
0093     mem_data->pgmajfault = ev[PGMAJFAULT];
0094 
0095     si_meminfo(&val);
0096     mem_data->sharedram = val.sharedram;
0097     mem_data->totalram  = P2K(val.totalram);
0098     mem_data->freeram   = P2K(val.freeram);
0099     mem_data->totalhigh = P2K(val.totalhigh);
0100     mem_data->freehigh  = P2K(val.freehigh);
0101     mem_data->bufferram = P2K(val.bufferram);
0102     mem_data->cached    = P2K(global_node_page_state(NR_FILE_PAGES)
0103                 - val.bufferram);
0104 
0105     si_swapinfo(&val);
0106     mem_data->totalswap = P2K(val.totalswap);
0107     mem_data->freeswap  = P2K(val.freeswap);
0108 
0109     mem_data->timestamp = get_tod_clock();
0110     mem_data->sync_count_2++;
0111 }
0112 
0113 
0114 static struct appldata_ops ops = {
0115     .name      = "mem",
0116     .record_nr = APPLDATA_RECORD_MEM_ID,
0117     .size      = sizeof(struct appldata_mem_data),
0118     .callback  = &appldata_get_mem_data,
0119     .owner     = THIS_MODULE,
0120     .mod_lvl   = {0xF0, 0xF0},      /* EBCDIC "00" */
0121 };
0122 
0123 
0124 /*
0125  * appldata_mem_init()
0126  *
0127  * init_data, register ops
0128  */
0129 static int __init appldata_mem_init(void)
0130 {
0131     int ret;
0132 
0133     ops.data = kzalloc(sizeof(struct appldata_mem_data), GFP_KERNEL);
0134     if (!ops.data)
0135         return -ENOMEM;
0136 
0137     ret = appldata_register_ops(&ops);
0138     if (ret)
0139         kfree(ops.data);
0140 
0141     return ret;
0142 }
0143 
0144 /*
0145  * appldata_mem_exit()
0146  *
0147  * unregister ops
0148  */
0149 static void __exit appldata_mem_exit(void)
0150 {
0151     appldata_unregister_ops(&ops);
0152     kfree(ops.data);
0153 }
0154 
0155 
0156 module_init(appldata_mem_init);
0157 module_exit(appldata_mem_exit);
0158 
0159 MODULE_LICENSE("GPL");
0160 MODULE_AUTHOR("Gerald Schaefer");
0161 MODULE_DESCRIPTION("Linux-VM Monitor Stream, MEMORY statistics");