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