Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 204352
b: refs/heads/master
c: 5e017dc
h: refs/heads/master
v: v3
  • Loading branch information
Dan Kruchinin authored and Herbert Xu committed Jul 19, 2010
1 parent 6ac4f39 commit 428f6d8
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e15bacbebb9dcc95f148f28dfc83a6d5e48b60b8
refs/heads/master: 5e017dc3f8bc9e4a28983666e6bc00114a2018bb
5 changes: 4 additions & 1 deletion trunk/include/linux/padata.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/notifier.h>
#include <linux/kobject.h>

#define PADATA_CPU_SERIAL 0x01
#define PADATA_CPU_PARALLEL 0x02
Expand Down Expand Up @@ -142,7 +143,8 @@ struct parallel_data {
* cbcpu for parallel and serial works respectivly.
* @cpumask_change_notifier: Notifiers chain for user-defined notify
* callbacks that will be called when either @pcpu or @cbcpu
* or both cpumasks change.
* or both cpumasks change.
* @kobj: padata instance kernel object.
* @lock: padata instance lock.
* @flags: padata flags.
*/
Expand All @@ -155,6 +157,7 @@ struct padata_instance {
cpumask_var_t cbcpu;
} cpumask;
struct blocking_notifier_head cpumask_change_notifier;
struct kobject kobj;
struct mutex lock;
u8 flags;
#define PADATA_INIT 1
Expand Down
155 changes: 146 additions & 9 deletions trunk/kernel/padata.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/rcupdate.h>

#define MAX_SEQ_NR (INT_MAX - NR_CPUS)
Expand Down Expand Up @@ -924,6 +925,149 @@ static int padata_cpu_callback(struct notifier_block *nfb,
}
#endif

static void __padata_free(struct padata_instance *pinst)
{
#ifdef CONFIG_HOTPLUG_CPU
unregister_hotcpu_notifier(&pinst->cpu_notifier);
#endif

padata_stop(pinst);
padata_free_pd(pinst->pd);
free_cpumask_var(pinst->cpumask.pcpu);
free_cpumask_var(pinst->cpumask.cbcpu);
kfree(pinst);
}

#define kobj2pinst(_kobj) \
container_of(_kobj, struct padata_instance, kobj)
#define attr2pentry(_attr) \
container_of(_attr, struct padata_sysfs_entry, attr)

static void padata_sysfs_release(struct kobject *kobj)
{
struct padata_instance *pinst = kobj2pinst(kobj);
__padata_free(pinst);
}

struct padata_sysfs_entry {
struct attribute attr;
ssize_t (*show)(struct padata_instance *, struct attribute *, char *);
ssize_t (*store)(struct padata_instance *, struct attribute *,
const char *, size_t);
};

static ssize_t show_cpumask(struct padata_instance *pinst,
struct attribute *attr, char *buf)
{
struct cpumask *cpumask;
ssize_t len;

mutex_lock(&pinst->lock);
if (!strcmp(attr->name, "serial_cpumask"))
cpumask = pinst->cpumask.cbcpu;
else
cpumask = pinst->cpumask.pcpu;

len = bitmap_scnprintf(buf, PAGE_SIZE, cpumask_bits(cpumask),
nr_cpu_ids);
if (PAGE_SIZE - len < 2)
len = -EINVAL;
else
len += sprintf(buf + len, "\n");

mutex_unlock(&pinst->lock);
return len;
}

static ssize_t store_cpumask(struct padata_instance *pinst,
struct attribute *attr,
const char *buf, size_t count)
{
cpumask_var_t new_cpumask;
ssize_t ret;
int mask_type;

if (!alloc_cpumask_var(&new_cpumask, GFP_KERNEL))
return -ENOMEM;

ret = bitmap_parse(buf, count, cpumask_bits(new_cpumask),
nr_cpumask_bits);
if (ret < 0)
goto out;

mask_type = !strcmp(attr->name, "serial_cpumask") ?
PADATA_CPU_SERIAL : PADATA_CPU_PARALLEL;
ret = padata_set_cpumask(pinst, mask_type, new_cpumask);
if (!ret)
ret = count;

out:
free_cpumask_var(new_cpumask);
return ret;
}

#define PADATA_ATTR_RW(_name, _show_name, _store_name) \
static struct padata_sysfs_entry _name##_attr = \
__ATTR(_name, 0644, _show_name, _store_name)
#define PADATA_ATTR_RO(_name, _show_name) \
static struct padata_sysfs_entry _name##_attr = \
__ATTR(_name, 0400, _show_name, NULL)

PADATA_ATTR_RW(serial_cpumask, show_cpumask, store_cpumask);
PADATA_ATTR_RW(parallel_cpumask, show_cpumask, store_cpumask);

/*
* Padata sysfs provides the following objects:
* serial_cpumask [RW] - cpumask for serial workers
* parallel_cpumask [RW] - cpumask for parallel workers
*/
static struct attribute *padata_default_attrs[] = {
&serial_cpumask_attr.attr,
&parallel_cpumask_attr.attr,
NULL,
};

static ssize_t padata_sysfs_show(struct kobject *kobj,
struct attribute *attr, char *buf)
{
struct padata_instance *pinst;
struct padata_sysfs_entry *pentry;
ssize_t ret = -EIO;

pinst = kobj2pinst(kobj);
pentry = attr2pentry(attr);
if (pentry->show)
ret = pentry->show(pinst, attr, buf);

return ret;
}

static ssize_t padata_sysfs_store(struct kobject *kobj, struct attribute *attr,
const char *buf, size_t count)
{
struct padata_instance *pinst;
struct padata_sysfs_entry *pentry;
ssize_t ret = -EIO;

pinst = kobj2pinst(kobj);
pentry = attr2pentry(attr);
if (pentry->show)
ret = pentry->store(pinst, attr, buf, count);

return ret;
}

static const struct sysfs_ops padata_sysfs_ops = {
.show = padata_sysfs_show,
.store = padata_sysfs_store,
};

static struct kobj_type padata_attr_type = {
.sysfs_ops = &padata_sysfs_ops,
.default_attrs = padata_default_attrs,
.release = padata_sysfs_release,
};

/**
* padata_alloc - Allocate and initialize padata instance.
* Use default cpumask(cpu_possible_mask)
Expand Down Expand Up @@ -989,6 +1133,7 @@ struct padata_instance *__padata_alloc(struct workqueue_struct *wq,
put_online_cpus();

BLOCKING_INIT_NOTIFIER_HEAD(&pinst->cpumask_change_notifier);
kobject_init(&pinst->kobj, &padata_attr_type);
mutex_init(&pinst->lock);

return pinst;
Expand All @@ -1011,14 +1156,6 @@ EXPORT_SYMBOL(__padata_alloc);
*/
void padata_free(struct padata_instance *pinst)
{
#ifdef CONFIG_HOTPLUG_CPU
unregister_hotcpu_notifier(&pinst->cpu_notifier);
#endif

padata_stop(pinst);
padata_free_pd(pinst->pd);
free_cpumask_var(pinst->cpumask.pcpu);
free_cpumask_var(pinst->cpumask.cbcpu);
kfree(pinst);
kobject_put(&pinst->kobj);
}
EXPORT_SYMBOL(padata_free);

0 comments on commit 428f6d8

Please sign in to comment.