From 93574c43d995a8ad4dee99fd3537c7e8dde77f01 Mon Sep 17 00:00:00 2001 From: fanrui Date: Tue, 23 Aug 2022 17:45:02 +0800 Subject: [PATCH] Fix write sysfs file `/sys/kernel/PBK/pbk_create_domain` bug Details: do operations in the bellowing order would cause the system reboot: echo 1 > /sys/kernel/PBK/pbk_create_domain echo 2 > /sys/kernel/PBK/pbk_create_domain echo 1 > /sys/kernel/PBK/pbk_create_domain --- PBK/pbk_cpu.c | 4 ++++ PBK/pbk_domain.c | 36 ++++++++++++++++++------------------ PBK/pbk_sysfs.c | 42 ++++++++++++------------------------------ include/linux/pbk.h | 5 ++++- 4 files changed, 38 insertions(+), 49 deletions(-) diff --git a/PBK/pbk_cpu.c b/PBK/pbk_cpu.c index 5372d5389388..03a789eab931 100644 --- a/PBK/pbk_cpu.c +++ b/PBK/pbk_cpu.c @@ -50,6 +50,8 @@ static int pbk_cpu_up(unsigned int cpu) ret = do_cpu_up(cpu, PBK_CPU_ONLINE_STATE); if (ret) pr_err("Failed to online CPU %u\n", cpu); + else + sched_domains_numa_masks_set(cpu); return ret; } @@ -61,6 +63,8 @@ static int pbk_cpu_down(unsigned int cpu) ret = cpu_down(cpu, PBK_CPU_OFFLINE_STATE); if (ret) pr_err("Failed to offline CPU %u\n", cpu); + else + sched_domains_numa_masks_clear(cpu); return ret; } diff --git a/PBK/pbk_domain.c b/PBK/pbk_domain.c index 47a4fa483fe2..d4f59dfd3baa 100644 --- a/PBK/pbk_domain.c +++ b/PBK/pbk_domain.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "pbk_cpu.h" @@ -49,8 +50,8 @@ struct pbk_domain *pbk_find_get_domain(pdid_t domain_id) spin_lock(&pbk_domains_lock); hash_for_each_possible(pbk_domains, pd, ht_node, domain_id) { if (pd->domain_id == domain_id) { - spin_unlock(&pbk_domains_lock); get_pbk_domain(pd); + spin_unlock(&pbk_domains_lock); return pd; } } @@ -60,26 +61,25 @@ struct pbk_domain *pbk_find_get_domain(pdid_t domain_id) return NULL; } -struct pbk_domain *pbk_find_matched_domain(cpumask_var_t request) +struct pbk_domain *pbk_find_get_domain_withcpu(cpumask_var_t mask) { - struct pbk_domain *pd = NULL; - int bkt = 0; - - // char buf[80]; - // cpumap_print_to_pagebuf(1, buf, request); - // pr_err("X = request = %s hash_empty = %d\n", buf, hash_empty(pbk_domains)); - - spin_lock(&pbk_domains_lock); - hash_for_each(pbk_domains, bkt, pd, ht_node) { - if (cpumask_equal(pbk_domain_cpu(pd), request)) { - spin_unlock(&pbk_domains_lock); - get_pbk_domain(pd); - return pd; + struct pbk_domain *pd; + struct hlist_node *tmp; + unsigned long timeout; + int bkt; + + timeout = USEC_PER_SEC; + while (timeout--) { + hash_for_each_safe(pbk_domains, bkt, tmp, pd, ht_node) { + if (cpumask_equal(mask, pbk_domain_cpu(pd))) { + get_pbk_domain(pd); + return pd; + } } - } - spin_unlock(&pbk_domains_lock); + udelay(1); + }; - pr_err("PBK can not find matched domain\n"); + pr_err("invalid cpulist request %*pbl\n", cpumask_pr_args(mask)); return NULL; } diff --git a/PBK/pbk_sysfs.c b/PBK/pbk_sysfs.c index d3b85686efae..8c73af34c017 100644 --- a/PBK/pbk_sysfs.c +++ b/PBK/pbk_sysfs.c @@ -19,17 +19,14 @@ static ssize_t pbk_create_domain_store(struct kobject *kobj, if (ret || !cpumask_subset(&request, pbk_cpuset)) return -EINVAL; - pd = pbk_find_matched_domain(&request); - if (pd == NULL) { - ret = pbk_alloc_cpus(&request); - if (ret) - return ret; - - pd = pbk_alloc_domain(&request); - if (IS_ERR(pd)) { - pr_err("Failed to allocate pbk domain\n"); - return PTR_ERR(pd); - } + ret = pbk_alloc_cpus(&request); + if (ret) + goto try_get_pd; + + pd = pbk_alloc_domain(&request); + if (IS_ERR(pd)) { + pr_err("Failed to allocate pbk domain\n"); + return PTR_ERR(pd); } current->pbkd = pd; @@ -39,25 +36,12 @@ static ssize_t pbk_create_domain_store(struct kobject *kobj, return ret; return count; -} - -static struct kobj_attribute pbk_create_domain_attr = __ATTR_WO(pbk_create_domain); - -static ssize_t pbk_join_domain_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - pdid_t domain_id; - struct pbk_domain *pd; - int ret; - ret = kstrtoint(buf, 0, &domain_id); - if (ret) - return -EINVAL; - - pd = pbk_find_get_domain(domain_id); +try_get_pd: + pd = pbk_find_get_domain_withcpu(&request); if (!pd) return -EINVAL; - + pbk_attach_domain(current, pd); pbk_resched_threads(current, pbk_domain_cpu(pd)); put_pbk_domain(pd); @@ -65,7 +49,7 @@ static ssize_t pbk_join_domain_store(struct kobject *kobj, return count; } -static struct kobj_attribute pbk_join_domain_attr = __ATTR_WO(pbk_join_domain); +static struct kobj_attribute pbk_create_domain_attr = __ATTR_WO(pbk_create_domain); static ssize_t pbk_with_nr_cpu_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) @@ -123,7 +107,6 @@ static struct kobj_attribute pbk_view_attr = __ATTR_WO(pbk_view); static struct attribute *pbk_attributes[] = { &pbk_create_domain_attr.attr, - &pbk_join_domain_attr.attr, &pbk_with_nr_cpu_attr.attr, &pbk_view_attr.attr, NULL @@ -142,7 +125,6 @@ static int __init pbk_sysfs_init(void) return -ENOMEM; pbk_create_domain_attr.attr.mode |= S_IWGRP; - pbk_join_domain_attr.attr.mode |= S_IWGRP; pbk_with_nr_cpu_attr.attr.mode |= S_IWGRP; pbk_view_attr.attr.mode |= S_IWGRP; diff --git a/include/linux/pbk.h b/include/linux/pbk.h index e01e52c1fa66..914c3355169b 100644 --- a/include/linux/pbk.h +++ b/include/linux/pbk.h @@ -35,7 +35,7 @@ struct pbk_domain { extern void pbk_create_root_domain(void); extern struct pbk_domain *pbk_find_get_domain(pdid_t domain_id); -extern struct pbk_domain *pbk_find_matched_domain(cpumask_var_t request); +extern struct pbk_domain *pbk_find_get_domain_withcpu(cpumask_var_t mask); extern struct pbk_domain *pbk_alloc_domain(cpumask_var_t request); extern void pbk_attach_domain(struct task_struct *p, struct pbk_domain *pd); extern void destroy_pbk_domain(struct pbk_domain *pd); @@ -109,6 +109,9 @@ static inline bool is_pbk_cpu_state(enum cpuhp_state state) extern int do_cpu_up(unsigned int cpu, enum cpuhp_state target); extern int cpu_down(unsigned int cpu, enum cpuhp_state target); +extern void sched_domains_numa_masks_set(unsigned int cpu); +extern void sched_domains_numa_masks_clear(unsigned int cpu); + #endif /* _LINUX_PBK_H */ #endif /* CONFIG_PURPOSE_BUILT_KERNEL */ \ No newline at end of file -- GitLab