.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
---|
1 | 2 | /* |
---|
2 | 3 | * padata.h - header for the padata parallelization interface |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2008, 2009 secunet Security Networks AG |
---|
5 | 6 | * Copyright (C) 2008, 2009 Steffen Klassert <steffen.klassert@secunet.com> |
---|
6 | 7 | * |
---|
7 | | - * This program is free software; you can redistribute it and/or modify it |
---|
8 | | - * under the terms and conditions of the GNU General Public License, |
---|
9 | | - * version 2, as published by the Free Software Foundation. |
---|
10 | | - * |
---|
11 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
12 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
13 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
14 | | - * more details. |
---|
15 | | - * |
---|
16 | | - * You should have received a copy of the GNU General Public License along with |
---|
17 | | - * this program; if not, write to the Free Software Foundation, Inc., |
---|
18 | | - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
---|
| 8 | + * Copyright (c) 2020 Oracle and/or its affiliates. |
---|
| 9 | + * Author: Daniel Jordan <daniel.m.jordan@oracle.com> |
---|
19 | 10 | */ |
---|
20 | 11 | |
---|
21 | 12 | #ifndef PADATA_H |
---|
22 | 13 | #define PADATA_H |
---|
23 | 14 | |
---|
| 15 | +#include <linux/compiler_types.h> |
---|
24 | 16 | #include <linux/workqueue.h> |
---|
25 | 17 | #include <linux/spinlock.h> |
---|
26 | 18 | #include <linux/list.h> |
---|
27 | | -#include <linux/notifier.h> |
---|
28 | 19 | #include <linux/kobject.h> |
---|
29 | 20 | |
---|
30 | 21 | #define PADATA_CPU_SERIAL 0x01 |
---|
31 | 22 | #define PADATA_CPU_PARALLEL 0x02 |
---|
32 | 23 | |
---|
33 | 24 | /** |
---|
34 | | - * struct padata_priv - Embedded to the users data structure. |
---|
| 25 | + * struct padata_priv - Represents one job |
---|
35 | 26 | * |
---|
36 | 27 | * @list: List entry, to attach to the padata lists. |
---|
37 | 28 | * @pd: Pointer to the internal control structure. |
---|
38 | 29 | * @cb_cpu: Callback cpu for serializatioon. |
---|
39 | | - * @cpu: Cpu for parallelization. |
---|
40 | 30 | * @seq_nr: Sequence number of the parallelized data object. |
---|
41 | 31 | * @info: Used to pass information from the parallel to the serial function. |
---|
42 | 32 | * @parallel: Parallel execution function. |
---|
.. | .. |
---|
46 | 36 | struct list_head list; |
---|
47 | 37 | struct parallel_data *pd; |
---|
48 | 38 | int cb_cpu; |
---|
49 | | - int cpu; |
---|
| 39 | + unsigned int seq_nr; |
---|
50 | 40 | int info; |
---|
51 | 41 | void (*parallel)(struct padata_priv *padata); |
---|
52 | 42 | void (*serial)(struct padata_priv *padata); |
---|
53 | 43 | }; |
---|
54 | 44 | |
---|
55 | 45 | /** |
---|
56 | | - * struct padata_list |
---|
| 46 | + * struct padata_list - one per work type per CPU |
---|
57 | 47 | * |
---|
58 | 48 | * @list: List head. |
---|
59 | 49 | * @lock: List lock. |
---|
.. | .. |
---|
77 | 67 | }; |
---|
78 | 68 | |
---|
79 | 69 | /** |
---|
80 | | - * struct padata_parallel_queue - The percpu padata parallel queue |
---|
81 | | - * |
---|
82 | | - * @parallel: List to wait for parallelization. |
---|
83 | | - * @reorder: List to wait for reordering after parallel processing. |
---|
84 | | - * @serial: List to wait for serialization after reordering. |
---|
85 | | - * @pwork: work struct for parallelization. |
---|
86 | | - * @swork: work struct for serialization. |
---|
87 | | - * @work: work struct for parallelization. |
---|
88 | | - * @num_obj: Number of objects that are processed by this cpu. |
---|
89 | | - * @cpu_index: Index of the cpu. |
---|
90 | | - */ |
---|
91 | | -struct padata_parallel_queue { |
---|
92 | | - struct padata_list parallel; |
---|
93 | | - struct padata_list reorder; |
---|
94 | | - struct work_struct work; |
---|
95 | | - atomic_t num_obj; |
---|
96 | | - int cpu_index; |
---|
97 | | -}; |
---|
98 | | - |
---|
99 | | -/** |
---|
100 | 70 | * struct padata_cpumask - The cpumasks for the parallel/serial workers |
---|
101 | 71 | * |
---|
102 | 72 | * @pcpu: cpumask for the parallel workers. |
---|
.. | .. |
---|
111 | 81 | * struct parallel_data - Internal control structure, covers everything |
---|
112 | 82 | * that depends on the cpumask in use. |
---|
113 | 83 | * |
---|
114 | | - * @pinst: padata instance. |
---|
115 | | - * @pqueue: percpu padata queues used for parallelization. |
---|
| 84 | + * @ps: padata_shell object. |
---|
| 85 | + * @reorder_list: percpu reorder lists |
---|
116 | 86 | * @squeue: percpu padata queues used for serialuzation. |
---|
117 | | - * @reorder_objects: Number of objects waiting in the reorder queues. |
---|
118 | 87 | * @refcnt: Number of objects holding a reference on this parallel_data. |
---|
119 | | - * @max_seq_nr: Maximal used sequence number. |
---|
| 88 | + * @seq_nr: Sequence number of the parallelized data object. |
---|
| 89 | + * @processed: Number of already processed objects. |
---|
120 | 90 | * @cpu: Next CPU to be processed. |
---|
121 | 91 | * @cpumask: The cpumasks in use for parallel and serial workers. |
---|
122 | 92 | * @reorder_work: work struct for reordering. |
---|
123 | 93 | * @lock: Reorder lock. |
---|
124 | 94 | */ |
---|
125 | 95 | struct parallel_data { |
---|
126 | | - struct padata_instance *pinst; |
---|
127 | | - struct padata_parallel_queue __percpu *pqueue; |
---|
| 96 | + struct padata_shell *ps; |
---|
| 97 | + struct padata_list __percpu *reorder_list; |
---|
128 | 98 | struct padata_serial_queue __percpu *squeue; |
---|
129 | | - atomic_t reorder_objects; |
---|
130 | 99 | atomic_t refcnt; |
---|
131 | | - atomic_t seq_nr; |
---|
| 100 | + unsigned int seq_nr; |
---|
| 101 | + unsigned int processed; |
---|
132 | 102 | int cpu; |
---|
133 | 103 | struct padata_cpumask cpumask; |
---|
134 | 104 | struct work_struct reorder_work; |
---|
135 | | - spinlock_t lock ____cacheline_aligned; |
---|
| 105 | + spinlock_t ____cacheline_aligned lock; |
---|
| 106 | +}; |
---|
| 107 | + |
---|
| 108 | +/** |
---|
| 109 | + * struct padata_shell - Wrapper around struct parallel_data, its |
---|
| 110 | + * purpose is to allow the underlying control structure to be replaced |
---|
| 111 | + * on the fly using RCU. |
---|
| 112 | + * |
---|
| 113 | + * @pinst: padat instance. |
---|
| 114 | + * @pd: Actual parallel_data structure which may be substituted on the fly. |
---|
| 115 | + * @opd: Pointer to old pd to be freed by padata_replace. |
---|
| 116 | + * @list: List entry in padata_instance list. |
---|
| 117 | + */ |
---|
| 118 | +struct padata_shell { |
---|
| 119 | + struct padata_instance *pinst; |
---|
| 120 | + struct parallel_data __rcu *pd; |
---|
| 121 | + struct parallel_data *opd; |
---|
| 122 | + struct list_head list; |
---|
| 123 | +}; |
---|
| 124 | + |
---|
| 125 | +/** |
---|
| 126 | + * struct padata_mt_job - represents one multithreaded job |
---|
| 127 | + * |
---|
| 128 | + * @thread_fn: Called for each chunk of work that a padata thread does. |
---|
| 129 | + * @fn_arg: The thread function argument. |
---|
| 130 | + * @start: The start of the job (units are job-specific). |
---|
| 131 | + * @size: size of this node's work (units are job-specific). |
---|
| 132 | + * @align: Ranges passed to the thread function fall on this boundary, with the |
---|
| 133 | + * possible exceptions of the beginning and end of the job. |
---|
| 134 | + * @min_chunk: The minimum chunk size in job-specific units. This allows |
---|
| 135 | + * the client to communicate the minimum amount of work that's |
---|
| 136 | + * appropriate for one worker thread to do at once. |
---|
| 137 | + * @max_threads: Max threads to use for the job, actual number may be less |
---|
| 138 | + * depending on task size and minimum chunk size. |
---|
| 139 | + */ |
---|
| 140 | +struct padata_mt_job { |
---|
| 141 | + void (*thread_fn)(unsigned long start, unsigned long end, void *arg); |
---|
| 142 | + void *fn_arg; |
---|
| 143 | + unsigned long start; |
---|
| 144 | + unsigned long size; |
---|
| 145 | + unsigned long align; |
---|
| 146 | + unsigned long min_chunk; |
---|
| 147 | + int max_threads; |
---|
136 | 148 | }; |
---|
137 | 149 | |
---|
138 | 150 | /** |
---|
139 | 151 | * struct padata_instance - The overall control structure. |
---|
140 | 152 | * |
---|
141 | | - * @cpu_notifier: cpu hotplug notifier. |
---|
142 | | - * @wq: The workqueue in use. |
---|
143 | | - * @pd: The internal control structure. |
---|
| 153 | + * @cpu_online_node: Linkage for CPU online callback. |
---|
| 154 | + * @cpu_dead_node: Linkage for CPU offline callback. |
---|
| 155 | + * @parallel_wq: The workqueue used for parallel work. |
---|
| 156 | + * @serial_wq: The workqueue used for serial work. |
---|
| 157 | + * @pslist: List of padata_shell objects attached to this instance. |
---|
144 | 158 | * @cpumask: User supplied cpumasks for parallel and serial works. |
---|
145 | | - * @cpumask_change_notifier: Notifiers chain for user-defined notify |
---|
146 | | - * callbacks that will be called when either @pcpu or @cbcpu |
---|
147 | | - * or both cpumasks change. |
---|
148 | 159 | * @kobj: padata instance kernel object. |
---|
149 | 160 | * @lock: padata instance lock. |
---|
150 | 161 | * @flags: padata flags. |
---|
151 | 162 | */ |
---|
152 | 163 | struct padata_instance { |
---|
153 | | - struct hlist_node node; |
---|
154 | | - struct workqueue_struct *wq; |
---|
155 | | - struct parallel_data *pd; |
---|
| 164 | + struct hlist_node cpu_online_node; |
---|
| 165 | + struct hlist_node cpu_dead_node; |
---|
| 166 | + struct workqueue_struct *parallel_wq; |
---|
| 167 | + struct workqueue_struct *serial_wq; |
---|
| 168 | + struct list_head pslist; |
---|
156 | 169 | struct padata_cpumask cpumask; |
---|
157 | | - struct blocking_notifier_head cpumask_change_notifier; |
---|
158 | 170 | struct kobject kobj; |
---|
159 | 171 | struct mutex lock; |
---|
160 | 172 | u8 flags; |
---|
.. | .. |
---|
163 | 175 | #define PADATA_INVALID 4 |
---|
164 | 176 | }; |
---|
165 | 177 | |
---|
166 | | -extern struct padata_instance *padata_alloc_possible( |
---|
167 | | - struct workqueue_struct *wq); |
---|
| 178 | +#ifdef CONFIG_PADATA |
---|
| 179 | +extern void __init padata_init(void); |
---|
| 180 | +#else |
---|
| 181 | +static inline void __init padata_init(void) {} |
---|
| 182 | +#endif |
---|
| 183 | + |
---|
| 184 | +extern struct padata_instance *padata_alloc(const char *name); |
---|
168 | 185 | extern void padata_free(struct padata_instance *pinst); |
---|
169 | | -extern int padata_do_parallel(struct padata_instance *pinst, |
---|
170 | | - struct padata_priv *padata, int cb_cpu); |
---|
| 186 | +extern struct padata_shell *padata_alloc_shell(struct padata_instance *pinst); |
---|
| 187 | +extern void padata_free_shell(struct padata_shell *ps); |
---|
| 188 | +extern int padata_do_parallel(struct padata_shell *ps, |
---|
| 189 | + struct padata_priv *padata, int *cb_cpu); |
---|
171 | 190 | extern void padata_do_serial(struct padata_priv *padata); |
---|
| 191 | +extern void __init padata_do_multithreaded(struct padata_mt_job *job); |
---|
172 | 192 | extern int padata_set_cpumask(struct padata_instance *pinst, int cpumask_type, |
---|
173 | 193 | cpumask_var_t cpumask); |
---|
174 | | -extern int padata_start(struct padata_instance *pinst); |
---|
175 | | -extern void padata_stop(struct padata_instance *pinst); |
---|
176 | | -extern int padata_register_cpumask_notifier(struct padata_instance *pinst, |
---|
177 | | - struct notifier_block *nblock); |
---|
178 | | -extern int padata_unregister_cpumask_notifier(struct padata_instance *pinst, |
---|
179 | | - struct notifier_block *nblock); |
---|
180 | 194 | #endif |
---|