From cce970b9a7b508dc6caf17a7257072393bcb7259 Mon Sep 17 00:00:00 2001 From: Jiankang Chen Date: Mon, 28 Oct 2019 20:29:47 +0800 Subject: [PATCH] svm: using a rbtree to manage the svm_process ascend inclusion category: feature bugzilla: 16554 CVE: NA -------- using a rbtree to manage a svm_process,and implement find process, delete process and insert process Signed-off-by: Jiankang Chen Signed-off-by: Lijun Fang Reviewed-by: Li Zefan Reviewed-by: Kefeng Wang Signed-off-by: Yang Yingliang --- drivers/char/svm.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/drivers/char/svm.c b/drivers/char/svm.c index e38720be4adc..603e50b51ff7 100644 --- a/drivers/char/svm.c +++ b/drivers/char/svm.c @@ -48,6 +48,7 @@ LIST_HEAD(child_list); #endif static DECLARE_RWSEM(svm_sem); static DEFINE_SPINLOCK(svm_process_lock); +static struct rb_root svm_process_root = RB_ROOT; struct core_device { struct device dev; @@ -114,18 +115,51 @@ static char *svm_cmd_to_string(unsigned int cmd) static struct svm_process *find_svm_process(unsigned long asid) { - /*TODO*/ + struct rb_node *node = svm_process_root.rb_node; + + while (node) { + struct svm_process *process = NULL; + + process = rb_entry(node, struct svm_process, rb_node); + if (asid < process->asid) + node = node->rb_left; + else if (asid > process->asid) + node = node->rb_right; + else + return process; + } + return NULL; } static void insert_svm_process(struct svm_process *process) { - /*TODO*/ + struct rb_node **p = &svm_process_root.rb_node; + struct rb_node *parent = NULL; + + while (*p) { + struct svm_process *tmp_process = NULL; + + parent = *p; + tmp_process = rb_entry(parent, struct svm_process, rb_node); + if (process->asid < tmp_process->asid) + p = &(*p)->rb_left; + else if (process->asid > tmp_process->asid) + p = &(*p)->rb_right; + else { + WARN_ON_ONCE("asid already in the tree"); + return; + } + } + + rb_link_node(&process->rb_node, parent, p); + rb_insert_color(&process->rb_node, &svm_process_root); } static void delete_svm_process(struct svm_process *process) { - /*TODO*/ + rb_erase(&process->rb_node, &svm_process_root); + RB_CLEAR_NODE(&process->rb_node); } static struct svm_device *file_to_sdev(struct file *file) -- GitLab