aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/padata.h5
-rw-r--r--kernel/padata.c155
2 files changed, 150 insertions, 10 deletions
diff --git a/include/linux/padata.h b/include/linux/padata.h
index 621e7736690c..293ad46ffced 100644
--- a/include/linux/padata.h
+++ b/include/linux/padata.h
@@ -26,6 +26,7 @@
26#include <linux/list.h> 26#include <linux/list.h>
27#include <linux/timer.h> 27#include <linux/timer.h>
28#include <linux/notifier.h> 28#include <linux/notifier.h>
29#include <linux/kobject.h>
29 30
30#define PADATA_CPU_SERIAL 0x01 31#define PADATA_CPU_SERIAL 0x01
31#define PADATA_CPU_PARALLEL 0x02 32#define PADATA_CPU_PARALLEL 0x02
@@ -142,7 +143,8 @@ struct parallel_data {
142 * cbcpu for parallel and serial works respectivly. 143 * cbcpu for parallel and serial works respectivly.
143 * @cpumask_change_notifier: Notifiers chain for user-defined notify 144 * @cpumask_change_notifier: Notifiers chain for user-defined notify
144 * callbacks that will be called when either @pcpu or @cbcpu 145 * callbacks that will be called when either @pcpu or @cbcpu
145 * or both cpumasks change. 146 * or both cpumasks change.
147 * @kobj: padata instance kernel object.
146 * @lock: padata instance lock. 148 * @lock: padata instance lock.
147 * @flags: padata flags. 149 * @flags: padata flags.
148 */ 150 */
@@ -155,6 +157,7 @@ struct padata_instance {
155 cpumask_var_t cbcpu; 157 cpumask_var_t cbcpu;
156 } cpumask; 158 } cpumask;
157 struct blocking_notifier_head cpumask_change_notifier; 159 struct blocking_notifier_head cpumask_change_notifier;
160 struct kobject kobj;
158 struct mutex lock; 161 struct mutex lock;
159 u8 flags; 162 u8 flags;
160#define PADATA_INIT 1 163#define PADATA_INIT 1
diff --git a/kernel/padata.c b/kernel/padata.c
index 84d0ca9dac9c..526f9ea2fcc8 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -26,6 +26,7 @@
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27#include <linux/sched.h> 27#include <linux/sched.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/sysfs.h>
29#include <linux/rcupdate.h> 30#include <linux/rcupdate.h>
30 31
31#define MAX_SEQ_NR (INT_MAX - NR_CPUS) 32#define MAX_SEQ_NR (INT_MAX - NR_CPUS)
@@ -924,6 +925,149 @@ static int padata_cpu_callback(struct notifier_block *nfb,
924} 925}
925#endif 926#endif
926 927
928static void __padata_free(struct padata_instance *pinst)
929{
930#ifdef CONFIG_HOTPLUG_CPU
931 unregister_hotcpu_notifier(&pinst->cpu_notifier);
932#endif
933
934 padata_stop(pinst);
935 padata_free_pd(pinst->pd);
936 free_cpumask_var(pinst->cpumask.pcpu);
937 free_cpumask_var(pinst->cpumask.cbcpu);
938 kfree(pinst);
939}
940
941#define kobj2pinst(_kobj) \
942 container_of(_kobj, struct padata_instance, kobj)
943#define attr2pentry(_attr) \
944 container_of(_attr, struct padata_sysfs_entry, attr)
945
946static void padata_sysfs_release(struct kobject *kobj)
947{
948 struct padata_instance *pinst = kobj2pinst(kobj);
949 __padata_free(pinst);
950}
951
952struct padata_sysfs_entry {
953 struct attribute attr;
954 ssize_t (*show)(struct padata_instance *, struct attribute *, char *);
955 ssize_t (*store)(struct padata_instance *, struct attribute *,
956 const char *, size_t);
957};
958
959static ssize_t show_cpumask(struct padata_instance *pinst,
960 struct attribute *attr, char *buf)
961{
962 struct cpumask *cpumask;
963 ssize_t len;
964
965 mutex_lock(&pinst->lock);
966 if (!strcmp(attr->name, "serial_cpumask"))
967 cpumask = pinst->cpumask.cbcpu;
968 else
969 cpumask = pinst->cpumask.pcpu;
970
971 len = bitmap_scnprintf(buf, PAGE_SIZE, cpumask_bits(cpumask),
972 nr_cpu_ids);
973 if (PAGE_SIZE - len < 2)
974 len = -EINVAL;
975 else
976 len += sprintf(buf + len, "\n");
977
978 mutex_unlock(&pinst->lock);
979 return len;
980}
981
982static ssize_t store_cpumask(struct padata_instance *pinst,
983 struct attribute *attr,
984 const char *buf, size_t count)
985{
986 cpumask_var_t new_cpumask;
987 ssize_t ret;
988 int mask_type;
989
990 if (!alloc_cpumask_var(&new_cpumask, GFP_KERNEL))
991 return -ENOMEM;
992
993 ret = bitmap_parse(buf, count, cpumask_bits(new_cpumask),
994 nr_cpumask_bits);
995 if (ret < 0)
996 goto out;
997
998 mask_type = !strcmp(attr->name, "serial_cpumask") ?
999 PADATA_CPU_SERIAL : PADATA_CPU_PARALLEL;
1000 ret = padata_set_cpumask(pinst, mask_type, new_cpumask);
1001 if (!ret)
1002 ret = count;
1003
1004out:
1005 free_cpumask_var(new_cpumask);
1006 return ret;
1007}
1008
1009#define PADATA_ATTR_RW(_name, _show_name, _store_name) \
1010 static struct padata_sysfs_entry _name##_attr = \
1011 __ATTR(_name, 0644, _show_name, _store_name)
1012#define PADATA_ATTR_RO(_name, _show_name) \
1013 static struct padata_sysfs_entry _name##_attr = \
1014 __ATTR(_name, 0400, _show_name, NULL)
1015
1016PADATA_ATTR_RW(serial_cpumask, show_cpumask, store_cpumask);
1017PADATA_ATTR_RW(parallel_cpumask, show_cpumask, store_cpumask);
1018
1019/*
1020 * Padata sysfs provides the following objects:
1021 * serial_cpumask [RW] - cpumask for serial workers
1022 * parallel_cpumask [RW] - cpumask for parallel workers
1023 */
1024static struct attribute *padata_default_attrs[] = {
1025 &serial_cpumask_attr.attr,
1026 &parallel_cpumask_attr.attr,
1027 NULL,
1028};
1029
1030static ssize_t padata_sysfs_show(struct kobject *kobj,
1031 struct attribute *attr, char *buf)
1032{
1033 struct padata_instance *pinst;
1034 struct padata_sysfs_entry *pentry;
1035 ssize_t ret = -EIO;
1036
1037 pinst = kobj2pinst(kobj);
1038 pentry = attr2pentry(attr);
1039 if (pentry->show)
1040 ret = pentry->show(pinst, attr, buf);
1041
1042 return ret;
1043}
1044
1045static ssize_t padata_sysfs_store(struct kobject *kobj, struct attribute *attr,
1046 const char *buf, size_t count)
1047{
1048 struct padata_instance *pinst;
1049 struct padata_sysfs_entry *pentry;
1050 ssize_t ret = -EIO;
1051
1052 pinst = kobj2pinst(kobj);
1053 pentry = attr2pentry(attr);
1054 if (pentry->show)
1055 ret = pentry->store(pinst, attr, buf, count);
1056
1057 return ret;
1058}
1059
1060static const struct sysfs_ops padata_sysfs_ops = {
1061 .show = padata_sysfs_show,
1062 .store = padata_sysfs_store,
1063};
1064
1065static struct kobj_type padata_attr_type = {
1066 .sysfs_ops = &padata_sysfs_ops,
1067 .default_attrs = padata_default_attrs,
1068 .release = padata_sysfs_release,
1069};
1070
927/** 1071/**
928 * padata_alloc - Allocate and initialize padata instance. 1072 * padata_alloc - Allocate and initialize padata instance.
929 * Use default cpumask(cpu_possible_mask) 1073 * Use default cpumask(cpu_possible_mask)
@@ -989,6 +1133,7 @@ struct padata_instance *__padata_alloc(struct workqueue_struct *wq,
989 put_online_cpus(); 1133 put_online_cpus();
990 1134
991 BLOCKING_INIT_NOTIFIER_HEAD(&pinst->cpumask_change_notifier); 1135 BLOCKING_INIT_NOTIFIER_HEAD(&pinst->cpumask_change_notifier);
1136 kobject_init(&pinst->kobj, &padata_attr_type);
992 mutex_init(&pinst->lock); 1137 mutex_init(&pinst->lock);
993 1138
994 return pinst; 1139 return pinst;
@@ -1011,14 +1156,6 @@ EXPORT_SYMBOL(__padata_alloc);
1011 */ 1156 */
1012void padata_free(struct padata_instance *pinst) 1157void padata_free(struct padata_instance *pinst)
1013{ 1158{
1014#ifdef CONFIG_HOTPLUG_CPU 1159 kobject_put(&pinst->kobj);
1015 unregister_hotcpu_notifier(&pinst->cpu_notifier);
1016#endif
1017
1018 padata_stop(pinst);
1019 padata_free_pd(pinst->pd);
1020 free_cpumask_var(pinst->cpumask.pcpu);
1021 free_cpumask_var(pinst->cpumask.cbcpu);
1022 kfree(pinst);
1023} 1160}
1024EXPORT_SYMBOL(padata_free); 1161EXPORT_SYMBOL(padata_free);