mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 10:50:53 +07:00
workqueue: introduce WORK_OFFQ_FLAG_*
Low WORK_STRUCT_FLAG_BITS bits of work_struct->data contain WORK_STRUCT_FLAG_* and flush color. If the work item is queued, the rest point to the cpu_workqueue with WORK_STRUCT_CWQ set; otherwise, WORK_STRUCT_CWQ is clear and the bits contain the last CPU number - either a real CPU number or one of WORK_CPU_*. Scheduled addition of mod_delayed_work[_on]() requires an additional flag, which is used only while a work item is off queue. There are more than enough bits to represent off-queue CPU number on both 32 and 64bits. This patch introduces WORK_OFFQ_FLAG_* which occupy the lower part of the @work->data high bits while off queue. This patch doesn't define any actual OFFQ flag yet. Off-queue CPU number is now shifted by WORK_OFFQ_CPU_SHIFT, which adds the number of bits used by OFFQ flags to WORK_STRUCT_FLAG_SHIFT, to make room for OFFQ flags. To avoid shift width warning with large WORK_OFFQ_FLAG_BITS, ulong cast is added to WORK_STRUCT_NO_CPU and, just in case, BUILD_BUG_ON() to check that there are enough bits to accomodate off-queue CPU number is added. This patch doesn't make any functional difference. Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
parent
bf4ede014e
commit
b549007727
@ -68,9 +68,15 @@ enum {
|
|||||||
WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT +
|
WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT +
|
||||||
WORK_STRUCT_COLOR_BITS,
|
WORK_STRUCT_COLOR_BITS,
|
||||||
|
|
||||||
|
/* data contains off-queue information when !WORK_STRUCT_CWQ */
|
||||||
|
WORK_OFFQ_FLAG_BASE = WORK_STRUCT_FLAG_BITS,
|
||||||
|
WORK_OFFQ_FLAG_BITS = 0,
|
||||||
|
WORK_OFFQ_CPU_SHIFT = WORK_OFFQ_FLAG_BASE + WORK_OFFQ_FLAG_BITS,
|
||||||
|
|
||||||
|
/* convenience constants */
|
||||||
WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1,
|
WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1,
|
||||||
WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK,
|
WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK,
|
||||||
WORK_STRUCT_NO_CPU = WORK_CPU_NONE << WORK_STRUCT_FLAG_BITS,
|
WORK_STRUCT_NO_CPU = (unsigned long)WORK_CPU_NONE << WORK_OFFQ_CPU_SHIFT,
|
||||||
|
|
||||||
/* bit mask for work_busy() return values */
|
/* bit mask for work_busy() return values */
|
||||||
WORK_BUSY_PENDING = 1 << 0,
|
WORK_BUSY_PENDING = 1 << 0,
|
||||||
|
@ -533,9 +533,9 @@ static int work_next_color(int color)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A work's data points to the cwq with WORK_STRUCT_CWQ set while the
|
* While queued, %WORK_STRUCT_CWQ is set and non flag bits of a work's data
|
||||||
* work is on queue. Once execution starts, WORK_STRUCT_CWQ is
|
* contain the pointer to the queued cwq. Once execution starts, the flag
|
||||||
* cleared and the work data contains the cpu number it was last on.
|
* is cleared and the high bits contain OFFQ flags and CPU number.
|
||||||
*
|
*
|
||||||
* set_work_cwq(), set_work_cpu_and_clear_pending() and clear_work_data()
|
* set_work_cwq(), set_work_cpu_and_clear_pending() and clear_work_data()
|
||||||
* can be used to set the cwq, cpu or clear work->data. These functions
|
* can be used to set the cwq, cpu or clear work->data. These functions
|
||||||
@ -565,7 +565,7 @@ static void set_work_cwq(struct work_struct *work,
|
|||||||
static void set_work_cpu_and_clear_pending(struct work_struct *work,
|
static void set_work_cpu_and_clear_pending(struct work_struct *work,
|
||||||
unsigned int cpu)
|
unsigned int cpu)
|
||||||
{
|
{
|
||||||
set_work_data(work, cpu << WORK_STRUCT_FLAG_BITS, 0);
|
set_work_data(work, (unsigned long)cpu << WORK_OFFQ_CPU_SHIFT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_work_data(struct work_struct *work)
|
static void clear_work_data(struct work_struct *work)
|
||||||
@ -592,7 +592,7 @@ static struct global_cwq *get_work_gcwq(struct work_struct *work)
|
|||||||
return ((struct cpu_workqueue_struct *)
|
return ((struct cpu_workqueue_struct *)
|
||||||
(data & WORK_STRUCT_WQ_DATA_MASK))->pool->gcwq;
|
(data & WORK_STRUCT_WQ_DATA_MASK))->pool->gcwq;
|
||||||
|
|
||||||
cpu = data >> WORK_STRUCT_FLAG_BITS;
|
cpu = data >> WORK_OFFQ_CPU_SHIFT;
|
||||||
if (cpu == WORK_CPU_NONE)
|
if (cpu == WORK_CPU_NONE)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -3724,6 +3724,10 @@ static int __init init_workqueues(void)
|
|||||||
unsigned int cpu;
|
unsigned int cpu;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* make sure we have enough bits for OFFQ CPU number */
|
||||||
|
BUILD_BUG_ON((1LU << (BITS_PER_LONG - WORK_OFFQ_CPU_SHIFT)) <
|
||||||
|
WORK_CPU_LAST);
|
||||||
|
|
||||||
cpu_notifier(workqueue_cpu_up_callback, CPU_PRI_WORKQUEUE_UP);
|
cpu_notifier(workqueue_cpu_up_callback, CPU_PRI_WORKQUEUE_UP);
|
||||||
cpu_notifier(workqueue_cpu_down_callback, CPU_PRI_WORKQUEUE_DOWN);
|
cpu_notifier(workqueue_cpu_down_callback, CPU_PRI_WORKQUEUE_DOWN);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user