aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/workqueue.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-13 20:56:58 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-13 20:56:58 -0500
commit2bcc673101268dc50e52b83226c5bbf38391e16d (patch)
tree0cdaf6affa8b05d436c2e8b80ff23e8c7f03a30a /kernel/workqueue.c
parent670310dfbae0eefe7318ff6a61e29e67a7a7bbce (diff)
parentb24591e2fcf852ad7ad2ccf745c8220bf378d312 (diff)
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer updates from Thomas Gleixner: "Yet another big pile of changes: - More year 2038 work from Arnd slowly reaching the point where we need to think about the syscalls themself. - A new timer function which allows to conditionally (re)arm a timer only when it's either not running or the new expiry time is sooner than the armed expiry time. This allows to use a single timer for multiple timeout requirements w/o caring about the first expiry time at the call site. - A new NMI safe accessor to clock real time for the printk timestamp work. Can be used by tracing, perf as well if required. - A large number of timer setup conversions from Kees which got collected here because either maintainers requested so or they simply got ignored. As Kees pointed out already there are a few trivial merge conflicts and some redundant commits which was unavoidable due to the size of this conversion effort. - Avoid a redundant iteration in the timer wheel softirq processing. - Provide a mechanism to treat RTC implementations depending on their hardware properties, i.e. don't inflict the write at the 0.5 seconds boundary which originates from the PC CMOS RTC to all RTCs. No functional change as drivers need to be updated separately. - The usual small updates to core code clocksource drivers. Nothing really exciting" * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (111 commits) timers: Add a function to start/reduce a timer pstore: Use ktime_get_real_fast_ns() instead of __getnstimeofday() timer: Prepare to change all DEFINE_TIMER() callbacks netfilter: ipvs: Convert timers to use timer_setup() scsi: qla2xxx: Convert timers to use timer_setup() block/aoe: discover_timer: Convert timers to use timer_setup() ide: Convert timers to use timer_setup() drbd: Convert timers to use timer_setup() mailbox: Convert timers to use timer_setup() crypto: Convert timers to use timer_setup() drivers/pcmcia: omap1: Fix error in automated timer conversion ARM: footbridge: Fix typo in timer conversion drivers/sgi-xp: Convert timers to use timer_setup() drivers/pcmcia: Convert timers to use timer_setup() drivers/memstick: Convert timers to use timer_setup() drivers/macintosh: Convert timers to use timer_setup() hwrng/xgene-rng: Convert timers to use timer_setup() auxdisplay: Convert timers to use timer_setup() sparc/led: Convert timers to use timer_setup() mips: ip22/32: Convert timers to use timer_setup() ...
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r--kernel/workqueue.c29
1 files changed, 12 insertions, 17 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 13f67b5a0a0c..7368b57842ea 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1493,9 +1493,9 @@ bool queue_work_on(int cpu, struct workqueue_struct *wq,
1493} 1493}
1494EXPORT_SYMBOL(queue_work_on); 1494EXPORT_SYMBOL(queue_work_on);
1495 1495
1496void delayed_work_timer_fn(unsigned long __data) 1496void delayed_work_timer_fn(struct timer_list *t)
1497{ 1497{
1498 struct delayed_work *dwork = (struct delayed_work *)__data; 1498 struct delayed_work *dwork = from_timer(dwork, t, timer);
1499 1499
1500 /* should have been called from irqsafe timer with irq already off */ 1500 /* should have been called from irqsafe timer with irq already off */
1501 __queue_work(dwork->cpu, dwork->wq, &dwork->work); 1501 __queue_work(dwork->cpu, dwork->wq, &dwork->work);
@@ -1509,8 +1509,7 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq,
1509 struct work_struct *work = &dwork->work; 1509 struct work_struct *work = &dwork->work;
1510 1510
1511 WARN_ON_ONCE(!wq); 1511 WARN_ON_ONCE(!wq);
1512 WARN_ON_ONCE(timer->function != delayed_work_timer_fn || 1512 WARN_ON_ONCE(timer->function != (TIMER_FUNC_TYPE)delayed_work_timer_fn);
1513 timer->data != (unsigned long)dwork);
1514 WARN_ON_ONCE(timer_pending(timer)); 1513 WARN_ON_ONCE(timer_pending(timer));
1515 WARN_ON_ONCE(!list_empty(&work->entry)); 1514 WARN_ON_ONCE(!list_empty(&work->entry));
1516 1515
@@ -1833,9 +1832,9 @@ static void destroy_worker(struct worker *worker)
1833 wake_up_process(worker->task); 1832 wake_up_process(worker->task);
1834} 1833}
1835 1834
1836static void idle_worker_timeout(unsigned long __pool) 1835static void idle_worker_timeout(struct timer_list *t)
1837{ 1836{
1838 struct worker_pool *pool = (void *)__pool; 1837 struct worker_pool *pool = from_timer(pool, t, idle_timer);
1839 1838
1840 spin_lock_irq(&pool->lock); 1839 spin_lock_irq(&pool->lock);
1841 1840
@@ -1881,9 +1880,9 @@ static void send_mayday(struct work_struct *work)
1881 } 1880 }
1882} 1881}
1883 1882
1884static void pool_mayday_timeout(unsigned long __pool) 1883static void pool_mayday_timeout(struct timer_list *t)
1885{ 1884{
1886 struct worker_pool *pool = (void *)__pool; 1885 struct worker_pool *pool = from_timer(pool, t, mayday_timer);
1887 struct work_struct *work; 1886 struct work_struct *work;
1888 1887
1889 spin_lock_irq(&pool->lock); 1888 spin_lock_irq(&pool->lock);
@@ -3223,11 +3222,9 @@ static int init_worker_pool(struct worker_pool *pool)
3223 INIT_LIST_HEAD(&pool->idle_list); 3222 INIT_LIST_HEAD(&pool->idle_list);
3224 hash_init(pool->busy_hash); 3223 hash_init(pool->busy_hash);
3225 3224
3226 setup_deferrable_timer(&pool->idle_timer, idle_worker_timeout, 3225 timer_setup(&pool->idle_timer, idle_worker_timeout, TIMER_DEFERRABLE);
3227 (unsigned long)pool);
3228 3226
3229 setup_timer(&pool->mayday_timer, pool_mayday_timeout, 3227 timer_setup(&pool->mayday_timer, pool_mayday_timeout, 0);
3230 (unsigned long)pool);
3231 3228
3232 mutex_init(&pool->attach_mutex); 3229 mutex_init(&pool->attach_mutex);
3233 INIT_LIST_HEAD(&pool->workers); 3230 INIT_LIST_HEAD(&pool->workers);
@@ -5370,11 +5367,8 @@ static void workqueue_sysfs_unregister(struct workqueue_struct *wq) { }
5370 */ 5367 */
5371#ifdef CONFIG_WQ_WATCHDOG 5368#ifdef CONFIG_WQ_WATCHDOG
5372 5369
5373static void wq_watchdog_timer_fn(unsigned long data);
5374
5375static unsigned long wq_watchdog_thresh = 30; 5370static unsigned long wq_watchdog_thresh = 30;
5376static struct timer_list wq_watchdog_timer = 5371static struct timer_list wq_watchdog_timer;
5377 TIMER_DEFERRED_INITIALIZER(wq_watchdog_timer_fn, 0, 0);
5378 5372
5379static unsigned long wq_watchdog_touched = INITIAL_JIFFIES; 5373static unsigned long wq_watchdog_touched = INITIAL_JIFFIES;
5380static DEFINE_PER_CPU(unsigned long, wq_watchdog_touched_cpu) = INITIAL_JIFFIES; 5374static DEFINE_PER_CPU(unsigned long, wq_watchdog_touched_cpu) = INITIAL_JIFFIES;
@@ -5388,7 +5382,7 @@ static void wq_watchdog_reset_touched(void)
5388 per_cpu(wq_watchdog_touched_cpu, cpu) = jiffies; 5382 per_cpu(wq_watchdog_touched_cpu, cpu) = jiffies;
5389} 5383}
5390 5384
5391static void wq_watchdog_timer_fn(unsigned long data) 5385static void wq_watchdog_timer_fn(struct timer_list *unused)
5392{ 5386{
5393 unsigned long thresh = READ_ONCE(wq_watchdog_thresh) * HZ; 5387 unsigned long thresh = READ_ONCE(wq_watchdog_thresh) * HZ;
5394 bool lockup_detected = false; 5388 bool lockup_detected = false;
@@ -5490,6 +5484,7 @@ module_param_cb(watchdog_thresh, &wq_watchdog_thresh_ops, &wq_watchdog_thresh,
5490 5484
5491static void wq_watchdog_init(void) 5485static void wq_watchdog_init(void)
5492{ 5486{
5487 timer_setup(&wq_watchdog_timer, wq_watchdog_timer_fn, TIMER_DEFERRABLE);
5493 wq_watchdog_set_thresh(wq_watchdog_thresh); 5488 wq_watchdog_set_thresh(wq_watchdog_thresh);
5494} 5489}
5495 5490