diff options
Diffstat (limited to 'include/linux/padata.h')
| -rw-r--r-- | include/linux/padata.h | 85 |
1 files changed, 45 insertions, 40 deletions
diff --git a/include/linux/padata.h b/include/linux/padata.h index 56f09e36f770..a0d8b41850b2 100644 --- a/include/linux/padata.h +++ b/include/linux/padata.h @@ -9,18 +9,17 @@ #ifndef PADATA_H #define PADATA_H +#include <linux/compiler_types.h> #include <linux/workqueue.h> #include <linux/spinlock.h> #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 /** - * struct padata_priv - Embedded to the users data structure. + * struct padata_priv - Represents one job * * @list: List entry, to attach to the padata lists. * @pd: Pointer to the internal control structure. @@ -36,13 +35,14 @@ struct padata_priv { struct parallel_data *pd; int cb_cpu; int cpu; + unsigned int seq_nr; int info; void (*parallel)(struct padata_priv *padata); void (*serial)(struct padata_priv *padata); }; /** - * struct padata_list + * struct padata_list - one per work type per CPU * * @list: List head. * @lock: List lock. @@ -70,23 +70,14 @@ struct padata_serial_queue { * * @parallel: List to wait for parallelization. * @reorder: List to wait for reordering after parallel processing. - * @serial: List to wait for serialization after reordering. - * @pwork: work struct for parallelization. - * @swork: work struct for serialization. - * @pd: Backpointer to the internal control structure. * @work: work struct for parallelization. - * @reorder_work: work struct for reordering. * @num_obj: Number of objects that are processed by this cpu. - * @cpu_index: Index of the cpu. */ struct padata_parallel_queue { struct padata_list parallel; struct padata_list reorder; - struct parallel_data *pd; struct work_struct work; - struct work_struct reorder_work; atomic_t num_obj; - int cpu_index; }; /** @@ -104,50 +95,67 @@ struct padata_cpumask { * struct parallel_data - Internal control structure, covers everything * that depends on the cpumask in use. * - * @pinst: padata instance. + * @ps: padata_shell object. * @pqueue: percpu padata queues used for parallelization. * @squeue: percpu padata queues used for serialuzation. - * @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. + * @seq_nr: Sequence number of the parallelized data object. + * @processed: Number of already processed objects. + * @cpu: Next CPU to be processed. * @cpumask: The cpumasks in use for parallel and serial workers. + * @reorder_work: work struct for reordering. * @lock: Reorder lock. - * @processed: Number of already processed objects. - * @timer: Reorder timer. */ struct parallel_data { - struct padata_instance *pinst; + struct padata_shell *ps; struct padata_parallel_queue __percpu *pqueue; struct padata_serial_queue __percpu *squeue; - atomic_t reorder_objects; atomic_t refcnt; atomic_t seq_nr; - struct padata_cpumask cpumask; - spinlock_t lock ____cacheline_aligned; unsigned int processed; - struct timer_list timer; + int cpu; + struct padata_cpumask cpumask; + struct work_struct reorder_work; + spinlock_t ____cacheline_aligned lock; +}; + +/** + * struct padata_shell - Wrapper around struct parallel_data, its + * purpose is to allow the underlying control structure to be replaced + * on the fly using RCU. + * + * @pinst: padat instance. + * @pd: Actual parallel_data structure which may be substituted on the fly. + * @opd: Pointer to old pd to be freed by padata_replace. + * @list: List entry in padata_instance list. + */ +struct padata_shell { + struct padata_instance *pinst; + struct parallel_data __rcu *pd; + struct parallel_data *opd; + struct list_head list; }; /** * struct padata_instance - The overall control structure. * - * @cpu_notifier: cpu hotplug notifier. - * @wq: The workqueue in use. - * @pd: The internal control structure. + * @node: Used by CPU hotplug. + * @parallel_wq: The workqueue used for parallel work. + * @serial_wq: The workqueue used for serial work. + * @pslist: List of padata_shell objects attached to this instance. * @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. + * @rcpumask: Actual cpumasks based on user cpumask and cpu_online_mask. * @kobj: padata instance kernel object. * @lock: padata instance lock. * @flags: padata flags. */ struct padata_instance { struct hlist_node node; - struct workqueue_struct *wq; - struct parallel_data *pd; + struct workqueue_struct *parallel_wq; + struct workqueue_struct *serial_wq; + struct list_head pslist; struct padata_cpumask cpumask; - struct blocking_notifier_head cpumask_change_notifier; + struct padata_cpumask rcpumask; struct kobject kobj; struct mutex lock; u8 flags; @@ -156,18 +164,15 @@ struct padata_instance { #define PADATA_INVALID 4 }; -extern struct padata_instance *padata_alloc_possible( - struct workqueue_struct *wq); +extern struct padata_instance *padata_alloc_possible(const char *name); 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 struct padata_shell *padata_alloc_shell(struct padata_instance *pinst); +extern void padata_free_shell(struct padata_shell *ps); +extern int padata_do_parallel(struct padata_shell *ps, + struct padata_priv *padata, int *cb_cpu); extern void padata_do_serial(struct padata_priv *padata); extern int padata_set_cpumask(struct padata_instance *pinst, int cpumask_type, cpumask_var_t cpumask); extern int padata_start(struct padata_instance *pinst); extern void padata_stop(struct padata_instance *pinst); -extern int padata_register_cpumask_notifier(struct padata_instance *pinst, - struct notifier_block *nblock); -extern int padata_unregister_cpumask_notifier(struct padata_instance *pinst, - struct notifier_block *nblock); #endif |

