new:kzalloc

This commit is contained in:
fslongjin
2022-08-15 17:57:05 +08:00
parent cec44c1fd7
commit f513286f53
11 changed files with 73 additions and 29 deletions

View File

@ -4,7 +4,7 @@ DragonOS提供了一些用于内存分配的api。您可以使用*kmalloc*来分
## 选择合适的内存分配器
在内核中,最直接、最简单的分配内存的方式就是,使用`kmalloc()`函数进行分配。并且,出于安全起见,在得到内存块后,我们强烈建议使用`memset()`函数将该内存区域清零。
在内核中,最直接、最简单的分配内存的方式就是,使用`kmalloc()`函数进行分配。并且,出于安全起见,除非内存在分配后一定会被覆盖,且您能确保内存中的脏数据一定不会对程序造成影响,在其余情况下,我们建议使用`kzalloc()`进行内存分配,它将会在`kmalloc()`的基础上,把申请到的内存进行清零。
您可以通过`kmalloc()`函数分配得到32bytes到1MBytes之间的内存对象。并且这些内存对象具有以下的性质

View File

@ -4,7 +4,7 @@
SLAB内存池提供小内存对象的分配功能。
### `void *kmalloc(unsigned long size, unsigned long flags)`
### `void *kmalloc(unsigned long size, gfp_t gfp)`
  获取小块的内存。
@ -18,9 +18,26 @@ SLAB内存池提供小内存对象的分配功能。
  内存对象的大小
**flags**
**gfp**
  标志位暂时未实现默认填0
  标志位
### `void *kzalloc(unsigned long size, gfp_t gfp)`
#### 描述
  获取小块的内存并将其清零。其余功能与kmalloc相同。
##### 参数
**size**
  内存对象的大小
**gfp**
  标志位
### `unsigned long kfree(void *address)`
@ -30,7 +47,7 @@ SLAB内存池提供小内存对象的分配功能。
  该函数用于释放通过kmalloc申请的内存。如果`address`为NULL则函数被调用后无事发生。
  请不要通过这个函数释放那些不是从`kmalloc()`申请的内存,否则将会导致系统崩溃。
  请不要通过这个函数释放那些不是从`kmalloc()``kzalloc()`申请的内存,否则将会导致系统崩溃。
##### 参数

View File

@ -1,5 +1,7 @@
#pragma once
#define __force __attribute__((force))
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

8
kernel/common/gfp.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
#include <common/sys/types.h>
#include <common/compiler.h>
/**
* __GFP_ZERO: 获取内存的同时,将获取到的这块内存清空
*
*/
#define __GFP_ZERO ((gfp_t)(1UL << 0))

View File

@ -37,14 +37,14 @@ void mutex_lock(mutex_t *lock)
spin_lock(&lock->wait_lock);
if (likely(mutex_is_locked(lock)))
{
struct mutex_waiter_t *waiter = (struct mutex_waiter_t *)kmalloc(sizeof(struct mutex_waiter_t), 0);
struct mutex_waiter_t *waiter = (struct mutex_waiter_t *)kzalloc(sizeof(struct mutex_waiter_t), 0);
if (waiter == NULL)
{
kerror("In mutex_lock: no memory to alloc waiter. Program's behaviour might be indetermined!");
spin_unlock(&lock->wait_lock);
return;
}
memset(waiter, 0, sizeof(struct mutex_waiter_t));
// memset(waiter, 0, sizeof(struct mutex_waiter_t));
waiter->pcb = current_pcb;
list_init(&waiter->list);
list_append(&lock->wait_list, &waiter->list);

View File

@ -84,3 +84,5 @@ typedef struct __pthread_condattr_t
{
int clockid; // clockid_t
} pthread_condattr_t;
typedef uint64_t gfp_t;

View File

@ -201,7 +201,7 @@ static int ps2_mouse_enable_5keys()
void ps2_mouse_init()
{
// 初始化鼠标读入队列缓冲区
ps2_mouse_buf_ptr = (struct ps2_mouse_input_buffer *)kmalloc(sizeof(struct ps2_mouse_input_buffer), 0);
ps2_mouse_buf_ptr = (struct ps2_mouse_input_buffer *)kzalloc(sizeof(struct ps2_mouse_input_buffer), 0);
ps2_mouse_buf_ptr->ptr_head = ps2_mouse_buf_ptr->buffer;
ps2_mouse_buf_ptr->ptr_tail = ps2_mouse_buf_ptr->buffer;
ps2_mouse_buf_ptr->count = 0;

View File

@ -105,8 +105,7 @@ void system_initialize()
// =========== 重新设置initial_tss[0]的ist
uchar *ptr = (uchar *)kmalloc(STACK_SIZE, 0) + STACK_SIZE;
memset(ptr, 0, STACK_SIZE); // 将ist清空
uchar *ptr = (uchar *)kzalloc(STACK_SIZE, 0) + STACK_SIZE;
((struct process_control_block *)(ptr - STACK_SIZE))->cpu_id = 0;
initial_tss[0].ist1 = (ul)ptr;

View File

@ -1,6 +1,7 @@
#pragma once
#include <common/glib.h>
#include <common/gfp.h>
#include <mm/mm-types.h>
#include <process/process.h>

View File

@ -397,7 +397,6 @@ ul slab_init()
io_mfence();
--page->zone->count_pages_free;
page_init(page, PAGE_KERNEL_INIT | PAGE_KERNEL | PAGE_PGT_MAPPED);
}
io_mfence();
@ -535,11 +534,12 @@ struct slab_obj *kmalloc_create_slab_obj(ul size)
* @brief 通用内存分配函数
*
* @param size 要分配的内存大小
* @param flags 内存的flag
* @param gfp 内存的flag
* @return void* 内核内存虚拟地址
*/
void *kmalloc(unsigned long size, unsigned long flags)
void *kmalloc(unsigned long size, gfp_t gfp)
{
void *result = NULL;
if (size > 1048576)
{
kwarn("kmalloc(): Can't alloc such memory: %ld bytes, because it is too large.", size);
@ -610,9 +610,15 @@ void *kmalloc(unsigned long size, unsigned long flags)
// 放锁
spin_unlock(&kmalloc_cache_group[index].lock);
// 返回内存对象
return (void *)((char *)slab_obj_ptr->vaddr + kmalloc_cache_group[index].size * i);
result = (void *)((char *)slab_obj_ptr->vaddr + kmalloc_cache_group[index].size * i);
goto done;
}
}
goto failed;
done:;
if (gfp & __GFP_ZERO)
memset(result, 0, size);
return result;
failed:;
spin_unlock(&kmalloc_cache_group[index].lock);
kerror("kmalloc(): Cannot alloc more memory: %d bytes", size);

View File

@ -49,15 +49,27 @@ struct slab
void *(*constructor)(void *vaddr, ul arg);
void *(*destructor)(void *vaddr, ul arg);
};
//extern struct slab kmalloc_cache_group[16];
/**
* @brief 通用内存分配函数
*
* @param size 要分配的内存大小
* @param flags 内存的flag
* @return void*
* @param gfp 内存的flag
* @return void* 分配得到的内存的指针
*/
void *kmalloc(unsigned long size, unsigned long flags);
void *kmalloc(unsigned long size, gfp_t gfp);
/**
* @brief 从kmalloc申请一块内存并将这块内存清空
*
* @param size 要分配的内存大小
* @param gfp 内存的flag
* @return void* 分配得到的内存的指针
*/
static __always_inline void *kzalloc(size_t size, gfp_t gfp)
{
return kmalloc(size, gfp | __GFP_ZERO);
}
/**
* @brief 通用内存释放函数
@ -112,8 +124,7 @@ ul slab_free(struct slab *slab_pool, void *addr, ul arg);
* @param size
* @return struct slab_obj* 创建好的slab_obj
*/
struct slab_obj * kmalloc_create_slab_obj(ul size);
struct slab_obj *kmalloc_create_slab_obj(ul size);
/**
* @brief 初始化内存池组
@ -121,5 +132,3 @@ struct slab_obj * kmalloc_create_slab_obj(ul size);
* @return ul
*/
ul slab_init();