123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- /**
- * @file mm-stat.c
- * @author longjin([email protected])
- * @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;
- }
|