diff options
author | Dan Kruchinin <dkruchinin@acm.org> | 2010-07-14 06:31:57 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2010-07-19 01:50:19 -0400 |
commit | e15bacbebb9dcc95f148f28dfc83a6d5e48b60b8 (patch) | |
tree | bf1ccd1a70247c91662077f31cb22e48103ce2b8 /include/linux/padata.h | |
parent | 2197f9a16df9de94655992941d80953ba47042c2 (diff) |
padata: Make two separate cpumasks
The aim of this patch is to make two separate cpumasks
for padata parallel and serial workers respectively.
It allows user to make more thin and sophisticated configurations
of padata framework. For example user may bind parallel and serial workers to non-intersecting
CPU groups to gain better performance. Also each padata instance has notifiers chain for its
cpumasks now. If either parallel or serial or both masks were changed all
interested subsystems will get notification about that. It's especially useful
if padata user uses algorithm for callback CPU selection according to serial cpumask.
Signed-off-by: Dan Kruchinin <dkruchinin@acm.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'include/linux/padata.h')
-rw-r--r-- | include/linux/padata.h | 116 |
1 files changed, 80 insertions, 36 deletions
diff --git a/include/linux/padata.h b/include/linux/padata.h index 8844b851191e..621e7736690c 100644 --- a/include/linux/padata.h +++ b/include/linux/padata.h | |||
@@ -25,6 +25,10 @@ | |||
25 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
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> | ||
29 | |||
30 | #define PADATA_CPU_SERIAL 0x01 | ||
31 | #define PADATA_CPU_PARALLEL 0x02 | ||
28 | 32 | ||
29 | /** | 33 | /** |
30 | * struct padata_priv - Embedded to the users data structure. | 34 | * struct padata_priv - Embedded to the users data structure. |
@@ -59,7 +63,20 @@ struct padata_list { | |||
59 | }; | 63 | }; |
60 | 64 | ||
61 | /** | 65 | /** |
62 | * struct padata_queue - The percpu padata queues. | 66 | * struct padata_serial_queue - The percpu padata serial queue |
67 | * | ||
68 | * @serial: List to wait for serialization after reordering. | ||
69 | * @work: work struct for serialization. | ||
70 | * @pd: Backpointer to the internal control structure. | ||
71 | */ | ||
72 | struct padata_serial_queue { | ||
73 | struct padata_list serial; | ||
74 | struct work_struct work; | ||
75 | struct parallel_data *pd; | ||
76 | }; | ||
77 | |||
78 | /** | ||
79 | * struct padata_parallel_queue - The percpu padata parallel queue | ||
63 | * | 80 | * |
64 | * @parallel: List to wait for parallelization. | 81 | * @parallel: List to wait for parallelization. |
65 | * @reorder: List to wait for reordering after parallel processing. | 82 | * @reorder: List to wait for reordering after parallel processing. |
@@ -67,44 +84,52 @@ struct padata_list { | |||
67 | * @pwork: work struct for parallelization. | 84 | * @pwork: work struct for parallelization. |
68 | * @swork: work struct for serialization. | 85 | * @swork: work struct for serialization. |
69 | * @pd: Backpointer to the internal control structure. | 86 | * @pd: Backpointer to the internal control structure. |
87 | * @work: work struct for parallelization. | ||
88 | * @num_obj: Number of objects that are processed by this cpu. | ||
70 | * @cpu_index: Index of the cpu. | 89 | * @cpu_index: Index of the cpu. |
71 | */ | 90 | */ |
72 | struct padata_queue { | 91 | struct padata_parallel_queue { |
73 | struct padata_list parallel; | 92 | struct padata_list parallel; |
74 | struct padata_list reorder; | 93 | struct padata_list reorder; |
75 | struct padata_list serial; | 94 | struct parallel_data *pd; |
76 | struct work_struct pwork; | 95 | struct work_struct work; |
77 | struct work_struct swork; | 96 | atomic_t num_obj; |
78 | struct parallel_data *pd; | 97 | int cpu_index; |
79 | int cpu_index; | ||
80 | }; | 98 | }; |
81 | 99 | ||
100 | |||
82 | /** | 101 | /** |
83 | * struct parallel_data - Internal control structure, covers everything | 102 | * struct parallel_data - Internal control structure, covers everything |
84 | * that depends on the cpumask in use. | 103 | * that depends on the cpumask in use. |
85 | * | 104 | * |
86 | * @pinst: padata instance. | 105 | * @pinst: padata instance. |
87 | * @queue: percpu padata queues. | 106 | * @pqueue: percpu padata queues used for parallelization. |
107 | * @squeue: percpu padata queues used for serialuzation. | ||
88 | * @seq_nr: The sequence number that will be attached to the next object. | 108 | * @seq_nr: The sequence number that will be attached to the next object. |
89 | * @reorder_objects: Number of objects waiting in the reorder queues. | 109 | * @reorder_objects: Number of objects waiting in the reorder queues. |
90 | * @refcnt: Number of objects holding a reference on this parallel_data. | 110 | * @refcnt: Number of objects holding a reference on this parallel_data. |
91 | * @max_seq_nr: Maximal used sequence number. | 111 | * @max_seq_nr: Maximal used sequence number. |
92 | * @cpumask: cpumask in use. | 112 | * @cpumask: Contains two cpumasks: pcpu and cbcpu for |
113 | * parallel and serial workers respectively. | ||
93 | * @lock: Reorder lock. | 114 | * @lock: Reorder lock. |
94 | * @processed: Number of already processed objects. | 115 | * @processed: Number of already processed objects. |
95 | * @timer: Reorder timer. | 116 | * @timer: Reorder timer. |
96 | */ | 117 | */ |
97 | struct parallel_data { | 118 | struct parallel_data { |
98 | struct padata_instance *pinst; | 119 | struct padata_instance *pinst; |
99 | struct padata_queue *queue; | 120 | struct padata_parallel_queue *pqueue; |
100 | atomic_t seq_nr; | 121 | struct padata_serial_queue *squeue; |
101 | atomic_t reorder_objects; | 122 | atomic_t seq_nr; |
102 | atomic_t refcnt; | 123 | atomic_t reorder_objects; |
103 | unsigned int max_seq_nr; | 124 | atomic_t refcnt; |
104 | cpumask_var_t cpumask; | 125 | unsigned int max_seq_nr; |
105 | spinlock_t lock ____cacheline_aligned; | 126 | struct { |
106 | unsigned int processed; | 127 | cpumask_var_t pcpu; |
107 | struct timer_list timer; | 128 | cpumask_var_t cbcpu; |
129 | } cpumask; | ||
130 | spinlock_t lock ____cacheline_aligned; | ||
131 | unsigned int processed; | ||
132 | struct timer_list timer; | ||
108 | }; | 133 | }; |
109 | 134 | ||
110 | /** | 135 | /** |
@@ -113,32 +138,51 @@ struct parallel_data { | |||
113 | * @cpu_notifier: cpu hotplug notifier. | 138 | * @cpu_notifier: cpu hotplug notifier. |
114 | * @wq: The workqueue in use. | 139 | * @wq: The workqueue in use. |
115 | * @pd: The internal control structure. | 140 | * @pd: The internal control structure. |
116 | * @cpumask: User supplied cpumask. | 141 | * @cpumask: User supplied cpumask. Contains two cpumasks: pcpu and |
142 | * cbcpu for parallel and serial works respectivly. | ||
143 | * @cpumask_change_notifier: Notifiers chain for user-defined notify | ||
144 | * callbacks that will be called when either @pcpu or @cbcpu | ||
145 | * or both cpumasks change. | ||
117 | * @lock: padata instance lock. | 146 | * @lock: padata instance lock. |
118 | * @flags: padata flags. | 147 | * @flags: padata flags. |
119 | */ | 148 | */ |
120 | struct padata_instance { | 149 | struct padata_instance { |
121 | struct notifier_block cpu_notifier; | 150 | struct notifier_block cpu_notifier; |
122 | struct workqueue_struct *wq; | 151 | struct workqueue_struct *wq; |
123 | struct parallel_data *pd; | 152 | struct parallel_data *pd; |
124 | cpumask_var_t cpumask; | 153 | struct { |
125 | struct mutex lock; | 154 | cpumask_var_t pcpu; |
126 | u8 flags; | 155 | cpumask_var_t cbcpu; |
127 | #define PADATA_INIT 1 | 156 | } cpumask; |
128 | #define PADATA_RESET 2 | 157 | struct blocking_notifier_head cpumask_change_notifier; |
129 | #define PADATA_INVALID 4 | 158 | struct mutex lock; |
159 | u8 flags; | ||
160 | #define PADATA_INIT 1 | ||
161 | #define PADATA_RESET 2 | ||
162 | #define PADATA_INVALID 4 | ||
130 | }; | 163 | }; |
131 | 164 | ||
132 | extern struct padata_instance *padata_alloc(const struct cpumask *cpumask, | 165 | extern struct padata_instance *padata_alloc(struct workqueue_struct *wq); |
133 | struct workqueue_struct *wq); | 166 | extern struct padata_instance *__padata_alloc(struct workqueue_struct *wq, |
167 | const struct cpumask *pcpumask, | ||
168 | const struct cpumask *cbcpumask); | ||
134 | extern void padata_free(struct padata_instance *pinst); | 169 | extern void padata_free(struct padata_instance *pinst); |
135 | extern int padata_do_parallel(struct padata_instance *pinst, | 170 | extern int padata_do_parallel(struct padata_instance *pinst, |
136 | struct padata_priv *padata, int cb_cpu); | 171 | struct padata_priv *padata, int cb_cpu); |
137 | extern void padata_do_serial(struct padata_priv *padata); | 172 | extern void padata_do_serial(struct padata_priv *padata); |
138 | extern int padata_set_cpumask(struct padata_instance *pinst, | 173 | extern int padata_get_cpumask(struct padata_instance *pinst, |
174 | int cpumask_type, struct cpumask *out_mask); | ||
175 | extern int padata_set_cpumask(struct padata_instance *pinst, int cpumask_type, | ||
139 | cpumask_var_t cpumask); | 176 | cpumask_var_t cpumask); |
140 | extern int padata_add_cpu(struct padata_instance *pinst, int cpu); | 177 | extern int __padata_set_cpumasks(struct padata_instance *pinst, |
141 | extern int padata_remove_cpu(struct padata_instance *pinst, int cpu); | 178 | cpumask_var_t pcpumask, |
179 | cpumask_var_t cbcpumask); | ||
180 | extern int padata_add_cpu(struct padata_instance *pinst, int cpu, int mask); | ||
181 | extern int padata_remove_cpu(struct padata_instance *pinst, int cpu, int mask); | ||
142 | extern int padata_start(struct padata_instance *pinst); | 182 | extern int padata_start(struct padata_instance *pinst); |
143 | extern void padata_stop(struct padata_instance *pinst); | 183 | extern void padata_stop(struct padata_instance *pinst); |
184 | extern int padata_register_cpumask_notifier(struct padata_instance *pinst, | ||
185 | struct notifier_block *nblock); | ||
186 | extern int padata_unregister_cpumask_notifier(struct padata_instance *pinst, | ||
187 | struct notifier_block *nblock); | ||
144 | #endif | 188 | #endif |