Browse Source

Release worker private (#74)

* 释放worker private,to_thread问题待解决

* 增加process_free_task_

* 测试free_kthread_struct,process_free_task

* free_kthread_struct测试ok

* 修正函数重复的问题

Co-authored-by: longjin <[email protected]>
houmkh 2 years ago
parent
commit
d9ee9a0f5b

+ 1 - 0
.vscode/settings.json

@@ -148,6 +148,7 @@
         "timer.h": "c",
         "hid.h": "c",
         "cfs.h": "c",
+        "err.h": "c",
         "rtc.h": "c",
         "wait_queue_head.h": "c",
         "list.h": "c",

+ 14 - 0
kernel/common/kthread.h

@@ -92,3 +92,17 @@ int kthread_mechanism_init();
  */
 bool kthread_set_worker_private(struct process_control_block *pcb);
 
+/**
+ * @brief 获取pcb中的kthread结构体
+ *
+ * @param pcb pcb
+ * @return struct kthread* kthread信息结构体
+ */
+struct kthread_info_t *to_kthread(struct process_control_block *pcb);
+
+/**
+ * @brief 释放pcb指向的worker private
+ * 
+ * @param pcb 要释放的pcb
+ */
+void free_kthread_struct(struct process_control_block *pcb);

+ 1 - 1
kernel/driver/video/video.c

@@ -183,7 +183,7 @@ int video_init()
                      PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, false);
 
     io_mfence();
-    char init_text2[] = "Video driver initialized.";
+    char init_text2[] = "Video driver initialized.\n";
     for (int i = 0; i < sizeof(init_text2) - 1; ++i)
         uart_send(COM1, init_text2[i]);
 

+ 26 - 6
kernel/process/kthread.c

@@ -41,7 +41,7 @@ struct kthread_create_info_t
  * @param pcb pcb
  * @return struct kthread* kthread信息结构体
  */
-static inline struct kthread_info_t *to_kthread(struct process_control_block *pcb)
+struct kthread_info_t *to_kthread(struct process_control_block *pcb)
 {
     WARN_ON(!(pcb->flags & PF_KTHREAD));
     return pcb->worker_private;
@@ -55,6 +55,7 @@ static struct process_control_block *__kthread_create_on_node(int (*thread_fn)(v
 
     if (create == NULL)
         return ERR_PTR(-ENOMEM);
+    BUG_ON(name_fmt == NULL);
 
     create->thread_fn = thread_fn;
     create->data = data;
@@ -65,7 +66,9 @@ static struct process_control_block *__kthread_create_on_node(int (*thread_fn)(v
     spin_lock(&__kthread_create_lock);
     list_append(&kthread_create_list, &create->list);
     spin_unlock(&__kthread_create_lock);
-    // kdebug("to wakeup kthread daemon..., current preempt=%d, rflags=%#018lx", current_pcb->preempt_count, get_rflags());
+    // kdebug("to wakeup kthread daemon..., current preempt=%d, rflags=%#018lx", current_pcb->preempt_count,
+
+    // todo: 使用completion优化这里
     while (kthreadd_pcb == NULL) // 若kthreadd未初始化,则等待kthreadd启动
         ;
     // 唤醒kthreadd守护进程
@@ -79,21 +82,21 @@ static struct process_control_block *__kthread_create_on_node(int (*thread_fn)(v
     pcb = create->result;
     if (!IS_ERR(create->result))
     {
-        // todo: 为内核线程设置名字
+        // 为内核线程设置名字
         char pcb_name[PCB_NAME_LEN];
         va_list get_args;
         va_copy(get_args, args);
-        //获取到字符串的前16字节
+        // 获取到字符串的前16字节
         int len = vsnprintf(pcb_name, name_fmt, PCB_NAME_LEN, get_args);
         if (len >= PCB_NAME_LEN)
         {
             //名字过大 放到full_name字段中
             struct kthread_info_t *kthread = to_kthread(pcb);
-            char *full_name = kzalloc(1024, __GFP_ZERO);
+            char *full_name = kzalloc(1024, 0);
             vsprintf(full_name, name_fmt, get_args);
             kthread->full_name = full_name;
         }
-        //将前16Bytes放到pcb的name字段
+        // 将前16Bytes放到pcb的name字段
         process_set_pcb_name(pcb, pcb_name);
         va_end(get_args);
     }
@@ -307,4 +310,21 @@ int kthread_mechanism_init()
     kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_SIGNAL);
 
     return 0;
+}
+
+/**
+ * @brief 释放pcb指向的worker private
+ *
+ * @param pcb 要释放的pcb
+ */
+void free_kthread_struct(struct process_control_block *pcb)
+{
+    struct kthread_info_t *kthread = to_kthread(pcb);
+    if (!kthread)
+    {
+        return;
+    }
+    pcb->worker_private = NULL;
+    kfree(kthread->full_name);
+    kfree(kthread);
 }

+ 6 - 1
kernel/process/process.c

@@ -1169,14 +1169,19 @@ void process_exit_thread(struct process_control_block *pcb)
 /**
  * @brief 释放pcb
  *
- * @param pcb
+ * @param pcb 要被释放的pcb
  * @return int
  */
 int process_release_pcb(struct process_control_block *pcb)
 {
+    // 释放子进程的页表
+    process_exit_mm(pcb);
+    // 释放子进程的pcb
+    free_kthread_struct(pcb);
     kfree(pcb);
     return 0;
 }
+
 /**
  * @brief 申请可用的文件句柄
  *

+ 0 - 6
kernel/process/process.h

@@ -188,12 +188,6 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 
 int process_fd_alloc(struct vfs_file_t *file);
 
-/**
- * @brief 释放pcb
- *
- * @param pcb
- * @return int
- */
 int process_release_pcb(struct process_control_block *pcb);
 
 /**

+ 3 - 5
kernel/syscall/syscall.c

@@ -10,7 +10,7 @@
 #include <mm/slab.h>
 #include <process/process.h>
 #include <time/sleep.h>
-
+#include <common/kthread.h>
 // 导出系统调用入口函数,定义在entry.S中
 extern void system_call(void);
 extern void syscall_int(void);
@@ -544,10 +544,7 @@ uint64_t sys_wait4(struct pt_regs *regs)
     // copy_to_user(status, (void*)child_proc->exit_code, sizeof(int));
     proc->next_pcb = child_proc->next_pcb;
 
-    // 释放子进程的页表
-    process_exit_mm(child_proc);
-    // 释放子进程的pcb
-    kfree(child_proc);
+    process_release_pcb(child_proc);
     return 0;
 }
 
@@ -611,3 +608,4 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] = {
     [23 ... 254] = system_call_not_exists,
     [255] = sys_ahci_end_req,
 };
+

+ 7 - 6
kernel/syscall/syscall.h

@@ -2,8 +2,9 @@
 
 #include <common/glib.h>
 #include <common/kprint.h>
-#include <process/ptrace.h>
 #include <common/unistd.h>
+#include <process/ptrace.h>
+
 // 定义最大系统调用数量
 #define MAX_SYSTEM_CALL_NUM 256
 
@@ -63,7 +64,7 @@ ul sys_printf(struct pt_regs *regs);
  * arg0=0  ===> 返回堆区域的起始地址
  * arg0=-1  ===> 返回堆区域的结束地址
  * @return uint64_t 错误码
- * 
+ *
  */
 uint64_t sys_brk(struct pt_regs *regs);
 
@@ -80,18 +81,18 @@ uint64_t sys_sbrk(struct pt_regs *regs);
  * 在VFS.c中实现
  * @param path(r8) 路径
  * @param mode(r9) 模式
- * @return uint64_t 
+ * @return uint64_t
  */
-uint64_t sys_mkdir(struct pt_regs * regs);
+uint64_t sys_mkdir(struct pt_regs *regs);
 
 /**
  * @brief 创建管道
  * 在pipe.c中实现
  * @param fd(r8) 文件句柄指针
  * @param num(r9) 文件句柄个数
- * @return uint64_t 
+ * @return uint64_t
  */
-uint64_t sys_pipe(struct pt_regs * regs);
+uint64_t sys_pipe(struct pt_regs *regs);
 
 ul sys_ahci_end_req(struct pt_regs *regs);