提交 93574c43 编写于 作者: F fanrui

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
上级 590ca54b
...@@ -50,6 +50,8 @@ static int pbk_cpu_up(unsigned int cpu) ...@@ -50,6 +50,8 @@ static int pbk_cpu_up(unsigned int cpu)
ret = do_cpu_up(cpu, PBK_CPU_ONLINE_STATE); ret = do_cpu_up(cpu, PBK_CPU_ONLINE_STATE);
if (ret) if (ret)
pr_err("Failed to online CPU %u\n", cpu); pr_err("Failed to online CPU %u\n", cpu);
else
sched_domains_numa_masks_set(cpu);
return ret; return ret;
} }
...@@ -61,6 +63,8 @@ static int pbk_cpu_down(unsigned int cpu) ...@@ -61,6 +63,8 @@ static int pbk_cpu_down(unsigned int cpu)
ret = cpu_down(cpu, PBK_CPU_OFFLINE_STATE); ret = cpu_down(cpu, PBK_CPU_OFFLINE_STATE);
if (ret) if (ret)
pr_err("Failed to offline CPU %u\n", cpu); pr_err("Failed to offline CPU %u\n", cpu);
else
sched_domains_numa_masks_clear(cpu);
return ret; return ret;
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <linux/sched/signal.h> #include <linux/sched/signal.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/delay.h>
#include "pbk_cpu.h" #include "pbk_cpu.h"
...@@ -49,8 +50,8 @@ struct pbk_domain *pbk_find_get_domain(pdid_t domain_id) ...@@ -49,8 +50,8 @@ struct pbk_domain *pbk_find_get_domain(pdid_t domain_id)
spin_lock(&pbk_domains_lock); spin_lock(&pbk_domains_lock);
hash_for_each_possible(pbk_domains, pd, ht_node, domain_id) { hash_for_each_possible(pbk_domains, pd, ht_node, domain_id) {
if (pd->domain_id == domain_id) { if (pd->domain_id == domain_id) {
spin_unlock(&pbk_domains_lock);
get_pbk_domain(pd); get_pbk_domain(pd);
spin_unlock(&pbk_domains_lock);
return pd; return pd;
} }
} }
...@@ -60,26 +61,25 @@ struct pbk_domain *pbk_find_get_domain(pdid_t domain_id) ...@@ -60,26 +61,25 @@ struct pbk_domain *pbk_find_get_domain(pdid_t domain_id)
return NULL; 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; struct pbk_domain *pd;
int bkt = 0; struct hlist_node *tmp;
unsigned long timeout;
// char buf[80]; int bkt;
// cpumap_print_to_pagebuf(1, buf, request);
// pr_err("X = request = %s hash_empty = %d\n", buf, hash_empty(pbk_domains)); timeout = USEC_PER_SEC;
while (timeout--) {
spin_lock(&pbk_domains_lock); hash_for_each_safe(pbk_domains, bkt, tmp, pd, ht_node) {
hash_for_each(pbk_domains, bkt, pd, ht_node) { if (cpumask_equal(mask, pbk_domain_cpu(pd))) {
if (cpumask_equal(pbk_domain_cpu(pd), request)) {
spin_unlock(&pbk_domains_lock);
get_pbk_domain(pd); get_pbk_domain(pd);
return 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; return NULL;
} }
......
...@@ -19,18 +19,15 @@ static ssize_t pbk_create_domain_store(struct kobject *kobj, ...@@ -19,18 +19,15 @@ static ssize_t pbk_create_domain_store(struct kobject *kobj,
if (ret || !cpumask_subset(&request, pbk_cpuset)) if (ret || !cpumask_subset(&request, pbk_cpuset))
return -EINVAL; return -EINVAL;
pd = pbk_find_matched_domain(&request);
if (pd == NULL) {
ret = pbk_alloc_cpus(&request); ret = pbk_alloc_cpus(&request);
if (ret) if (ret)
return ret; goto try_get_pd;
pd = pbk_alloc_domain(&request); pd = pbk_alloc_domain(&request);
if (IS_ERR(pd)) { if (IS_ERR(pd)) {
pr_err("Failed to allocate pbk domain\n"); pr_err("Failed to allocate pbk domain\n");
return PTR_ERR(pd); return PTR_ERR(pd);
} }
}
current->pbkd = pd; current->pbkd = pd;
...@@ -39,22 +36,9 @@ static ssize_t pbk_create_domain_store(struct kobject *kobj, ...@@ -39,22 +36,9 @@ static ssize_t pbk_create_domain_store(struct kobject *kobj,
return ret; return ret;
return count; 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); try_get_pd:
if (ret) pd = pbk_find_get_domain_withcpu(&request);
return -EINVAL;
pd = pbk_find_get_domain(domain_id);
if (!pd) if (!pd)
return -EINVAL; return -EINVAL;
...@@ -65,7 +49,7 @@ static ssize_t pbk_join_domain_store(struct kobject *kobj, ...@@ -65,7 +49,7 @@ static ssize_t pbk_join_domain_store(struct kobject *kobj,
return count; 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, static ssize_t pbk_with_nr_cpu_store(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count) 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); ...@@ -123,7 +107,6 @@ static struct kobj_attribute pbk_view_attr = __ATTR_WO(pbk_view);
static struct attribute *pbk_attributes[] = { static struct attribute *pbk_attributes[] = {
&pbk_create_domain_attr.attr, &pbk_create_domain_attr.attr,
&pbk_join_domain_attr.attr,
&pbk_with_nr_cpu_attr.attr, &pbk_with_nr_cpu_attr.attr,
&pbk_view_attr.attr, &pbk_view_attr.attr,
NULL NULL
...@@ -142,7 +125,6 @@ static int __init pbk_sysfs_init(void) ...@@ -142,7 +125,6 @@ static int __init pbk_sysfs_init(void)
return -ENOMEM; return -ENOMEM;
pbk_create_domain_attr.attr.mode |= S_IWGRP; 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_with_nr_cpu_attr.attr.mode |= S_IWGRP;
pbk_view_attr.attr.mode |= S_IWGRP; pbk_view_attr.attr.mode |= S_IWGRP;
......
...@@ -35,7 +35,7 @@ struct pbk_domain { ...@@ -35,7 +35,7 @@ struct pbk_domain {
extern void pbk_create_root_domain(void); 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_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 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 pbk_attach_domain(struct task_struct *p, struct pbk_domain *pd);
extern void destroy_pbk_domain(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) ...@@ -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 do_cpu_up(unsigned int cpu, enum cpuhp_state target);
extern int cpu_down(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 /* _LINUX_PBK_H */
#endif /* CONFIG_PURPOSE_BUILT_KERNEL */ #endif /* CONFIG_PURPOSE_BUILT_KERNEL */
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册