History

Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull scheduler fixes from Ingo Molnar: "Two smaller fixes - plus a context tracking tracing fix that is a bit bigger" * 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: tracing/context-tracking: Add preempt_schedule_context() for tracing sched: Fix clear NOHZ_BALANCE_KICK sched/x86: Construct all sibling maps if smt

Linus Torvalds committed 13 years ago

Commit a3d5c342 parents 86c7667 29bb9e54 files · +78 −9Browse files

Unified · Split

4 files
  1. arch/x86/kernel/smpboot.c +4 −4
  2. include/linux/preempt.h +17 −1
  3. kernel/context_tracking.c +40 −0
  4. kernel/sched/core.c +17 −4
arch/x86/kernel/smpboot.c+4−4
@@ -372,15 +372,15 @@ static bool __cpuinit match_mc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) · 371 unmodified lines
372 372
373void __cpuinit set_cpu_sibling_map(int cpu)373void __cpuinit set_cpu_sibling_map(int cpu)
374{374{
375 bool has_mc = boot_cpu_data.x86_max_cores > 1;
376 bool has_smt = smp_num_siblings > 1;375 bool has_smt = smp_num_siblings > 1;
376 bool has_mp = has_smt || boot_cpu_data.x86_max_cores > 1;
377 struct cpuinfo_x86 *c = &cpu_data(cpu);377 struct cpuinfo_x86 *c = &cpu_data(cpu);
378 struct cpuinfo_x86 *o;378 struct cpuinfo_x86 *o;
379 int i;379 int i;
380 380
381 cpumask_set_cpu(cpu, cpu_sibling_setup_mask);381 cpumask_set_cpu(cpu, cpu_sibling_setup_mask);
382 382
383 if (!has_smt && !has_mc) {383 if (!has_mp) {
384 cpumask_set_cpu(cpu, cpu_sibling_mask(cpu));384 cpumask_set_cpu(cpu, cpu_sibling_mask(cpu));
385 cpumask_set_cpu(cpu, cpu_llc_shared_mask(cpu));385 cpumask_set_cpu(cpu, cpu_llc_shared_mask(cpu));
386 cpumask_set_cpu(cpu, cpu_core_mask(cpu));386 cpumask_set_cpu(cpu, cpu_core_mask(cpu));
@@ -394,7 +394,7 @@ void __cpuinit set_cpu_sibling_map(int cpu) · 7 unmodified lines
394 if ((i == cpu) || (has_smt && match_smt(c, o)))394 if ((i == cpu) || (has_smt && match_smt(c, o)))
395 link_mask(sibling, cpu, i);395 link_mask(sibling, cpu, i);
396 396
397 if ((i == cpu) || (has_mc && match_llc(c, o)))397 if ((i == cpu) || (has_mp && match_llc(c, o)))
398 link_mask(llc_shared, cpu, i);398 link_mask(llc_shared, cpu, i);
399 399
400 }400 }
@@ -406,7 +406,7 @@ void __cpuinit set_cpu_sibling_map(int cpu) · 5 unmodified lines
406 for_each_cpu(i, cpu_sibling_setup_mask) {406 for_each_cpu(i, cpu_sibling_setup_mask) {
407 o = &cpu_data(i);407 o = &cpu_data(i);
408 408
409 if ((i == cpu) || (has_mc && match_mc(c, o))) {409 if ((i == cpu) || (has_mp && match_mc(c, o))) {
410 link_mask(core, cpu, i);410 link_mask(core, cpu, i);
411 411
412 /*412 /*
include/linux/preempt.h+17−1
@@ -33,9 +33,25 @@ do { \ · 32 unmodified lines
33 preempt_schedule(); \33 preempt_schedule(); \
34} while (0)34} while (0)
35 35
36#ifdef CONFIG_CONTEXT_TRACKING
37
38void preempt_schedule_context(void);
39
40#define preempt_check_resched_context() \
41do { \
42 if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \
43 preempt_schedule_context(); \
44} while (0)
45#else
46
47#define preempt_check_resched_context() preempt_check_resched()
48
49#endif /* CONFIG_CONTEXT_TRACKING */
50
36#else /* !CONFIG_PREEMPT */51#else /* !CONFIG_PREEMPT */
37 52
38#define preempt_check_resched() do { } while (0)53#define preempt_check_resched() do { } while (0)
54#define preempt_check_resched_context() do { } while (0)
39 55
40#endif /* CONFIG_PREEMPT */56#endif /* CONFIG_PREEMPT */
41 57
@@ -88,7 +104,7 @@ do { \ · 46 unmodified lines
88do { \104do { \
89 preempt_enable_no_resched_notrace(); \105 preempt_enable_no_resched_notrace(); \
90 barrier(); \106 barrier(); \
91 preempt_check_resched(); \107 preempt_check_resched_context(); \
92} while (0)108} while (0)
93 109
94#else /* !CONFIG_PREEMPT_COUNT */110#else /* !CONFIG_PREEMPT_COUNT */
kernel/context_tracking.c+40−0
@@ -70,6 +70,46 @@ void user_enter(void) · 69 unmodified lines
70 local_irq_restore(flags);70 local_irq_restore(flags);
71}71}
72 72
73#ifdef CONFIG_PREEMPT
74/**
75 * preempt_schedule_context - preempt_schedule called by tracing
76 *
77 * The tracing infrastructure uses preempt_enable_notrace to prevent
78 * recursion and tracing preempt enabling caused by the tracing
79 * infrastructure itself. But as tracing can happen in areas coming
80 * from userspace or just about to enter userspace, a preempt enable
81 * can occur before user_exit() is called. This will cause the scheduler
82 * to be called when the system is still in usermode.
83 *
84 * To prevent this, the preempt_enable_notrace will use this function
85 * instead of preempt_schedule() to exit user context if needed before
86 * calling the scheduler.
87 */
88void __sched notrace preempt_schedule_context(void)
89{
90 struct thread_info *ti = current_thread_info();
91 enum ctx_state prev_ctx;
92
93 if (likely(ti->preempt_count || irqs_disabled()))
94 return;
95
96 /*
97 * Need to disable preemption in case user_exit() is traced
98 * and the tracer calls preempt_enable_notrace() causing
99 * an infinite recursion.
100 */
101 preempt_disable_notrace();
102 prev_ctx = exception_enter();
103 preempt_enable_no_resched_notrace();
104
105 preempt_schedule();
106
107 preempt_disable_notrace();
108 exception_exit(prev_ctx);
109 preempt_enable_notrace();
110}
111EXPORT_SYMBOL_GPL(preempt_schedule_context);
112#endif /* CONFIG_PREEMPT */
73 113
74/**114/**
75 * user_exit - Inform the context tracking that the CPU is115 * user_exit - Inform the context tracking that the CPU is
kernel/sched/core.c+17−4
@@ -633,7 +633,19 @@ void wake_up_nohz_cpu(int cpu) · 632 unmodified lines
633static inline bool got_nohz_idle_kick(void)633static inline bool got_nohz_idle_kick(void)
634{634{
635 int cpu = smp_processor_id();635 int cpu = smp_processor_id();
636 return idle_cpu(cpu) && test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu));636
637 if (!test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu)))
638 return false;
639
640 if (idle_cpu(cpu) && !need_resched())
641 return true;
642
643 /*
644 * We can't run Idle Load Balance on this CPU for this time so we
645 * cancel it and clear NOHZ_BALANCE_KICK
646 */
647 clear_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu));
648 return false;
637}649}
638 650
639#else /* CONFIG_NO_HZ_COMMON */651#else /* CONFIG_NO_HZ_COMMON */
@@ -1393,8 +1405,9 @@ static void sched_ttwu_pending(void) · 753 unmodified lines
1393 1405
1394void scheduler_ipi(void)1406void scheduler_ipi(void)
1395{1407{
1396 if (llist_empty(&this_rq()->wake_list) && !got_nohz_idle_kick()1408 if (llist_empty(&this_rq()->wake_list)
1397 && !tick_nohz_full_cpu(smp_processor_id()))1409 && !tick_nohz_full_cpu(smp_processor_id())
1410 && !got_nohz_idle_kick())
1398 return;1411 return;
1399 1412
1400 /*1413 /*
@@ -1417,7 +1430,7 @@ void scheduler_ipi(void) · 16 unmodified lines
1417 /*1430 /*
1418 * Check if someone kicked us for doing the nohz idle load balance.1431 * Check if someone kicked us for doing the nohz idle load balance.
1419 */1432 */
1420 if (unlikely(got_nohz_idle_kick() && !need_resched())) {1433 if (unlikely(got_nohz_idle_kick())) {
1421 this_rq()->idle_balance = 1;1434 this_rq()->idle_balance = 1;
1422 raise_softirq_irqoff(SCHED_SOFTIRQ);1435 raise_softirq_irqoff(SCHED_SOFTIRQ);
1423 }1436 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t