Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq: (55 commits) workqueue: mark init_workqueues() as early_initcall() workqueue: explain for_each_*cwq_cpu() iterators fscache: fix build on !CONFIG_SYSCTL slow-work: kill it gfs2: use workqueue instead of slow-work drm: use workqueue instead of slow-work cifs: use workqueue instead of slow-work fscache: drop references to slow-work fscache: convert operation to use workqueue instead of slow-work fscache: convert object to use workqueue instead of slow-work workqueue: fix how cpu number is stored in work->data workqueue: fix mayday_mask handling on UP workqueue: fix build problem on !CONFIG_SMP workqueue: fix locking in retry path of maybe_create_worker() async: use workqueue for worker pool workqueue: remove WQ_SINGLE_CPU and use WQ_UNBOUND instead workqueue: implement unbound workqueue workqueue: prepare for WQ_UNBOUND implementation libata: take advantage of cmwq and remove concurrency limitations workqueue: fix worker management invocation without pending works ... Fixed up conflicts in fs/cifs/* as per Tejun. Other trivial conflicts in include/linux/workqueue.h, kernel/trace/Kconfig and kernel/workqueue.c
This commit is contained in:
@ -9,6 +9,7 @@
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/threads.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
struct workqueue_struct;
|
||||
@ -22,12 +23,59 @@ typedef void (*work_func_t)(struct work_struct *work);
|
||||
*/
|
||||
#define work_data_bits(work) ((unsigned long *)(&(work)->data))
|
||||
|
||||
enum {
|
||||
WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */
|
||||
WORK_STRUCT_CWQ_BIT = 1, /* data points to cwq */
|
||||
WORK_STRUCT_LINKED_BIT = 2, /* next work is linked to this one */
|
||||
#ifdef CONFIG_DEBUG_OBJECTS_WORK
|
||||
WORK_STRUCT_STATIC_BIT = 3, /* static initializer (debugobjects) */
|
||||
WORK_STRUCT_COLOR_SHIFT = 4, /* color for workqueue flushing */
|
||||
#else
|
||||
WORK_STRUCT_COLOR_SHIFT = 3, /* color for workqueue flushing */
|
||||
#endif
|
||||
|
||||
WORK_STRUCT_COLOR_BITS = 4,
|
||||
|
||||
WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT,
|
||||
WORK_STRUCT_CWQ = 1 << WORK_STRUCT_CWQ_BIT,
|
||||
WORK_STRUCT_LINKED = 1 << WORK_STRUCT_LINKED_BIT,
|
||||
#ifdef CONFIG_DEBUG_OBJECTS_WORK
|
||||
WORK_STRUCT_STATIC = 1 << WORK_STRUCT_STATIC_BIT,
|
||||
#else
|
||||
WORK_STRUCT_STATIC = 0,
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The last color is no color used for works which don't
|
||||
* participate in workqueue flushing.
|
||||
*/
|
||||
WORK_NR_COLORS = (1 << WORK_STRUCT_COLOR_BITS) - 1,
|
||||
WORK_NO_COLOR = WORK_NR_COLORS,
|
||||
|
||||
/* special cpu IDs */
|
||||
WORK_CPU_UNBOUND = NR_CPUS,
|
||||
WORK_CPU_NONE = NR_CPUS + 1,
|
||||
WORK_CPU_LAST = WORK_CPU_NONE,
|
||||
|
||||
/*
|
||||
* Reserve 7 bits off of cwq pointer w/ debugobjects turned
|
||||
* off. This makes cwqs aligned to 128 bytes which isn't too
|
||||
* excessive while allowing 15 workqueue flush colors.
|
||||
*/
|
||||
WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT +
|
||||
WORK_STRUCT_COLOR_BITS,
|
||||
|
||||
WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1,
|
||||
WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK,
|
||||
WORK_STRUCT_NO_CPU = WORK_CPU_NONE << WORK_STRUCT_FLAG_BITS,
|
||||
|
||||
/* bit mask for work_busy() return values */
|
||||
WORK_BUSY_PENDING = 1 << 0,
|
||||
WORK_BUSY_RUNNING = 1 << 1,
|
||||
};
|
||||
|
||||
struct work_struct {
|
||||
atomic_long_t data;
|
||||
#define WORK_STRUCT_PENDING 0 /* T if work item pending execution */
|
||||
#define WORK_STRUCT_STATIC 1 /* static initializer (debugobjects) */
|
||||
#define WORK_STRUCT_FLAG_MASK (3UL)
|
||||
#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
|
||||
struct list_head entry;
|
||||
work_func_t func;
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
@ -35,8 +83,9 @@ struct work_struct {
|
||||
#endif
|
||||
};
|
||||
|
||||
#define WORK_DATA_INIT() ATOMIC_LONG_INIT(0)
|
||||
#define WORK_DATA_STATIC_INIT() ATOMIC_LONG_INIT(2)
|
||||
#define WORK_DATA_INIT() ATOMIC_LONG_INIT(WORK_STRUCT_NO_CPU)
|
||||
#define WORK_DATA_STATIC_INIT() \
|
||||
ATOMIC_LONG_INIT(WORK_STRUCT_NO_CPU | WORK_STRUCT_STATIC)
|
||||
|
||||
struct delayed_work {
|
||||
struct work_struct work;
|
||||
@ -96,9 +145,14 @@ struct execute_work {
|
||||
#ifdef CONFIG_DEBUG_OBJECTS_WORK
|
||||
extern void __init_work(struct work_struct *work, int onstack);
|
||||
extern void destroy_work_on_stack(struct work_struct *work);
|
||||
static inline unsigned int work_static(struct work_struct *work)
|
||||
{
|
||||
return *work_data_bits(work) & WORK_STRUCT_STATIC;
|
||||
}
|
||||
#else
|
||||
static inline void __init_work(struct work_struct *work, int onstack) { }
|
||||
static inline void destroy_work_on_stack(struct work_struct *work) { }
|
||||
static inline unsigned int work_static(struct work_struct *work) { return 0; }
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -162,7 +216,7 @@ static inline void destroy_work_on_stack(struct work_struct *work) { }
|
||||
* @work: The work item in question
|
||||
*/
|
||||
#define work_pending(work) \
|
||||
test_bit(WORK_STRUCT_PENDING, work_data_bits(work))
|
||||
test_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))
|
||||
|
||||
/**
|
||||
* delayed_work_pending - Find out whether a delayable work item is currently
|
||||
@ -177,16 +231,56 @@ static inline void destroy_work_on_stack(struct work_struct *work) { }
|
||||
* @work: The work item in question
|
||||
*/
|
||||
#define work_clear_pending(work) \
|
||||
clear_bit(WORK_STRUCT_PENDING, work_data_bits(work))
|
||||
clear_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))
|
||||
|
||||
enum {
|
||||
WQ_NON_REENTRANT = 1 << 0, /* guarantee non-reentrance */
|
||||
WQ_UNBOUND = 1 << 1, /* not bound to any cpu */
|
||||
WQ_FREEZEABLE = 1 << 2, /* freeze during suspend */
|
||||
WQ_RESCUER = 1 << 3, /* has an rescue worker */
|
||||
WQ_HIGHPRI = 1 << 4, /* high priority */
|
||||
WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */
|
||||
|
||||
WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */
|
||||
WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */
|
||||
WQ_DFL_ACTIVE = WQ_MAX_ACTIVE / 2,
|
||||
};
|
||||
|
||||
/* unbound wq's aren't per-cpu, scale max_active according to #cpus */
|
||||
#define WQ_UNBOUND_MAX_ACTIVE \
|
||||
max_t(int, WQ_MAX_ACTIVE, num_possible_cpus() * WQ_MAX_UNBOUND_PER_CPU)
|
||||
|
||||
/*
|
||||
* System-wide workqueues which are always present.
|
||||
*
|
||||
* system_wq is the one used by schedule[_delayed]_work[_on]().
|
||||
* Multi-CPU multi-threaded. There are users which expect relatively
|
||||
* short queue flush time. Don't queue works which can run for too
|
||||
* long.
|
||||
*
|
||||
* system_long_wq is similar to system_wq but may host long running
|
||||
* works. Queue flushing might take relatively long.
|
||||
*
|
||||
* system_nrt_wq is non-reentrant and guarantees that any given work
|
||||
* item is never executed in parallel by multiple CPUs. Queue
|
||||
* flushing might take relatively long.
|
||||
*
|
||||
* system_unbound_wq is unbound workqueue. Workers are not bound to
|
||||
* any specific CPU, not concurrency managed, and all queued works are
|
||||
* executed immediately as long as max_active limit is not reached and
|
||||
* resources are available.
|
||||
*/
|
||||
extern struct workqueue_struct *system_wq;
|
||||
extern struct workqueue_struct *system_long_wq;
|
||||
extern struct workqueue_struct *system_nrt_wq;
|
||||
extern struct workqueue_struct *system_unbound_wq;
|
||||
|
||||
extern struct workqueue_struct *
|
||||
__create_workqueue_key(const char *name, int singlethread,
|
||||
int freezeable, int rt, struct lock_class_key *key,
|
||||
const char *lock_name);
|
||||
__alloc_workqueue_key(const char *name, unsigned int flags, int max_active,
|
||||
struct lock_class_key *key, const char *lock_name);
|
||||
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
#define __create_workqueue(name, singlethread, freezeable, rt) \
|
||||
#define alloc_workqueue(name, flags, max_active) \
|
||||
({ \
|
||||
static struct lock_class_key __key; \
|
||||
const char *__lock_name; \
|
||||
@ -196,20 +290,20 @@ __create_workqueue_key(const char *name, int singlethread,
|
||||
else \
|
||||
__lock_name = #name; \
|
||||
\
|
||||
__create_workqueue_key((name), (singlethread), \
|
||||
(freezeable), (rt), &__key, \
|
||||
__lock_name); \
|
||||
__alloc_workqueue_key((name), (flags), (max_active), \
|
||||
&__key, __lock_name); \
|
||||
})
|
||||
#else
|
||||
#define __create_workqueue(name, singlethread, freezeable, rt) \
|
||||
__create_workqueue_key((name), (singlethread), (freezeable), (rt), \
|
||||
NULL, NULL)
|
||||
#define alloc_workqueue(name, flags, max_active) \
|
||||
__alloc_workqueue_key((name), (flags), (max_active), NULL, NULL)
|
||||
#endif
|
||||
|
||||
#define create_workqueue(name) __create_workqueue((name), 0, 0, 0)
|
||||
#define create_rt_workqueue(name) __create_workqueue((name), 0, 0, 1)
|
||||
#define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1, 0)
|
||||
#define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0, 0)
|
||||
#define create_workqueue(name) \
|
||||
alloc_workqueue((name), WQ_RESCUER, 1)
|
||||
#define create_freezeable_workqueue(name) \
|
||||
alloc_workqueue((name), WQ_FREEZEABLE | WQ_UNBOUND | WQ_RESCUER, 1)
|
||||
#define create_singlethread_workqueue(name) \
|
||||
alloc_workqueue((name), WQ_UNBOUND | WQ_RESCUER, 1)
|
||||
|
||||
extern void destroy_workqueue(struct workqueue_struct *wq);
|
||||
|
||||
@ -231,16 +325,19 @@ extern int schedule_delayed_work(struct delayed_work *work, unsigned long delay)
|
||||
extern int schedule_delayed_work_on(int cpu, struct delayed_work *work,
|
||||
unsigned long delay);
|
||||
extern int schedule_on_each_cpu(work_func_t func);
|
||||
extern int current_is_keventd(void);
|
||||
extern int keventd_up(void);
|
||||
|
||||
extern void init_workqueues(void);
|
||||
int execute_in_process_context(work_func_t fn, struct execute_work *);
|
||||
|
||||
extern int flush_work(struct work_struct *work);
|
||||
|
||||
extern int cancel_work_sync(struct work_struct *work);
|
||||
|
||||
extern void workqueue_set_max_active(struct workqueue_struct *wq,
|
||||
int max_active);
|
||||
extern bool workqueue_congested(unsigned int cpu, struct workqueue_struct *wq);
|
||||
extern unsigned int work_cpu(struct work_struct *work);
|
||||
extern unsigned int work_busy(struct work_struct *work);
|
||||
|
||||
/*
|
||||
* Kill off a pending schedule_delayed_work(). Note that the work callback
|
||||
* function may still be running on return from cancel_delayed_work(), unless
|
||||
@ -298,7 +395,14 @@ static inline long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg)
|
||||
long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg);
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#ifdef CONFIG_FREEZER
|
||||
extern void freeze_workqueues_begin(void);
|
||||
extern bool freeze_workqueues_busy(void);
|
||||
extern void thaw_workqueues(void);
|
||||
#endif /* CONFIG_FREEZER */
|
||||
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
int in_workqueue_context(struct workqueue_struct *wq);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user