2010-07-27 05:10:20

by Steffen Klassert

[permalink] [raw]
Subject: [PATCH 0/7] padata/pcrypt: cleanups

This patchset contains the following changes:

1. padata - Rename padata_alloc functions to not export underlined functions.

2. padata - Rearrange set_cpumask functions to have proper locking for all
these functions and to avoid to export underlined functions.

3. padata - Pass the padata cpumasks to the cpumask_change_notifier chain, so
users can access them without the need of a padata_get_cpumask function.

4. pcrypt - Rename the stuct pcrypt_instance. An instance refers usually to a
crypto instance in the crypto-layer, the struct pcrypt_instance is not related
to a crypto instance, so we rename it.

5. pcrypt - Update pcrypt cpumask acording to the padata cpumask notifier.
The padata cpumask change notifier passes a padata_cpumask to the
notifier chain, so we use this to update the pcrypt cpumask.

6. padata - Remove padata_get_cpumask. This function is a bit error prone
because the cpumask can change at any time, so we can't be sure to get the
right cpumask from that function.

7. padata - Update the API documentation.

Steffen


2010-07-27 05:10:56

by Steffen Klassert

[permalink] [raw]
Subject: [PATCH 1/7] padata: Rename padata_alloc functions

We rename padata_alloc to padata_alloc_possible because this
function allocates a padata_instance and uses the cpu_possible
mask for parallel and serial workers. Also we rename __padata_alloc
to padata_alloc to avoid to export underlined functions. Underlined
functions are considered to be private to padata. Users are updated
accordingly.

Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/pcrypt.c | 2 +-
include/linux/padata.h | 9 +++++----
kernel/padata.c | 24 ++++++++++++------------
3 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
index 794c172..5546083 100644
--- a/crypto/pcrypt.c
+++ b/crypto/pcrypt.c
@@ -457,7 +457,7 @@ static int __pcrypt_init_instance(struct pcrypt_instance *pcrypt,
if (!pcrypt->wq)
goto err;

- pcrypt->pinst = padata_alloc(pcrypt->wq);
+ pcrypt->pinst = padata_alloc_possible(pcrypt->wq);
if (!pcrypt->pinst)
goto err_destroy_workqueue;

diff --git a/include/linux/padata.h b/include/linux/padata.h
index 293ad46..71dfc9d 100644
--- a/include/linux/padata.h
+++ b/include/linux/padata.h
@@ -165,10 +165,11 @@ struct padata_instance {
#define PADATA_INVALID 4
};

-extern struct padata_instance *padata_alloc(struct workqueue_struct *wq);
-extern struct padata_instance *__padata_alloc(struct workqueue_struct *wq,
- const struct cpumask *pcpumask,
- const struct cpumask *cbcpumask);
+extern struct padata_instance *padata_alloc_possible(
+ struct workqueue_struct *wq);
+extern struct padata_instance *padata_alloc(struct workqueue_struct *wq,
+ const struct cpumask *pcpumask,
+ const struct cpumask *cbcpumask);
extern void padata_free(struct padata_instance *pinst);
extern int padata_do_parallel(struct padata_instance *pinst,
struct padata_priv *padata, int cb_cpu);
diff --git a/kernel/padata.c b/kernel/padata.c
index 7f895e2..12860bc 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -1060,29 +1060,29 @@ static struct kobj_type padata_attr_type = {
};

/**
- * padata_alloc - Allocate and initialize padata instance.
- * Use default cpumask(cpu_possible_mask)
- * for serial and parallel workes.
+ * padata_alloc_possible - Allocate and initialize padata instance.
+ * Use the cpu_possible_mask for serial and
+ * parallel workers.
*
* @wq: workqueue to use for the allocated padata instance
*/
-struct padata_instance *padata_alloc(struct workqueue_struct *wq)
+struct padata_instance *padata_alloc_possible(struct workqueue_struct *wq)
{
- return __padata_alloc(wq, cpu_possible_mask, cpu_possible_mask);
+ return padata_alloc(wq, cpu_possible_mask, cpu_possible_mask);
}
-EXPORT_SYMBOL(padata_alloc);
+EXPORT_SYMBOL(padata_alloc_possible);

/**
- * __padata_alloc - allocate and initialize a padata instance
- * and specify cpumasks for serial and parallel workers.
+ * padata_alloc - allocate and initialize a padata instance and specify
+ * cpumasks for serial and parallel workers.
*
* @wq: workqueue to use for the allocated padata instance
* @pcpumask: cpumask that will be used for padata parallelization
* @cbcpumask: cpumask that will be used for padata serialization
*/
-struct padata_instance *__padata_alloc(struct workqueue_struct *wq,
- const struct cpumask *pcpumask,
- const struct cpumask *cbcpumask)
+struct padata_instance *padata_alloc(struct workqueue_struct *wq,
+ const struct cpumask *pcpumask,
+ const struct cpumask *cbcpumask)
{
struct padata_instance *pinst;
struct parallel_data *pd = NULL;
@@ -1138,7 +1138,7 @@ err_free_inst:
err:
return NULL;
}
-EXPORT_SYMBOL(__padata_alloc);
+EXPORT_SYMBOL(padata_alloc);

/**
* padata_free - free a padata instance
--
1.5.6.5

2010-07-27 05:11:34

by Steffen Klassert

[permalink] [raw]
Subject: [PATCH 2/7] padata: Rearrange set_cpumask functions

padata_set_cpumask needs to be protected by a lock. We make
__padata_set_cpumasks unlocked and static. So this function
can be used by the exported and locked padata_set_cpumask and
padata_set_cpumasks functions.

Signed-off-by: Steffen Klassert <[email protected]>
---
include/linux/padata.h | 6 +-
kernel/padata.c | 117 +++++++++++++++++++++++++++--------------------
2 files changed, 70 insertions(+), 53 deletions(-)

diff --git a/include/linux/padata.h b/include/linux/padata.h
index 71dfc9d..bb0fc5d 100644
--- a/include/linux/padata.h
+++ b/include/linux/padata.h
@@ -178,9 +178,9 @@ extern int padata_get_cpumask(struct padata_instance *pinst,
int cpumask_type, struct cpumask *out_mask);
extern int padata_set_cpumask(struct padata_instance *pinst, int cpumask_type,
cpumask_var_t cpumask);
-extern int __padata_set_cpumasks(struct padata_instance *pinst,
- cpumask_var_t pcpumask,
- cpumask_var_t cbcpumask);
+extern int padata_set_cpumasks(struct padata_instance *pinst,
+ cpumask_var_t pcpumask,
+ cpumask_var_t cbcpumask);
extern int padata_add_cpu(struct padata_instance *pinst, int cpu, int mask);
extern int padata_remove_cpu(struct padata_instance *pinst, int cpu, int mask);
extern int padata_start(struct padata_instance *pinst);
diff --git a/kernel/padata.c b/kernel/padata.c
index 12860bc..4987203 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -623,6 +623,66 @@ int padata_get_cpumask(struct padata_instance *pinst,
}
EXPORT_SYMBOL(padata_get_cpumask);

+static int __padata_set_cpumasks(struct padata_instance *pinst,
+ cpumask_var_t pcpumask,
+ cpumask_var_t cbcpumask)
+{
+ int valid;
+ struct parallel_data *pd;
+
+ valid = padata_validate_cpumask(pinst, pcpumask);
+ if (!valid) {
+ __padata_stop(pinst);
+ goto out_replace;
+ }
+
+ valid = padata_validate_cpumask(pinst, cbcpumask);
+ if (!valid)
+ __padata_stop(pinst);
+
+out_replace:
+ pd = padata_alloc_pd(pinst, pcpumask, cbcpumask);
+ if (!pd)
+ return -ENOMEM;
+
+ cpumask_copy(pinst->cpumask.pcpu, pcpumask);
+ cpumask_copy(pinst->cpumask.cbcpu, cbcpumask);
+
+ padata_replace(pinst, pd);
+
+ if (valid)
+ __padata_start(pinst);
+
+ return 0;
+}
+
+/**
+ * padata_set_cpumasks - Set both parallel and serial cpumasks. The first
+ * one is used by parallel workers and the second one
+ * by the wokers doing serialization.
+ *
+ * @pinst: padata instance
+ * @pcpumask: the cpumask to use for parallel workers
+ * @cbcpumask: the cpumsak to use for serial workers
+ */
+int padata_set_cpumasks(struct padata_instance *pinst, cpumask_var_t pcpumask,
+ cpumask_var_t cbcpumask)
+{
+ int err;
+
+ mutex_lock(&pinst->lock);
+ get_online_cpus();
+
+ err = __padata_set_cpumasks(pinst, pcpumask, cbcpumask);
+
+ put_online_cpus();
+ mutex_unlock(&pinst->lock);
+
+ return err;
+
+}
+EXPORT_SYMBOL(padata_set_cpumasks);
+
/**
* padata_set_cpumask: Sets specified by @cpumask_type cpumask to the value
* equivalent to @cpumask.
@@ -636,6 +696,10 @@ int padata_set_cpumask(struct padata_instance *pinst, int cpumask_type,
cpumask_var_t cpumask)
{
struct cpumask *serial_mask, *parallel_mask;
+ int err = -EINVAL;
+
+ mutex_lock(&pinst->lock);
+ get_online_cpus();

switch (cpumask_type) {
case PADATA_CPU_PARALLEL:
@@ -647,65 +711,18 @@ int padata_set_cpumask(struct padata_instance *pinst, int cpumask_type,
serial_mask = cpumask;
break;
default:
- return -EINVAL;
+ goto out;
}

- return __padata_set_cpumasks(pinst, parallel_mask, serial_mask);
-}
-EXPORT_SYMBOL(padata_set_cpumask);
-
-/**
- * __padata_set_cpumasks - Set both parallel and serial cpumasks. The first
- * one is used by parallel workers and the second one
- * by the wokers doing serialization.
- *
- * @pinst: padata instance
- * @pcpumask: the cpumask to use for parallel workers
- * @cbcpumask: the cpumsak to use for serial workers
- */
-int __padata_set_cpumasks(struct padata_instance *pinst,
- cpumask_var_t pcpumask, cpumask_var_t cbcpumask)
-{
- int valid;
- int err = 0;
- struct parallel_data *pd = NULL;
-
- mutex_lock(&pinst->lock);
- get_online_cpus();
-
- valid = padata_validate_cpumask(pinst, pcpumask);
- if (!valid) {
- __padata_stop(pinst);
- goto out_replace;
- }
-
- valid = padata_validate_cpumask(pinst, cbcpumask);
- if (!valid)
- __padata_stop(pinst);
-
-out_replace:
- pd = padata_alloc_pd(pinst, pcpumask, cbcpumask);
- if (!pd) {
- err = -ENOMEM;
- goto out;
- }
-
- cpumask_copy(pinst->cpumask.pcpu, pcpumask);
- cpumask_copy(pinst->cpumask.cbcpu, cbcpumask);
-
- padata_replace(pinst, pd);
-
- if (valid)
- __padata_start(pinst);
+ err = __padata_set_cpumasks(pinst, parallel_mask, serial_mask);

out:
put_online_cpus();
mutex_unlock(&pinst->lock);

return err;
-
}
-EXPORT_SYMBOL(__padata_set_cpumasks);
+EXPORT_SYMBOL(padata_set_cpumask);

static int __padata_add_cpu(struct padata_instance *pinst, int cpu)
{
--
1.5.6.5

2010-07-27 05:12:18

by Steffen Klassert

[permalink] [raw]
Subject: [PATCH 3/7] padata: Pass the padata cpumasks to the cpumask_change_notifier chain

We pass a pointer to the new padata cpumasks to the cpumask_change_notifier
chain. So users can access the cpumasks without the need of an extra
padata_get_cpumask function.

Signed-off-by: Steffen Klassert <[email protected]>
---
include/linux/padata.h | 40 +++++++++++++++++++++-------------------
kernel/padata.c | 3 ++-
2 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/include/linux/padata.h b/include/linux/padata.h
index bb0fc5d..43db792 100644
--- a/include/linux/padata.h
+++ b/include/linux/padata.h
@@ -98,6 +98,16 @@ struct padata_parallel_queue {
int cpu_index;
};

+/**
+ * struct padata_cpumask - The cpumasks for the parallel/serial workers
+ *
+ * @pcpu: cpumask for the parallel workers.
+ * @cbcpu: cpumask for the serial (callback) workers.
+ */
+struct padata_cpumask {
+ cpumask_var_t pcpu;
+ cpumask_var_t cbcpu;
+};

/**
* struct parallel_data - Internal control structure, covers everything
@@ -110,8 +120,7 @@ struct padata_parallel_queue {
* @reorder_objects: Number of objects waiting in the reorder queues.
* @refcnt: Number of objects holding a reference on this parallel_data.
* @max_seq_nr: Maximal used sequence number.
- * @cpumask: Contains two cpumasks: pcpu and cbcpu for
- * parallel and serial workers respectively.
+ * @cpumask: The cpumasks in use for parallel and serial workers.
* @lock: Reorder lock.
* @processed: Number of already processed objects.
* @timer: Reorder timer.
@@ -120,17 +129,14 @@ struct parallel_data {
struct padata_instance *pinst;
struct padata_parallel_queue *pqueue;
struct padata_serial_queue *squeue;
- atomic_t seq_nr;
- atomic_t reorder_objects;
- atomic_t refcnt;
- unsigned int max_seq_nr;
- struct {
- cpumask_var_t pcpu;
- cpumask_var_t cbcpu;
- } cpumask;
- spinlock_t lock ____cacheline_aligned;
- unsigned int processed;
- struct timer_list timer;
+ atomic_t seq_nr;
+ atomic_t reorder_objects;
+ atomic_t refcnt;
+ unsigned int max_seq_nr;
+ struct padata_cpumask cpumask;
+ spinlock_t lock ____cacheline_aligned;
+ unsigned int processed;
+ struct timer_list timer;
};

/**
@@ -139,8 +145,7 @@ struct parallel_data {
* @cpu_notifier: cpu hotplug notifier.
* @wq: The workqueue in use.
* @pd: The internal control structure.
- * @cpumask: User supplied cpumask. Contains two cpumasks: pcpu and
- * cbcpu for parallel and serial works respectivly.
+ * @cpumask: User supplied cpumasks for parallel and serial works.
* @cpumask_change_notifier: Notifiers chain for user-defined notify
* callbacks that will be called when either @pcpu or @cbcpu
* or both cpumasks change.
@@ -152,10 +157,7 @@ struct padata_instance {
struct notifier_block cpu_notifier;
struct workqueue_struct *wq;
struct parallel_data *pd;
- struct {
- cpumask_var_t pcpu;
- cpumask_var_t cbcpu;
- } cpumask;
+ struct padata_cpumask cpumask;
struct blocking_notifier_head cpumask_change_notifier;
struct kobject kobj;
struct mutex lock;
diff --git a/kernel/padata.c b/kernel/padata.c
index 4987203..1c8c1d1 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -538,7 +538,8 @@ static void padata_replace(struct padata_instance *pinst,

if (notification_mask)
blocking_notifier_call_chain(&pinst->cpumask_change_notifier,
- notification_mask, pinst);
+ notification_mask,
+ &pd_new->cpumask);

pinst->flags &= ~PADATA_RESET;
}
--
1.5.6.5

2010-07-27 05:13:01

by Steffen Klassert

[permalink] [raw]
Subject: [PATCH 4/7] crypto: pcrypt - Rename pcrypt_instance

In the crypto-layer an instance refers usually to a crypto instance.
The struct pcrypt_instance is not related to a crypto instance.
It rather contains the padata informations, so we rename it to
padata_pcrypt. The functions that handle this struct are renamed
accordingly.

Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/pcrypt.c | 30 ++++++++++++++----------------
1 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
index 5546083..7742553 100644
--- a/crypto/pcrypt.c
+++ b/crypto/pcrypt.c
@@ -28,8 +28,7 @@
#include <linux/kobject.h>
#include <crypto/pcrypt.h>

-struct pcrypt_instance {
- const char *name;
+struct padata_pcrypt {
struct padata_instance *pinst;
struct workqueue_struct *wq;

@@ -55,8 +54,8 @@ struct pcrypt_instance {
struct notifier_block nblock;
};

-static struct pcrypt_instance pencrypt;
-static struct pcrypt_instance pdecrypt;
+static struct padata_pcrypt pencrypt;
+static struct padata_pcrypt pdecrypt;
static struct kset *pcrypt_kset;

struct pcrypt_instance_ctx {
@@ -70,7 +69,7 @@ struct pcrypt_aead_ctx {
};

static int pcrypt_do_parallel(struct padata_priv *padata, unsigned int *cb_cpu,
- struct pcrypt_instance *pcrypt)
+ struct padata_pcrypt *pcrypt)
{
unsigned int cpu_index, cpu, i;
struct pcrypt_cpumask *cpumask;
@@ -408,13 +407,13 @@ static void pcrypt_free(struct crypto_instance *inst)
static int pcrypt_cpumask_change_notify(struct notifier_block *self,
unsigned long val, void *data)
{
- struct pcrypt_instance *pcrypt;
+ struct padata_pcrypt *pcrypt;
struct pcrypt_cpumask *new_mask, *old_mask;

if (!(val & PADATA_CPU_SERIAL))
return 0;

- pcrypt = container_of(self, struct pcrypt_instance, nblock);
+ pcrypt = container_of(self, struct padata_pcrypt, nblock);
new_mask = kmalloc(sizeof(*new_mask), GFP_KERNEL);
if (!new_mask)
return -ENOMEM;
@@ -446,13 +445,12 @@ static int pcrypt_sysfs_add(struct padata_instance *pinst, const char *name)
return ret;
}

-static int __pcrypt_init_instance(struct pcrypt_instance *pcrypt,
- const char *name)
+static int pcrypt_init_padata(struct padata_pcrypt *pcrypt,
+ const char *name)
{
int ret = -ENOMEM;
struct pcrypt_cpumask *mask;

- pcrypt->name = name;
pcrypt->wq = create_workqueue(name);
if (!pcrypt->wq)
goto err;
@@ -495,7 +493,7 @@ err:
return ret;
}

-static void __pcrypt_deinit_instance(struct pcrypt_instance *pcrypt)
+static void pcrypt_fini_padata(struct padata_pcrypt *pcrypt)
{
kobject_put(&pcrypt->pinst->kobj);
free_cpumask_var(pcrypt->cb_cpumask->mask);
@@ -522,11 +520,11 @@ static int __init pcrypt_init(void)
if (!pcrypt_kset)
goto err;

- err = __pcrypt_init_instance(&pencrypt, "pencrypt");
+ err = pcrypt_init_padata(&pencrypt, "pencrypt");
if (err)
goto err_unreg_kset;

- err = __pcrypt_init_instance(&pdecrypt, "pdecrypt");
+ err = pcrypt_init_padata(&pdecrypt, "pdecrypt");
if (err)
goto err_deinit_pencrypt;

@@ -536,7 +534,7 @@ static int __init pcrypt_init(void)
return crypto_register_template(&pcrypt_tmpl);

err_deinit_pencrypt:
- __pcrypt_deinit_instance(&pencrypt);
+ pcrypt_fini_padata(&pencrypt);
err_unreg_kset:
kset_unregister(pcrypt_kset);
err:
@@ -545,8 +543,8 @@ err:

static void __exit pcrypt_exit(void)
{
- __pcrypt_deinit_instance(&pencrypt);
- __pcrypt_deinit_instance(&pdecrypt);
+ pcrypt_fini_padata(&pencrypt);
+ pcrypt_fini_padata(&pdecrypt);

kset_unregister(pcrypt_kset);
crypto_unregister_template(&pcrypt_tmpl);
--
1.5.6.5

2010-07-27 05:15:13

by Steffen Klassert

[permalink] [raw]
Subject: [PATCH 5/7] crypto: pcrypt - Update pcrypt cpumask according to the padata cpumask notifier

The padata cpumask change notifier passes a padata_cpumask to the
notifier chain. So we use this cpumask instead of asking padata for
the cpumask.

Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/pcrypt.c | 13 +++++++++++--
1 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
index 7742553..de30782 100644
--- a/crypto/pcrypt.c
+++ b/crypto/pcrypt.c
@@ -26,6 +26,7 @@
#include <linux/slab.h>
#include <linux/notifier.h>
#include <linux/kobject.h>
+#include <linux/cpu.h>
#include <crypto/pcrypt.h>

struct padata_pcrypt {
@@ -409,6 +410,7 @@ static int pcrypt_cpumask_change_notify(struct notifier_block *self,
{
struct padata_pcrypt *pcrypt;
struct pcrypt_cpumask *new_mask, *old_mask;
+ struct padata_cpumask *cpumask = (struct padata_cpumask *)data;

if (!(val & PADATA_CPU_SERIAL))
return 0;
@@ -424,7 +426,7 @@ static int pcrypt_cpumask_change_notify(struct notifier_block *self,

old_mask = pcrypt->cb_cpumask;

- padata_get_cpumask(pcrypt->pinst, PADATA_CPU_SERIAL, new_mask->mask);
+ cpumask_copy(new_mask->mask, cpumask->cbcpu);
rcu_assign_pointer(pcrypt->cb_cpumask, new_mask);
synchronize_rcu_bh();

@@ -451,6 +453,8 @@ static int pcrypt_init_padata(struct padata_pcrypt *pcrypt,
int ret = -ENOMEM;
struct pcrypt_cpumask *mask;

+ get_online_cpus();
+
pcrypt->wq = create_workqueue(name);
if (!pcrypt->wq)
goto err;
@@ -467,7 +471,7 @@ static int pcrypt_init_padata(struct padata_pcrypt *pcrypt,
goto err_free_padata;
}

- padata_get_cpumask(pcrypt->pinst, PADATA_CPU_SERIAL, mask->mask);
+ cpumask_and(mask->mask, cpu_possible_mask, cpu_active_mask);
rcu_assign_pointer(pcrypt->cb_cpumask, mask);

pcrypt->nblock.notifier_call = pcrypt_cpumask_change_notify;
@@ -479,7 +483,10 @@ static int pcrypt_init_padata(struct padata_pcrypt *pcrypt,
if (ret)
goto err_unregister_notifier;

+ put_online_cpus();
+
return ret;
+
err_unregister_notifier:
padata_unregister_cpumask_notifier(pcrypt->pinst, &pcrypt->nblock);
err_free_cpumask:
@@ -490,6 +497,8 @@ err_free_padata:
err_destroy_workqueue:
destroy_workqueue(pcrypt->wq);
err:
+ put_online_cpus();
+
return ret;
}

--
1.5.6.5

2010-07-27 05:16:05

by Steffen Klassert

[permalink] [raw]
Subject: [PATCH 6/7] padata: Remove padata_get_cpumask

A function that copies the padata cpumasks to a user buffer
is a bit error prone. The cpumask can change any time so we
can't be sure to have the right cpumask when using this function.
A user who is interested in the padata cpumasks should register
to the padata cpumask notifier chain instead. Users of
padata_get_cpumask are already updated, so we can remove it.

Signed-off-by: Steffen Klassert <[email protected]>
---
include/linux/padata.h | 2 --
kernel/padata.c | 35 -----------------------------------
2 files changed, 0 insertions(+), 37 deletions(-)

diff --git a/include/linux/padata.h b/include/linux/padata.h
index 43db792..bdcd1e9 100644
--- a/include/linux/padata.h
+++ b/include/linux/padata.h
@@ -176,8 +176,6 @@ extern void padata_free(struct padata_instance *pinst);
extern int padata_do_parallel(struct padata_instance *pinst,
struct padata_priv *padata, int cb_cpu);
extern void padata_do_serial(struct padata_priv *padata);
-extern int padata_get_cpumask(struct padata_instance *pinst,
- int cpumask_type, struct cpumask *out_mask);
extern int padata_set_cpumask(struct padata_instance *pinst, int cpumask_type,
cpumask_var_t cpumask);
extern int padata_set_cpumasks(struct padata_instance *pinst,
diff --git a/kernel/padata.c b/kernel/padata.c
index 1c8c1d1..fd46792 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -589,41 +589,6 @@ static bool padata_validate_cpumask(struct padata_instance *pinst,
return true;
}

-/**
- * padata_get_cpumask: Fetch serial or parallel cpumask from the
- * given padata instance and copy it to @out_mask
- *
- * @pinst: A pointer to padata instance
- * @cpumask_type: Specifies which cpumask will be copied.
- * Possible values are PADATA_CPU_SERIAL *or* PADATA_CPU_PARALLEL
- * corresponding to serial and parallel cpumask respectively.
- * @out_mask: A pointer to cpumask structure where selected
- * cpumask will be copied.
- */
-int padata_get_cpumask(struct padata_instance *pinst,
- int cpumask_type, struct cpumask *out_mask)
-{
- struct parallel_data *pd;
- int ret = 0;
-
- rcu_read_lock_bh();
- pd = rcu_dereference(pinst->pd);
- switch (cpumask_type) {
- case PADATA_CPU_SERIAL:
- cpumask_copy(out_mask, pd->cpumask.cbcpu);
- break;
- case PADATA_CPU_PARALLEL:
- cpumask_copy(out_mask, pd->cpumask.pcpu);
- break;
- default:
- ret = -EINVAL;
- }
-
- rcu_read_unlock_bh();
- return ret;
-}
-EXPORT_SYMBOL(padata_get_cpumask);
-
static int __padata_set_cpumasks(struct padata_instance *pinst,
cpumask_var_t pcpumask,
cpumask_var_t cbcpumask)
--
1.5.6.5

2010-07-27 05:17:24

by Steffen Klassert

[permalink] [raw]
Subject: [PATCH 7/7] padata: update API documentation


Signed-off-by: Steffen Klassert <[email protected]>
---
Documentation/padata.txt | 76 ++++++++++++++++++++++++++++++++++++++-------
1 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/Documentation/padata.txt b/Documentation/padata.txt
index 93dd4e6..ad2a0ff 100644
--- a/Documentation/padata.txt
+++ b/Documentation/padata.txt
@@ -1,5 +1,5 @@
The padata parallel execution mechanism
-Last updated for 2.6.34
+Last updated for 2.6.36

Padata is a mechanism by which the kernel can farm work out to be done in
parallel on multiple CPUs while retaining the ordering of tasks. It was
@@ -13,12 +13,28 @@ overall control of how tasks are to be run:

#include <linux/padata.h>

- struct padata_instance *padata_alloc(const struct cpumask *cpumask,
- struct workqueue_struct *wq);
+ struct padata_instance *padata_alloc(struct workqueue_struct *wq,
+ const struct cpumask *pcpumask,
+ const struct cpumask *cbcpumask);

-The cpumask describes which processors will be used to execute work
-submitted to this instance. The workqueue wq is where the work will
-actually be done; it should be a multithreaded queue, naturally.
+The pcpumask describes which processors will be used to execute work
+submitted to this instance in parallel. The cbcpumask defines which
+processors are allowed to use as the serialization callback processor.
+The workqueue wq is where the work will actually be done; it should be
+a multithreaded queue, naturally.
+
+To allocate a padata instance with the cpu_possible_mask for both
+cpumasks this helper function can be used:
+
+ struct padata_instance *padata_alloc_possible(struct workqueue_struct *wq);
+
+Note: Padata maintains two kinds of cpumasks internally. The user supplied
+cpumasks, submitted by padata_alloc/padata_alloc_possible and the 'usable'
+cpumasks. The usable cpumasks are always the subset of active cpus in the
+user supplied cpumasks, these are the cpumasks padata actually use. So
+it is legal to supply a cpumask to padata that contains offline cpus.
+Once a offline cpu in the user supplied cpumask comes online, padata
+is going to use it.

There are functions for enabling and disabling the instance:

@@ -34,13 +50,49 @@ is unused.

The list of CPUs to be used can be adjusted with these functions:

- int padata_set_cpumask(struct padata_instance *pinst,
+ int padata_set_cpumasks(struct padata_instance *pinst,
+ cpumask_var_t pcpumask,
+ cpumask_var_t cbcpumask);
+ int padata_set_cpumask(struct padata_instance *pinst, int cpumask_type,
cpumask_var_t cpumask);
- int padata_add_cpu(struct padata_instance *pinst, int cpu);
- int padata_remove_cpu(struct padata_instance *pinst, int cpu);
+ int padata_add_cpu(struct padata_instance *pinst, int cpu, int mask);
+ int padata_remove_cpu(struct padata_instance *pinst, int cpu, int mask);
+
+Changing the CPU masks are expensive operations, though, so it should not be
+done with great frequency.
+
+It's possible to change both cpumasks of a padata instance with
+padata_set_cpumasks by specifying the cpumasks for parallel execution (pcpumask)
+and for the serial callback function (cbcpumask). padata_set_cpumask is to
+change just one of the cpumasks. Here cpumask_type is one of PADATA_CPU_SERIAL,
+PADATA_CPU_PARALLEL and cpumask specifies the new cpumask to use.
+To simply add or remove one cpu from a certain cpumask the functions
+padata_add_cpu/padata_remove_cpu are used. cpu specifies the cpu to add or
+remove and mask is one of PADATA_CPU_SERIAL, PADATA_CPU_PARALLEL.
+
+If a user is interested in padata cpumask changes, he can register to
+the padata cpumask change notifier:
+
+ int padata_register_cpumask_notifier(struct padata_instance *pinst,
+ struct notifier_block *nblock);
+
+To unregister from that notifier:
+
+ int padata_unregister_cpumask_notifier(struct padata_instance *pinst,
+ struct notifier_block *nblock);
+
+The padata cpumask change notifier notifies about changes of the usable
+cpumasks, i.e. the subset of active cpus in the user supplied cpumask.
+
+Padata calls the notifier chain with:
+
+ blocking_notifier_call_chain(&pinst->cpumask_change_notifier,
+ notification_mask,
+ &pd_new->cpumask);

-Changing the CPU mask has the look of an expensive operation, though, so it
-probably should not be done with great frequency.
+Here cpumask_change_notifier is registered notifier, notification_mask
+is one of PADATA_CPU_SERIAL, PADATA_CPU_PARALLEL and cpumask is a pointer
+to a struct padata_cpumask that contains the new cpumask informations.

Actually submitting work to the padata instance requires the creation of a
padata_priv structure:
@@ -53,7 +105,7 @@ padata_priv structure:

This structure will almost certainly be embedded within some larger
structure specific to the work to be done. Most its fields are private to
-padata, but the structure should be zeroed at initialization time, and the
+padata, but the structure should be zeroed at initialisation time, and the
parallel() and serial() functions should be provided. Those functions will
be called in the process of getting the work done as we will see
momentarily.
--
1.5.6.5

2010-07-31 11:56:42

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH 0/7] padata/pcrypt: cleanups

On Tue, Jul 27, 2010 at 07:13:47AM +0200, Steffen Klassert wrote:
> This patchset contains the following changes:

All applied. Thanks Steffen.
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

2010-08-03 17:54:45

by Randy Dunlap

[permalink] [raw]
Subject: Re: [PATCH 7/7] padata: update API documentation

On Tue, 27 Jul 2010 07:20:47 +0200 Steffen Klassert wrote:

>
> Signed-off-by: Steffen Klassert <[email protected]>
> ---
> Documentation/padata.txt | 76 ++++++++++++++++++++++++++++++++++++++-------
> 1 files changed, 64 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/padata.txt b/Documentation/padata.txt
> index 93dd4e6..ad2a0ff 100644
> --- a/Documentation/padata.txt
> +++ b/Documentation/padata.txt
> @@ -1,5 +1,5 @@
> The padata parallel execution mechanism
> -Last updated for 2.6.34
> +Last updated for 2.6.36
>
> Padata is a mechanism by which the kernel can farm work out to be done in
> parallel on multiple CPUs while retaining the ordering of tasks. It was
> @@ -13,12 +13,28 @@ overall control of how tasks are to be run:
>
> #include <linux/padata.h>
>
> - struct padata_instance *padata_alloc(const struct cpumask *cpumask,
> - struct workqueue_struct *wq);
> + struct padata_instance *padata_alloc(struct workqueue_struct *wq,
> + const struct cpumask *pcpumask,
> + const struct cpumask *cbcpumask);
>
> -The cpumask describes which processors will be used to execute work
> -submitted to this instance. The workqueue wq is where the work will
> -actually be done; it should be a multithreaded queue, naturally.
> +The pcpumask describes which processors will be used to execute work
> +submitted to this instance in parallel. The cbcpumask defines which
> +processors are allowed to use as the serialization callback processor.

to be used as

> +The workqueue wq is where the work will actually be done; it should be
> +a multithreaded queue, naturally.
> +
> +To allocate a padata instance with the cpu_possible_mask for both
> +cpumasks this helper function can be used:
> +
> + struct padata_instance *padata_alloc_possible(struct workqueue_struct *wq);
> +
> +Note: Padata maintains two kinds of cpumasks internally. The user supplied
> +cpumasks, submitted by padata_alloc/padata_alloc_possible and the 'usable'
> +cpumasks. The usable cpumasks are always the subset of active cpus in the

a subset of

> +user supplied cpumasks, these are the cpumasks padata actually use. So

cpumasks; uses.

> +it is legal to supply a cpumask to padata that contains offline cpus.
> +Once a offline cpu in the user supplied cpumask comes online, padata

an offline

and prefer s/cpu/CPU/ throughout (in text, but not when it is a function
parameter, of course)


> +is going to use it.
>
> There are functions for enabling and disabling the instance:
>
> @@ -34,13 +50,49 @@ is unused.
>
> The list of CPUs to be used can be adjusted with these functions:
>
> - int padata_set_cpumask(struct padata_instance *pinst,
> + int padata_set_cpumasks(struct padata_instance *pinst,
> + cpumask_var_t pcpumask,
> + cpumask_var_t cbcpumask);
> + int padata_set_cpumask(struct padata_instance *pinst, int cpumask_type,
> cpumask_var_t cpumask);
> - int padata_add_cpu(struct padata_instance *pinst, int cpu);
> - int padata_remove_cpu(struct padata_instance *pinst, int cpu);
> + int padata_add_cpu(struct padata_instance *pinst, int cpu, int mask);
> + int padata_remove_cpu(struct padata_instance *pinst, int cpu, int mask);
> +
> +Changing the CPU masks are expensive operations, though, so it should not be
> +done with great frequency.
> +
> +It's possible to change both cpumasks of a padata instance with
> +padata_set_cpumasks by specifying the cpumasks for parallel execution (pcpumask)
> +and for the serial callback function (cbcpumask). padata_set_cpumask is to

is used to

> +change just one of the cpumasks. Here cpumask_type is one of PADATA_CPU_SERIAL,
> +PADATA_CPU_PARALLEL and cpumask specifies the new cpumask to use.
> +To simply add or remove one cpu from a certain cpumask the functions
> +padata_add_cpu/padata_remove_cpu are used. cpu specifies the cpu to add or
> +remove and mask is one of PADATA_CPU_SERIAL, PADATA_CPU_PARALLEL.
> +
> +If a user is interested in padata cpumask changes, he can register to
> +the padata cpumask change notifier:
> +
> + int padata_register_cpumask_notifier(struct padata_instance *pinst,
> + struct notifier_block *nblock);
> +
> +To unregister from that notifier:
> +
> + int padata_unregister_cpumask_notifier(struct padata_instance *pinst,
> + struct notifier_block *nblock);
> +
> +The padata cpumask change notifier notifies about changes of the usable
> +cpumasks, i.e. the subset of active cpus in the user supplied cpumask.
> +
> +Padata calls the notifier chain with:
> +
> + blocking_notifier_call_chain(&pinst->cpumask_change_notifier,
> + notification_mask,
> + &pd_new->cpumask);
>
> -Changing the CPU mask has the look of an expensive operation, though, so it
> -probably should not be done with great frequency.
> +Here cpumask_change_notifier is registered notifier, notification_mask
> +is one of PADATA_CPU_SERIAL, PADATA_CPU_PARALLEL and cpumask is a pointer
> +to a struct padata_cpumask that contains the new cpumask informations.

information.

>
> Actually submitting work to the padata instance requires the creation of a
> padata_priv structure:
> @@ -53,7 +105,7 @@ padata_priv structure:
>
> This structure will almost certainly be embedded within some larger
> structure specific to the work to be done. Most its fields are private to

Most of its

> -padata, but the structure should be zeroed at initialization time, and the
> +padata, but the structure should be zeroed at initialisation time, and the

^^either spelling is OK

> parallel() and serial() functions should be provided. Those functions will
> be called in the process of getting the work done as we will see
> momentarily.
> --


---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***