From: seantywork Date: Sun, 21 Sep 2025 08:00:30 +0000 (+0000) Subject: rcu update, remove X-Git-Url: https://git.feebdaed.xyz/?a=commitdiff_plain;h=bc92e266d25dcbea01cad8f17e537b8c336b99dc;p=linuxyz.git rcu update, remove --- diff --git a/krcu-cmap/rcucmap.c b/krcu-cmap/rcucmap.c index 7f9dd1a..f26840c 100644 --- a/krcu-cmap/rcucmap.c +++ b/krcu-cmap/rcucmap.c @@ -11,20 +11,145 @@ #define OP_COUNT 10 -struct myelement { - - struct list_head node; - struct rcu_head rcu; +struct node { + int key; + int value; + struct list_head _node; + struct rcu_head _rcu; }; -static LIST_HEAD(myelements); -static spinlock_t myelements_lock; +struct cc_buck { + struct list_head nodes; + spinlock_t lock; +}; + +struct cc_map { + struct cc_buck* buckets; + int count; +}; +static struct cc_map* cmap; static struct task_struct *task_write; static struct task_struct *task_read; static int w = 10; static int r = 11; + +static int _hashfunc(__u32 key, __u32 bcount){ + __u32 hash = ((key >> 16) ^ key) * 0x45d9f3bu; + hash = ((hash >> 16) ^ hash) * 0x45d9f3bu; + hash = (hash >> 16) ^ hash; + return hash % bcount; +} + +static struct cc_map* make_ccmap(int bcount){ + + struct cc_map* cmap = (struct cc_map*)kzalloc(sizeof(struct cc_map), GFP_KERNEL); + cmap->count = bcount; + cmap->buckets = (struct cc_buck*)kzalloc(sizeof(struct cc_buck) * cmap->count, GFP_KERNEL); + for(int i = 0; i < cmap->count; i++){ + spin_lock_init(&cmap->buckets[i].lock); + INIT_LIST_HEAD(&cmap->buckets[i].nodes); + } + return cmap; +} + +static void _ccmap_cb(struct rcu_head* _rcu){ + struct node* n = container_of(_rcu, struct node, _rcu); + kfree(n); +} + +static int update_ccmap(struct cc_map* cmap, int key, int value){ + int result = -1; + struct node* n = NULL; + struct node* old_n = NULL; + struct node* new_n = NULL; + __u32 idx = _hashfunc((__u32)key, (__u32)cmap->count); + rcu_read_lock(); + spin_lock(&cmap->buckets[idx].lock); + list_for_each_entry(n, &cmap->buckets[idx].nodes, _node){ + if(n->key != key){ + continue; + } + old_n = n; + break; + } + new_n = kzalloc(sizeof(struct node), GFP_ATOMIC); + if(new_n == NULL){ + goto done; + } + if(old_n == NULL){ + new_n->key = key; + new_n->value = value; + list_add_rcu(&new_n->_node, &cmap->buckets[idx].nodes); + } else { + memcpy(new_n, old_n, sizeof(struct node)); + new_n->value = value; + list_replace_rcu(&old_n->_node, &new_n->_node); + } + result = (int)idx; + +done: + spin_unlock(&cmap->buckets[idx].lock); + rcu_read_unlock(); +// synchronize_rcu(); +// if(old_n != NULL && new_n != NULL){ +// kfree(old_n); +// } + if(old_n != NULL && new_n != NULL){ + call_rcu(&old_n->_rcu, _ccmap_cb); + } + return result; +} + + +static int remove_ccmap(struct cc_map* cmap, int key){ + int result = -1; + struct node* n = NULL; + struct node* found_n = NULL; + __u32 idx = _hashfunc((__u32)key, (__u32)cmap->count); + rcu_read_lock(); + spin_lock(&cmap->buckets[idx].lock); + list_for_each_entry(n, &cmap->buckets[idx].nodes, _node){ + if(n->key != key){ + continue; + } + found_n = n; + break; + } + if(found_n == NULL){ + goto done; + } + list_del_rcu(&found_n->_node); + result = (int)idx; +done: + spin_unlock(&cmap->buckets[idx].lock); + rcu_read_unlock(); + if(found_n != NULL){ + call_rcu(&found_n->_rcu, _ccmap_cb); + } + return result; +} + +static void delete_ccmap(struct cc_map* cmap){ + if(cmap == NULL){ + return; + } + struct node* n = NULL; + struct node* tmp_n = NULL; + for(int i = 0; i < cmap->count; i++){ + spin_lock(&cmap->buckets[i].lock); + list_for_each_entry_safe(n, tmp_n, &cmap->buckets[i].nodes, _node){ + list_del(&n->_node); + kfree(n); + } + spin_unlock(&cmap->buckets[i].lock); + kfree(&cmap->buckets[i]); + } + kfree(cmap); + +} + static int task_writer(void *arg){ int v = *(int *)arg; @@ -52,8 +177,8 @@ static int task_reader(void *arg){ static int __init rcu_cmap_init(void){ - spin_lock_init(&myelements_lock); + /* task_write = kthread_run(task_writer, (void*)&w, "tw/%d", w); if(IS_ERR(task_write)){ printk(KERN_ERR "rcucmap: failed to create task_write thread\n"); @@ -66,17 +191,34 @@ static int __init rcu_cmap_init(void){ } get_task_struct(task_write); get_task_struct(task_read); - - printk(KERN_INFO "rcucmap: loaded\n"); + */ + + printk(KERN_INFO "rcucmap: init\n"); + cmap = make_ccmap(OP_COUNT); + printk(KERN_INFO "rcucmap: updating cmap\n"); + for(int i = 0 ; i < OP_COUNT; i++){ + int idx = update_ccmap(cmap, i, i); + printk(KERN_INFO "update cmap: %d\n", idx); + } + printk(KERN_INFO "rcucmap: removing from cmap\n"); + for(int i = 0 ; i < OP_COUNT; i++){ + int idx = remove_ccmap(cmap, i); + printk(KERN_INFO "remove cmap: %d\n", idx); + } + printk(KERN_INFO "rcucmap: done\n"); return 0; } static void __exit rcu_cmap_exit(void){ + /* kthread_stop(task_write); kthread_stop(task_read); + */ - printk(KERN_INFO "rcucmap: unloaded\n"); + printk(KERN_INFO "rcucmap: deleting cmap\n"); + delete_ccmap(cmap); + printk(KERN_INFO "rcucmap: exit\n"); }