diff options
Diffstat (limited to 'include/linux/padata.h')
-rw-r--r-- | include/linux/padata.h | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/include/linux/padata.h b/include/linux/padata.h new file mode 100644 index 000000000..495b16b6b --- /dev/null +++ b/include/linux/padata.h @@ -0,0 +1,195 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * padata.h - header for the padata parallelization interface + * + * Copyright (C) 2008, 2009 secunet Security Networks AG + * Copyright (C) 2008, 2009 Steffen Klassert <steffen.klassert@secunet.com> + * + * Copyright (c) 2020 Oracle and/or its affiliates. + * Author: Daniel Jordan <daniel.m.jordan@oracle.com> + */ + +#ifndef PADATA_H +#define PADATA_H + +#include <linux/refcount.h> +#include <linux/compiler_types.h> +#include <linux/workqueue.h> +#include <linux/spinlock.h> +#include <linux/list.h> +#include <linux/kobject.h> + +#define PADATA_CPU_SERIAL 0x01 +#define PADATA_CPU_PARALLEL 0x02 + +/** + * struct padata_priv - Represents one job + * + * @list: List entry, to attach to the padata lists. + * @pd: Pointer to the internal control structure. + * @cb_cpu: Callback cpu for serializatioon. + * @seq_nr: Sequence number of the parallelized data object. + * @info: Used to pass information from the parallel to the serial function. + * @parallel: Parallel execution function. + * @serial: Serial complete function. + */ +struct padata_priv { + struct list_head list; + struct parallel_data *pd; + int cb_cpu; + unsigned int seq_nr; + int info; + void (*parallel)(struct padata_priv *padata); + void (*serial)(struct padata_priv *padata); +}; + +/** + * struct padata_list - one per work type per CPU + * + * @list: List head. + * @lock: List lock. + */ +struct padata_list { + struct list_head list; + spinlock_t lock; +}; + +/** +* struct padata_serial_queue - The percpu padata serial queue +* +* @serial: List to wait for serialization after reordering. +* @work: work struct for serialization. +* @pd: Backpointer to the internal control structure. +*/ +struct padata_serial_queue { + struct padata_list serial; + struct work_struct work; + struct parallel_data *pd; +}; + +/** + * 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 + * that depends on the cpumask in use. + * + * @ps: padata_shell object. + * @reorder_list: percpu reorder lists + * @squeue: percpu padata queues used for serialuzation. + * @refcnt: Number of objects holding a reference on this parallel_data. + * @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. + */ +struct parallel_data { + struct padata_shell *ps; + struct padata_list __percpu *reorder_list; + struct padata_serial_queue __percpu *squeue; + refcount_t refcnt; + unsigned int seq_nr; + unsigned int processed; + 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_mt_job - represents one multithreaded job + * + * @thread_fn: Called for each chunk of work that a padata thread does. + * @fn_arg: The thread function argument. + * @start: The start of the job (units are job-specific). + * @size: size of this node's work (units are job-specific). + * @align: Ranges passed to the thread function fall on this boundary, with the + * possible exceptions of the beginning and end of the job. + * @min_chunk: The minimum chunk size in job-specific units. This allows + * the client to communicate the minimum amount of work that's + * appropriate for one worker thread to do at once. + * @max_threads: Max threads to use for the job, actual number may be less + * depending on task size and minimum chunk size. + */ +struct padata_mt_job { + void (*thread_fn)(unsigned long start, unsigned long end, void *arg); + void *fn_arg; + unsigned long start; + unsigned long size; + unsigned long align; + unsigned long min_chunk; + int max_threads; +}; + +/** + * struct padata_instance - The overall control structure. + * + * @cpu_online_node: Linkage for CPU online callback. + * @cpu_dead_node: Linkage for CPU offline callback. + * @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. + * @kobj: padata instance kernel object. + * @lock: padata instance lock. + * @flags: padata flags. + */ +struct padata_instance { + struct hlist_node cpu_online_node; + struct hlist_node cpu_dead_node; + struct workqueue_struct *parallel_wq; + struct workqueue_struct *serial_wq; + struct list_head pslist; + struct padata_cpumask cpumask; + struct kobject kobj; + struct mutex lock; + u8 flags; +#define PADATA_INIT 1 +#define PADATA_RESET 2 +#define PADATA_INVALID 4 +}; + +#ifdef CONFIG_PADATA +extern void __init padata_init(void); +#else +static inline void __init padata_init(void) {} +#endif + +extern struct padata_instance *padata_alloc(const char *name); +extern void padata_free(struct padata_instance *pinst); +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 void __init padata_do_multithreaded(struct padata_mt_job *job); +extern int padata_set_cpumask(struct padata_instance *pinst, int cpumask_type, + cpumask_var_t cpumask); +#endif |