MOS Source Code
Loading...
Searching...
No Matches
mmstat.c
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#include "mos/mm/mmstat.h"
4
10#include "mos/syslog/printk.h"
11#include "mos/tasks/process.h"
13
14#include <mos/mos_global.h>
15#include <mos/types.h>
16#include <mos_stdlib.h>
17
18typedef struct
19{
20 size_t npages;
22
24
26 [MEM_PAGETABLE] = "PageTable", //
27 [MEM_SLAB] = "Slab", //
28 [MEM_PAGECACHE] = "PageCache", //
29 [MEM_KERNEL] = "Kernel", //
30 [MEM_USER] = "User", //
31};
32
33void mmstat_inc(mmstat_type_t type, size_t size)
34{
36 stat[type].npages += size;
37}
38
39void mmstat_dec(mmstat_type_t type, size_t size)
40{
42 stat[type].npages -= size;
43}
44
45// ! sysfs support
46
48{
49 char size_buf[32];
50 format_size(size_buf, sizeof(size_buf), pmm_total_frames * MOS_PAGE_SIZE);
51 sysfs_printf(f, "%-20s: %s, %zu pages\n", "Total", size_buf, pmm_total_frames);
52
53 format_size(size_buf, sizeof(size_buf), pmm_allocated_frames * MOS_PAGE_SIZE);
54 sysfs_printf(f, "%-20s: %s, %zu pages\n", "Allocated", size_buf, pmm_allocated_frames);
55
56 format_size(size_buf, sizeof(size_buf), pmm_reserved_frames * MOS_PAGE_SIZE);
57 sysfs_printf(f, "%-20s: %s, %zu pages\n", "Reserved", size_buf, pmm_reserved_frames);
58
59 for (u32 i = 0; i < _MEM_MAX_TYPES; i++)
60 {
61 format_size(size_buf, sizeof(size_buf), stat[i].npages * MOS_PAGE_SIZE);
62 sysfs_printf(f, "%-20s: %s, %zu pages\n", mem_type_names[i], size_buf, stat[i].npages);
63 }
64 return true;
65}
66
68{
69 const pfn_t pfn = (pfn_t) sysfs_file_get_data(f);
70 if (pfn >= pmm_total_frames)
71 {
72 pr_warn("mmstat: invalid pfn %llu", pfn);
73 return false;
74 }
75
76 const phyframe_t *frame = pfn_phyframe(pfn);
77 sysfs_printf(f, "pfn: %llu\n", pfn);
78 sysfs_printf(f, "type: %s\n", frame->state == PHYFRAME_FREE ? "free" : frame->state == PHYFRAME_ALLOCATED ? "allocated" : "reserved");
79 sysfs_printf(f, "order: %u\n", frame->order);
80 if (frame->state == PHYFRAME_ALLOCATED)
81 sysfs_printf(f, "refcnt: %zu\n", frame->allocated_refcount);
82
83 return true;
84}
85
86static size_t mmstat_sysfs_phyframe_stat_store(sysfs_file_t *f, const char *buf, size_t count, off_t offset)
87{
88 MOS_UNUSED(offset);
89
90 const pfn_t pfn = strntoll(buf, NULL, 10, count);
91 if (pfn >= pmm_total_frames)
92 {
93 pr_warn("mmstat: invalid pfn %llu", pfn);
94 return -EINVAL;
95 }
96
97 sysfs_file_set_data(f, (void *) pfn);
98 return count;
99}
100
102{
103 const pid_t pid = (pid_t) (ptr_t) sysfs_file_get_data(f);
104 if (!pid)
105 {
106 pr_warn("mmstat: invalid pid %d", pid);
107 return false;
108 }
109
110 const process_t *proc = process_get(pid);
111 if (!proc)
112 {
113 pr_warn("mmstat: invalid pid %d", pid);
114 return false;
115 }
116
117 mm_context_t *mmctx = proc->mm;
118 spinlock_acquire(&mmctx->mm_lock);
119
120 pagetable_iter_t iter;
121 pagetable_iter_init(&iter, mmctx->pgd, 0, MOS_USER_END_VADDR);
122
124 while ((range = pagetable_iter_next(&iter)))
125 {
126 if (!range->present)
127 continue;
128
129 sysfs_printf(f, PTR_RANGE, range->vaddr, range->vaddr_end);
130 sysfs_printf(f, " %pvf " PFN_RANGE, (void *) &range->flags, range->pfn, range->pfn_end);
131 sysfs_printf(f, "\n");
132 }
133
134 spinlock_release(&mmctx->mm_lock);
135
136 return true;
137}
138
140{
141 const pid_t pid = (pid_t) (ptr_t) sysfs_file_get_data(f);
142 if (!pid)
143 {
144 pr_warn("mmstat: invalid pid %d", pid);
145 return false;
146 }
147
148 process_t *proc = process_get(pid);
149 if (!proc)
150 {
151 pr_warn("mmstat: invalid pid %d", pid);
152 return false;
153 }
154
155 int i = 0;
156 spinlock_acquire(&proc->mm->mm_lock);
157 list_foreach(vmap_t, vmap, proc->mm->mmaps)
158 {
159 sysfs_printf(f, "%3d: ", i++);
160 sysfs_printf(f, "%pvm\n", (void *) vmap);
161 }
162 spinlock_release(&proc->mm->mm_lock);
163 return true;
164}
165
166static size_t mmstat_sysfs_store_pid(sysfs_file_t *f, const char *buf, size_t count, off_t offset)
167{
168 MOS_UNUSED(offset);
169
170 const pid_t pid = strntoll(buf, NULL, 10, count);
171 if (!pid)
172 {
173 pr_warn("mmstat: invalid pid %d", pid);
174 sysfs_file_set_data(f, (void *) 0);
175 return -EINVAL;
176 }
177
178 sysfs_file_set_data(f, (void *) (ptr_t) pid);
179 return count;
180}
181
188
#define MOS_ASSERT(cond)
Definition assert.h:14
#define MOS_PAGE_SIZE
Definition autoconf.h:6
MOSAPI void format_size(char *buf, size_t buf_size, u64 size)
Definition mos_stdlib.c:103
MOSAPI s64 strntoll(const char *str, char **endptr, int base, size_t n)
Definition mos_stdlib.c:73
#define list_foreach(t, v, h)
Iterate over a list.
Definition list.h:83
#define pfn_phyframe(pfn)
Definition pmm.h:81
size_t pmm_total_frames
Definition pmm.c:16
size_t pmm_reserved_frames
Definition pmm.h:83
size_t pmm_allocated_frames
Definition pmm.h:83
void pagetable_iter_init(pagetable_iter_t *it, pgd_t pgd, ptr_t vaddr, ptr_t end)
Initialize a pagetable iterator.
Definition iterator.c:82
pagetable_iter_range_t * pagetable_iter_next(pagetable_iter_t *it)
Get the next page table range.
Definition iterator.c:97
static bool mmstat_sysfs_pagetable_show(sysfs_file_t *f)
Definition mmstat.c:101
void mmstat_dec(mmstat_type_t type, size_t size)
Decrement the memory usage statistics.
Definition mmstat.c:39
static bool mmstat_sysfs_stat(sysfs_file_t *f)
Definition mmstat.c:47
void mmstat_inc(mmstat_type_t type, size_t size)
Increment the memory usage statistics.
Definition mmstat.c:33
static bool mmstat_sysfs_phyframe_stat_show(sysfs_file_t *f)
Definition mmstat.c:67
static sysfs_item_t mmstat_sysfs_items[]
Definition mmstat.c:182
static bool mmstat_sysfs_vmaps_show(sysfs_file_t *f)
Definition mmstat.c:139
static size_t mmstat_sysfs_phyframe_stat_store(sysfs_file_t *f, const char *buf, size_t count, off_t offset)
Definition mmstat.c:86
static size_t mmstat_sysfs_store_pid(sysfs_file_t *f, const char *buf, size_t count, off_t offset)
Definition mmstat.c:166
const char * mem_type_names[_MEM_MAX_TYPES]
Definition mmstat.c:25
static vmap_global_mstat_t stat[_MEM_MAX_TYPES]
Definition mmstat.c:23
mmstat_type_t
Definition mmstat.h:7
@ _MEM_MAX_TYPES
Definition mmstat.h:14
@ MEM_PAGECACHE
Definition mmstat.h:10
@ MEM_USER
Definition mmstat.h:12
@ MEM_PAGETABLE
Definition mmstat.h:8
@ MEM_SLAB
Definition mmstat.h:9
@ MEM_KERNEL
Definition mmstat.h:11
#define MOS_UNUSED(x)
Definition mos_global.h:64
#define NULL
Definition pb_syshdr.h:46
#define pr_warn(fmt,...)
Definition printk.h:38
process_t * process_get(pid_t pid)
Definition process.c:162
#define MOS_USER_END_VADDR
size_t size
Definition slab.c:30
#define spinlock_acquire(lock)
Definition spinlock.h:61
#define spinlock_release(lock)
Definition spinlock.h:62
spinlock_t mm_lock
protects [pgd] and the [mmaps] list (the list itself, not the vmap_t objects)
Definition platform.h:81
list_head mmaps
Definition platform.h:83
pgd_t pgd
Definition platform.h:82
atomic_t allocated_refcount
Definition pmm.h:58
enum phyframe_t::phyframe_state state
u8 order
Definition pmm.h:35
mm_context_t * mm
Definition task_types.h:59
Definition mm.h:58
void sysfs_file_set_data(sysfs_file_t *file, void *data)
Definition sysfs.c:105
ssize_t sysfs_printf(sysfs_file_t *file, const char *fmt,...)
Definition sysfs.c:73
void * sysfs_file_get_data(sysfs_file_t *file)
Definition sysfs.c:110
#define SYSFS_RW_ITEM(_name, _show_fn, _store_fn)
Definition sysfs.h:49
#define SYSFS_RO_ITEM(_name, _show_fn)
Definition sysfs.h:48
#define SYSFS_AUTOREGISTER(sysfs_name, sysfs_items)
unsigned int u32
Definition types.h:21
unsigned long long pfn_t
Definition types.h:41
#define PTR_RANGE
Definition types.h:36
ssize_t off_t
Definition types.h:84
s32 pid_t
Definition types.h:78
#define PFN_RANGE
Definition types.h:43
unsigned long ptr_t
Definition types.h:25