mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-10 08:06:48 +00:00
new: mstat()函数,查询内存信息
This commit is contained in:
parent
fdd5d3cf66
commit
fb51b0dd6f
@ -2,7 +2,7 @@
|
||||
CFLAGS += -I .
|
||||
|
||||
|
||||
all:mm.o slab.o
|
||||
all:mm.o slab.o mm-stat.o
|
||||
|
||||
mm.o: mm.c
|
||||
gcc $(CFLAGS) -c mm.c -o mm.o
|
||||
@ -10,3 +10,5 @@ mm.o: mm.c
|
||||
slab.o: slab.c
|
||||
gcc $(CFLAGS) -c slab.c -o slab.o
|
||||
|
||||
mm-stat.o: mm-stat.c
|
||||
gcc $(CFLAGS) -c mm-stat.c -o mm-stat.o
|
||||
|
195
kernel/mm/mm-stat.c
Normal file
195
kernel/mm/mm-stat.c
Normal file
@ -0,0 +1,195 @@
|
||||
/**
|
||||
* @file mm-stat.c
|
||||
* @author longjin(longjin@RinGoTek.cn)
|
||||
* @brief 查询内存信息
|
||||
* @version 0.1
|
||||
* @date 2022-08-06
|
||||
*
|
||||
* @copyright Copyright (c) 2022
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mm.h"
|
||||
#include "slab.h"
|
||||
#include <common/errno.h>
|
||||
#include <process/ptrace.h>
|
||||
|
||||
extern const struct slab kmalloc_cache_group[16];
|
||||
|
||||
static int __empty_2m_pages(int zone);
|
||||
static int __count_in_using_2m_pages(int zone);
|
||||
static uint64_t __count_kmalloc_free();
|
||||
static uint64_t __count_kmalloc_using();
|
||||
static uint64_t __count_kmalloc_total();
|
||||
uint64_t sys_mm_stat(struct pt_regs *regs);
|
||||
|
||||
/**
|
||||
* @brief 获取指定zone中的空闲2M页的数量
|
||||
*
|
||||
* @param zone 内存zone号
|
||||
* @return int 空闲2M页数量
|
||||
*/
|
||||
static int __count_empty_2m_pages(int zone)
|
||||
{
|
||||
int zone_start = 0, zone_end = 0;
|
||||
|
||||
uint64_t attr = 0;
|
||||
switch (zone)
|
||||
{
|
||||
case ZONE_DMA:
|
||||
// DMA区域
|
||||
zone_start = 0;
|
||||
zone_end = ZONE_DMA_INDEX;
|
||||
attr |= PAGE_PGT_MAPPED;
|
||||
break;
|
||||
case ZONE_NORMAL:
|
||||
zone_start = ZONE_DMA_INDEX;
|
||||
zone_end = ZONE_NORMAL_INDEX;
|
||||
attr |= PAGE_PGT_MAPPED;
|
||||
break;
|
||||
case ZONE_UNMAPPED_IN_PGT:
|
||||
zone_start = ZONE_NORMAL_INDEX;
|
||||
zone_end = ZONE_UNMAPPED_INDEX;
|
||||
attr = 0;
|
||||
break;
|
||||
default:
|
||||
kerror("In __count_empty_2m_pages: param: zone invalid.");
|
||||
// 返回错误码
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
uint64_t result = 0;
|
||||
for (int i = zone_start; i <= zone_end; ++i)
|
||||
{
|
||||
result += (memory_management_struct.zones_struct + i)->count_pages_free;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取指定zone中的正在使用的2M页的数量
|
||||
*
|
||||
* @param zone 内存zone号
|
||||
* @return int 空闲2M页数量
|
||||
*/
|
||||
static int __count_in_using_2m_pages(int zone)
|
||||
{
|
||||
int zone_start = 0, zone_end = 0;
|
||||
|
||||
uint64_t attr = 0;
|
||||
switch (zone)
|
||||
{
|
||||
case ZONE_DMA:
|
||||
// DMA区域
|
||||
zone_start = 0;
|
||||
zone_end = ZONE_DMA_INDEX;
|
||||
attr |= PAGE_PGT_MAPPED;
|
||||
break;
|
||||
case ZONE_NORMAL:
|
||||
zone_start = ZONE_DMA_INDEX;
|
||||
zone_end = ZONE_NORMAL_INDEX;
|
||||
attr |= PAGE_PGT_MAPPED;
|
||||
break;
|
||||
case ZONE_UNMAPPED_IN_PGT:
|
||||
zone_start = ZONE_NORMAL_INDEX;
|
||||
zone_end = ZONE_UNMAPPED_INDEX;
|
||||
attr = 0;
|
||||
break;
|
||||
default:
|
||||
kerror("In __count_in_using_2m_pages: param: zone invalid.");
|
||||
// 返回错误码
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
uint64_t result = 0;
|
||||
for (int i = zone_start; i <= zone_end; ++i)
|
||||
{
|
||||
result += (memory_management_struct.zones_struct + i)->count_pages_using;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 计算kmalloc缓冲区中的空闲内存
|
||||
*
|
||||
* @return uint64_t 空闲内存(字节)
|
||||
*/
|
||||
static uint64_t __count_kmalloc_free()
|
||||
{
|
||||
uint64_t result = 0;
|
||||
for (int i = 0; i < sizeof(kmalloc_cache_group) / sizeof(struct slab); ++i)
|
||||
{
|
||||
result += kmalloc_cache_group[i].size * kmalloc_cache_group[i].count_total_free;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 计算kmalloc缓冲区中已使用的内存
|
||||
*
|
||||
* @return uint64_t 已使用的内存(字节)
|
||||
*/
|
||||
static uint64_t __count_kmalloc_using()
|
||||
{
|
||||
uint64_t result = 0;
|
||||
for (int i = 0; i < sizeof(kmalloc_cache_group) / sizeof(struct slab); ++i)
|
||||
{
|
||||
result += kmalloc_cache_group[i].size * kmalloc_cache_group[i].count_total_using;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 计算kmalloc缓冲区中总共占用的内存
|
||||
*
|
||||
* @return uint64_t 缓冲区占用的内存(字节)
|
||||
*/
|
||||
static uint64_t __count_kmalloc_total()
|
||||
{
|
||||
uint64_t result = 0;
|
||||
for (int i = 0; i < sizeof(kmalloc_cache_group) / sizeof(struct slab); ++i)
|
||||
{
|
||||
result += kmalloc_cache_group[i].size * (kmalloc_cache_group[i].count_total_free + kmalloc_cache_group[i].count_total_using);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取系统当前的内存信息(未上锁,不一定精准)
|
||||
*
|
||||
* @return struct mm_stat_t 内存信息结构体
|
||||
*/
|
||||
struct mm_stat_t mm_stat()
|
||||
{
|
||||
struct mm_stat_t tmp = {0};
|
||||
// 统计物理页的信息
|
||||
tmp.used = __count_in_using_2m_pages(ZONE_NORMAL) * PAGE_2M_SIZE;
|
||||
tmp.free = __count_empty_2m_pages(ZONE_NORMAL) * PAGE_2M_SIZE;
|
||||
tmp.total = tmp.used + tmp.free;
|
||||
tmp.shared = 0;
|
||||
// 统计kmalloc slab中的信息
|
||||
tmp.cache_free = __count_kmalloc_free();
|
||||
tmp.cache_used = __count_kmalloc_using();
|
||||
tmp.available = tmp.free + tmp.cache_free;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取内存信息的系统调用
|
||||
*
|
||||
* @param r8 返回的内存信息结构体的地址
|
||||
* @return uint64_t
|
||||
*/
|
||||
uint64_t sys_mstat(struct pt_regs *regs)
|
||||
{
|
||||
if (regs->r8 == NULL)
|
||||
return -EINVAL;
|
||||
struct mm_stat_t stat = mm_stat();
|
||||
if (regs->cs == (USER_CS | 0x3))
|
||||
copy_to_user((void *)regs->r8, &stat, sizeof(struct mm_stat_t));
|
||||
else
|
||||
memcpy((void *)regs->r8, &stat, sizeof(struct mm_stat_t));
|
||||
return 0;
|
||||
}
|
@ -145,7 +145,7 @@
|
||||
do \
|
||||
{ \
|
||||
ul tmp; \
|
||||
io_mfence();\
|
||||
io_mfence(); \
|
||||
__asm__ __volatile__( \
|
||||
"movq %%cr3, %0\n\t" \
|
||||
"movq %0, %%cr3\n\t" \
|
||||
@ -227,6 +227,21 @@ struct Page
|
||||
ul age;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 系统内存信息结构体(单位:字节)
|
||||
*
|
||||
*/
|
||||
struct mm_stat_t
|
||||
{
|
||||
uint64_t total; // 计算机的总内存数量大小
|
||||
uint64_t used; // 已使用的内存大小
|
||||
uint64_t free; // 空闲物理页所占的内存大小
|
||||
uint64_t shared; // 共享的内存大小
|
||||
uint64_t cache_used; // 位于slab缓冲区中的已使用的内存大小
|
||||
uint64_t cache_free; // 位于slab缓冲区中的空闲的内存大小
|
||||
uint64_t available; // 系统总空闲内存大小(包括kmalloc缓冲区)
|
||||
};
|
||||
|
||||
extern struct memory_desc memory_management_struct;
|
||||
|
||||
// 导出内核程序的几个段的起止地址
|
||||
@ -443,4 +458,11 @@ int8_t mm_check_page_table(uint64_t *ptr);
|
||||
* @param offset 新的地址相对于原地址的偏移量
|
||||
* @return uint64_t
|
||||
*/
|
||||
uint64_t mm_do_brk(uint64_t old_brk_end_addr, int64_t offset);
|
||||
uint64_t mm_do_brk(uint64_t old_brk_end_addr, int64_t offset);
|
||||
|
||||
/**
|
||||
* @brief 获取系统当前的内存信息(未上锁,不一定精准)
|
||||
*
|
||||
* @return struct mm_stat_t 内存信息结构体
|
||||
*/
|
||||
struct mm_stat_t mm_stat();
|
@ -18,6 +18,7 @@ extern void system_call(void);
|
||||
extern void syscall_int(void);
|
||||
|
||||
extern uint64_t sys_clock(struct pt_regs *regs);
|
||||
extern uint64_t sys_mstat(struct pt_regs *regs);
|
||||
|
||||
/**
|
||||
* @brief 导出系统调用处理函数的符号
|
||||
@ -778,5 +779,7 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
|
||||
[17] = sys_mkdir,
|
||||
[18] = sys_nanosleep,
|
||||
[19] = sys_clock,
|
||||
[20 ... 254] = system_call_not_exists,
|
||||
[20] = system_call_not_exists,
|
||||
[21] = sys_mstat,
|
||||
[22 ... 254] = system_call_not_exists,
|
||||
[255] = sys_ahci_end_req};
|
||||
|
@ -30,5 +30,9 @@
|
||||
#define SYS_MKDIR 17 // 创建文件夹
|
||||
#define SYS_NANOSLEEP 18 // 纳秒级休眠
|
||||
#define SYS_CLOCK 19 // 获取当前cpu时间
|
||||
#define SYS_PIPE 20
|
||||
|
||||
#define SYS_MSTAT 21 // 获取系统的内存状态信息
|
||||
|
||||
|
||||
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
@ -1,7 +1,18 @@
|
||||
#include "stat.h"
|
||||
#include<libsystem/syscall.h>
|
||||
#include <libsystem/syscall.h>
|
||||
|
||||
int mkdir(const char *path, mode_t mode)
|
||||
{
|
||||
return syscall_invoke(SYS_MKDIR, (uint64_t)path, (uint64_t)mode, 0,0,0,0,0,0);
|
||||
return syscall_invoke(SYS_MKDIR, (uint64_t)path, (uint64_t)mode, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取系统的内存信息
|
||||
*
|
||||
* @param stat 传入的内存信息结构体
|
||||
* @return int 错误码
|
||||
*/
|
||||
int mstat(struct mstat_t *stat)
|
||||
{
|
||||
return syscall_invoke(SYS_MSTAT, (uint64_t)stat, 0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
@ -1,4 +1,27 @@
|
||||
#pragma once
|
||||
#include <libc/sys/types.h>
|
||||
|
||||
int mkdir(const char *path, mode_t mode);
|
||||
/**
|
||||
* @brief 系统内存信息结构体(单位:字节)
|
||||
*
|
||||
*/
|
||||
struct mstat_t
|
||||
{
|
||||
uint64_t total; // 计算机的总内存数量大小
|
||||
uint64_t used; // 已使用的内存大小
|
||||
uint64_t free; // 空闲物理页所占的内存大小
|
||||
uint64_t shared; // 共享的内存大小
|
||||
uint64_t cache_used; // 位于slab缓冲区中的已使用的内存大小
|
||||
uint64_t cache_free; // 位于slab缓冲区中的空闲的内存大小
|
||||
uint64_t available; // 系统总空闲内存大小(包括kmalloc缓冲区)
|
||||
};
|
||||
|
||||
int mkdir(const char *path, mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief 获取系统的内存信息
|
||||
*
|
||||
* @param stat 传入的内存信息结构体
|
||||
* @return int 错误码
|
||||
*/
|
||||
int mstat(struct mstat_t* stat);
|
@ -24,6 +24,9 @@
|
||||
#define SYS_MKDIR 17 // 创建文件夹
|
||||
#define SYS_NANOSLEEP 18 // 纳秒级休眠
|
||||
#define SYS_CLOCK 19 // 获取当前cpu时间
|
||||
#define SYS_PIPE 20
|
||||
|
||||
#define SYS_MSTAT 21 // 获取系统的内存状态信息
|
||||
|
||||
/**
|
||||
* @brief 用户态系统调用函数
|
||||
|
Loading…
x
Reference in New Issue
Block a user