18
18
#include <linux/init.h>
19
19
#include <linux/module.h>
20
20
#include <linux/sysctl.h>
21
- #include <linux/smpboot.h>
22
- #include <linux/sched/rt.h>
23
- #include <uapi/linux/sched/types.h>
24
21
#include <linux/tick.h>
25
- #include <linux/workqueue.h>
26
22
#include <linux/sched/clock.h>
27
23
#include <linux/sched/debug.h>
28
24
#include <linux/sched/isolation.h>
25
+ #include <linux/stop_machine.h>
29
26
30
27
#include <asm/irq_regs.h>
31
28
#include <linux/kvm_para.h>
32
- #include <linux/kthread.h>
33
29
34
30
static DEFINE_MUTEX (watchdog_mutex );
35
31
@@ -169,11 +165,10 @@ static void lockup_detector_update_enable(void)
169
165
unsigned int __read_mostly softlockup_panic =
170
166
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE ;
171
167
172
- static bool softlockup_threads_initialized __read_mostly ;
168
+ static bool softlockup_initialized __read_mostly ;
173
169
static u64 __read_mostly sample_period ;
174
170
175
171
static DEFINE_PER_CPU (unsigned long, watchdog_touch_ts ) ;
176
- static DEFINE_PER_CPU (struct task_struct * , softlockup_watchdog ) ;
177
172
static DEFINE_PER_CPU (struct hrtimer , watchdog_hrtimer ) ;
178
173
static DEFINE_PER_CPU (bool , softlockup_touch_sync ) ;
179
174
static DEFINE_PER_CPU (bool , soft_watchdog_warn ) ;
@@ -335,6 +330,25 @@ static void watchdog_interrupt_count(void)
335
330
__this_cpu_inc (hrtimer_interrupts );
336
331
}
337
332
333
+ /*
334
+ * The watchdog thread function - touches the timestamp.
335
+ *
336
+ * It only runs once every sample_period seconds (4 seconds by
337
+ * default) to reset the softlockup timestamp. If this gets delayed
338
+ * for more than 2*watchdog_thresh seconds then the debug-printout
339
+ * triggers in watchdog_timer_fn().
340
+ */
341
+ static int softlockup_fn (void * data )
342
+ {
343
+ __this_cpu_write (soft_lockup_hrtimer_cnt ,
344
+ __this_cpu_read (hrtimer_interrupts ));
345
+ __touch_watchdog ();
346
+
347
+ return 0 ;
348
+ }
349
+
350
+ static DEFINE_PER_CPU (struct cpu_stop_work , softlockup_stop_work ) ;
351
+
338
352
/* watchdog kicker functions */
339
353
static enum hrtimer_restart watchdog_timer_fn (struct hrtimer * hrtimer )
340
354
{
@@ -350,7 +364,9 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
350
364
watchdog_interrupt_count ();
351
365
352
366
/* kick the softlockup detector */
353
- wake_up_process (__this_cpu_read (softlockup_watchdog ));
367
+ stop_one_cpu_nowait (smp_processor_id (),
368
+ softlockup_fn , NULL ,
369
+ this_cpu_ptr (& softlockup_stop_work ));
354
370
355
371
/* .. and repeat */
356
372
hrtimer_forward_now (hrtimer , ns_to_ktime (sample_period ));
@@ -448,17 +464,12 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
448
464
return HRTIMER_RESTART ;
449
465
}
450
466
451
- static void watchdog_set_prio (unsigned int policy , unsigned int prio )
452
- {
453
- struct sched_param param = { .sched_priority = prio };
454
-
455
- sched_setscheduler (current , policy , & param );
456
- }
457
-
458
467
static void watchdog_enable (unsigned int cpu )
459
468
{
460
469
struct hrtimer * hrtimer = this_cpu_ptr (& watchdog_hrtimer );
461
470
471
+ WARN_ON_ONCE (cpu != smp_processor_id ());
472
+
462
473
/*
463
474
* Start the timer first to prevent the NMI watchdog triggering
464
475
* before the timer has a chance to fire.
@@ -473,15 +484,14 @@ static void watchdog_enable(unsigned int cpu)
473
484
/* Enable the perf event */
474
485
if (watchdog_enabled & NMI_WATCHDOG_ENABLED )
475
486
watchdog_nmi_enable (cpu );
476
-
477
- watchdog_set_prio (SCHED_FIFO , MAX_RT_PRIO - 1 );
478
487
}
479
488
480
489
static void watchdog_disable (unsigned int cpu )
481
490
{
482
491
struct hrtimer * hrtimer = this_cpu_ptr (& watchdog_hrtimer );
483
492
484
- watchdog_set_prio (SCHED_NORMAL , 0 );
493
+ WARN_ON_ONCE (cpu != smp_processor_id ());
494
+
485
495
/*
486
496
* Disable the perf event first. That prevents that a large delay
487
497
* between disabling the timer and disabling the perf event causes
@@ -491,77 +501,63 @@ static void watchdog_disable(unsigned int cpu)
491
501
hrtimer_cancel (hrtimer );
492
502
}
493
503
494
- static void watchdog_cleanup ( unsigned int cpu , bool online )
504
+ static int softlockup_stop_fn ( void * data )
495
505
{
496
- watchdog_disable (cpu );
506
+ watchdog_disable (smp_processor_id ());
507
+ return 0 ;
497
508
}
498
509
499
- static int watchdog_should_run ( unsigned int cpu )
510
+ static void softlockup_stop_all ( void )
500
511
{
501
- return __this_cpu_read (hrtimer_interrupts ) !=
502
- __this_cpu_read (soft_lockup_hrtimer_cnt );
512
+ int cpu ;
513
+
514
+ if (!softlockup_initialized )
515
+ return ;
516
+
517
+ for_each_cpu (cpu , & watchdog_allowed_mask )
518
+ smp_call_on_cpu (cpu , softlockup_stop_fn , NULL , false);
519
+
520
+ cpumask_clear (& watchdog_allowed_mask );
503
521
}
504
522
505
- /*
506
- * The watchdog thread function - touches the timestamp.
507
- *
508
- * It only runs once every sample_period seconds (4 seconds by
509
- * default) to reset the softlockup timestamp. If this gets delayed
510
- * for more than 2*watchdog_thresh seconds then the debug-printout
511
- * triggers in watchdog_timer_fn().
512
- */
513
- static void watchdog (unsigned int cpu )
523
+ static int softlockup_start_fn (void * data )
514
524
{
515
- __this_cpu_write (soft_lockup_hrtimer_cnt ,
516
- __this_cpu_read (hrtimer_interrupts ));
517
- __touch_watchdog ();
525
+ watchdog_enable (smp_processor_id ());
526
+ return 0 ;
518
527
}
519
528
520
- static struct smp_hotplug_thread watchdog_threads = {
521
- .store = & softlockup_watchdog ,
522
- .thread_should_run = watchdog_should_run ,
523
- .thread_fn = watchdog ,
524
- .thread_comm = "watchdog/%u" ,
525
- .setup = watchdog_enable ,
526
- .cleanup = watchdog_cleanup ,
527
- .park = watchdog_disable ,
528
- .unpark = watchdog_enable ,
529
- };
530
-
531
- static void softlockup_update_smpboot_threads (void )
529
+ static void softlockup_start_all (void )
532
530
{
533
- lockdep_assert_held (& watchdog_mutex );
534
-
535
- if (!softlockup_threads_initialized )
536
- return ;
531
+ int cpu ;
537
532
538
- smpboot_update_cpumask_percpu_thread (& watchdog_threads ,
539
- & watchdog_allowed_mask );
533
+ cpumask_copy (& watchdog_allowed_mask , & watchdog_cpumask );
534
+ for_each_cpu (cpu , & watchdog_allowed_mask )
535
+ smp_call_on_cpu (cpu , softlockup_start_fn , NULL , false);
540
536
}
541
537
542
- /* Temporarily park all watchdog threads */
543
- static void softlockup_park_all_threads (void )
538
+ int lockup_detector_online_cpu (unsigned int cpu )
544
539
{
545
- cpumask_clear ( & watchdog_allowed_mask );
546
- softlockup_update_smpboot_threads () ;
540
+ watchdog_enable ( cpu );
541
+ return 0 ;
547
542
}
548
543
549
- /* Unpark enabled threads */
550
- static void softlockup_unpark_threads (void )
544
+ int lockup_detector_offline_cpu (unsigned int cpu )
551
545
{
552
- cpumask_copy ( & watchdog_allowed_mask , & watchdog_cpumask );
553
- softlockup_update_smpboot_threads () ;
546
+ watchdog_disable ( cpu );
547
+ return 0 ;
554
548
}
555
549
556
550
static void lockup_detector_reconfigure (void )
557
551
{
558
552
cpus_read_lock ();
559
553
watchdog_nmi_stop ();
560
- softlockup_park_all_threads ();
554
+
555
+ softlockup_stop_all ();
561
556
set_sample_period ();
562
557
lockup_detector_update_enable ();
563
558
if (watchdog_enabled && watchdog_thresh )
564
- softlockup_unpark_threads ();
559
+ softlockup_start_all ();
560
+
565
561
watchdog_nmi_start ();
566
562
cpus_read_unlock ();
567
563
/*
@@ -580,8 +576,6 @@ static void lockup_detector_reconfigure(void)
580
576
*/
581
577
static __init void lockup_detector_setup (void )
582
578
{
583
- int ret ;
584
-
585
579
/*
586
580
* If sysctl is off and watchdog got disabled on the command line,
587
581
* nothing to do here.
@@ -592,24 +586,13 @@ static __init void lockup_detector_setup(void)
592
586
!(watchdog_enabled && watchdog_thresh ))
593
587
return ;
594
588
595
- ret = smpboot_register_percpu_thread_cpumask (& watchdog_threads ,
596
- & watchdog_allowed_mask );
597
- if (ret ) {
598
- pr_err ("Failed to initialize soft lockup detector threads\n" );
599
- return ;
600
- }
601
-
602
589
mutex_lock (& watchdog_mutex );
603
- softlockup_threads_initialized = true;
604
590
lockup_detector_reconfigure ();
591
+ softlockup_initialized = true;
605
592
mutex_unlock (& watchdog_mutex );
606
593
}
607
594
608
595
#else /* CONFIG_SOFTLOCKUP_DETECTOR */
609
- static inline int watchdog_park_threads (void ) { return 0 ; }
610
- static inline void watchdog_unpark_threads (void ) { }
611
- static inline int watchdog_enable_all_cpus (void ) { return 0 ; }
612
- static inline void watchdog_disable_all_cpus (void ) { }
613
596
static void lockup_detector_reconfigure (void )
614
597
{
615
598
cpus_read_lock ();
0 commit comments