aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/Kconfig.preempt15
-rw-r--r--kernel/exit.c2
-rw-r--r--kernel/module.c15
-rw-r--r--kernel/sched.c54
-rw-r--r--kernel/sched_fair.c14
-rw-r--r--kernel/sched_rt.c6
-rw-r--r--kernel/time/ntp.c23
-rw-r--r--kernel/time/tick-sched.c2
-rw-r--r--kernel/time/timekeeping.c6
9 files changed, 100 insertions, 37 deletions
diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
index 0669b70fa6a3..9fdba03dc1fc 100644
--- a/kernel/Kconfig.preempt
+++ b/kernel/Kconfig.preempt
@@ -52,8 +52,23 @@ config PREEMPT
52 52
53endchoice 53endchoice
54 54
55config PREEMPT_RCU
56 bool "Preemptible RCU"
57 depends on PREEMPT
58 default n
59 help
60 This option reduces the latency of the kernel by making certain
61 RCU sections preemptible. Normally RCU code is non-preemptible, if
62 this option is selected then read-only RCU sections become
63 preemptible. This helps latency, but may expose bugs due to
64 now-naive assumptions about each RCU read-side critical section
65 remaining on a given CPU through its execution.
66
67 Say N if you are unsure.
68
55config RCU_TRACE 69config RCU_TRACE
56 bool "Enable tracing for RCU - currently stats in debugfs" 70 bool "Enable tracing for RCU - currently stats in debugfs"
71 depends on PREEMPT_RCU
57 select DEBUG_FS 72 select DEBUG_FS
58 default y 73 default y
59 help 74 help
diff --git a/kernel/exit.c b/kernel/exit.c
index cd20bf07e9e3..53872bf993fa 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1378,7 +1378,7 @@ unlock_sig:
1378 if (!retval && infop) 1378 if (!retval && infop)
1379 retval = put_user(0, &infop->si_errno); 1379 retval = put_user(0, &infop->si_errno);
1380 if (!retval && infop) 1380 if (!retval && infop)
1381 retval = put_user(why, &infop->si_code); 1381 retval = put_user((short)why, &infop->si_code);
1382 if (!retval && infop) 1382 if (!retval && infop)
1383 retval = put_user(exit_code, &infop->si_status); 1383 retval = put_user(exit_code, &infop->si_status);
1384 if (!retval && infop) 1384 if (!retval && infop)
diff --git a/kernel/module.c b/kernel/module.c
index be4807fb90e4..5d437bffd8dc 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2178,10 +2178,20 @@ sys_init_module(void __user *umod,
2178 wake_up(&module_wq); 2178 wake_up(&module_wq);
2179 return ret; 2179 return ret;
2180 } 2180 }
2181 if (ret > 0) {
2182 printk(KERN_WARNING "%s: '%s'->init suspiciously returned %d, "
2183 "it should follow 0/-E convention\n"
2184 KERN_WARNING "%s: loading module anyway...\n",
2185 __func__, mod->name, ret,
2186 __func__);
2187 dump_stack();
2188 }
2181 2189
2182 /* Now it's a first class citizen! */ 2190 /* Now it's a first class citizen! Wake up anyone waiting for it. */
2183 mutex_lock(&module_mutex);
2184 mod->state = MODULE_STATE_LIVE; 2191 mod->state = MODULE_STATE_LIVE;
2192 wake_up(&module_wq);
2193
2194 mutex_lock(&module_mutex);
2185 /* Drop initial reference. */ 2195 /* Drop initial reference. */
2186 module_put(mod); 2196 module_put(mod);
2187 unwind_remove_table(mod->unwind_info, 1); 2197 unwind_remove_table(mod->unwind_info, 1);
@@ -2190,7 +2200,6 @@ sys_init_module(void __user *umod,
2190 mod->init_size = 0; 2200 mod->init_size = 0;
2191 mod->init_text_size = 0; 2201 mod->init_text_size = 0;
2192 mutex_unlock(&module_mutex); 2202 mutex_unlock(&module_mutex);
2193 wake_up(&module_wq);
2194 2203
2195 return 0; 2204 return 0;
2196} 2205}
diff --git a/kernel/sched.c b/kernel/sched.c
index dcd553cc4ee8..b02e4fc25645 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4422,7 +4422,7 @@ int task_nice(const struct task_struct *p)
4422{ 4422{
4423 return TASK_NICE(p); 4423 return TASK_NICE(p);
4424} 4424}
4425EXPORT_SYMBOL_GPL(task_nice); 4425EXPORT_SYMBOL(task_nice);
4426 4426
4427/** 4427/**
4428 * idle_cpu - is a given cpu idle currently? 4428 * idle_cpu - is a given cpu idle currently?
@@ -5100,7 +5100,7 @@ long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval)
5100 time_slice = 0; 5100 time_slice = 0;
5101 if (p->policy == SCHED_RR) { 5101 if (p->policy == SCHED_RR) {
5102 time_slice = DEF_TIMESLICE; 5102 time_slice = DEF_TIMESLICE;
5103 } else { 5103 } else if (p->policy != SCHED_FIFO) {
5104 struct sched_entity *se = &p->se; 5104 struct sched_entity *se = &p->se;
5105 unsigned long flags; 5105 unsigned long flags;
5106 struct rq *rq; 5106 struct rq *rq;
@@ -5813,6 +5813,13 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
5813 /* Must be high prio: stop_machine expects to yield to it. */ 5813 /* Must be high prio: stop_machine expects to yield to it. */
5814 rq = task_rq_lock(p, &flags); 5814 rq = task_rq_lock(p, &flags);
5815 __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1); 5815 __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1);
5816
5817 /* Update our root-domain */
5818 if (rq->rd) {
5819 BUG_ON(!cpu_isset(cpu, rq->rd->span));
5820 cpu_set(cpu, rq->rd->online);
5821 }
5822
5816 task_rq_unlock(rq, &flags); 5823 task_rq_unlock(rq, &flags);
5817 cpu_rq(cpu)->migration_thread = p; 5824 cpu_rq(cpu)->migration_thread = p;
5818 break; 5825 break;
@@ -5821,15 +5828,6 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
5821 case CPU_ONLINE_FROZEN: 5828 case CPU_ONLINE_FROZEN:
5822 /* Strictly unnecessary, as first user will wake it. */ 5829 /* Strictly unnecessary, as first user will wake it. */
5823 wake_up_process(cpu_rq(cpu)->migration_thread); 5830 wake_up_process(cpu_rq(cpu)->migration_thread);
5824
5825 /* Update our root-domain */
5826 rq = cpu_rq(cpu);
5827 spin_lock_irqsave(&rq->lock, flags);
5828 if (rq->rd) {
5829 BUG_ON(!cpu_isset(cpu, rq->rd->span));
5830 cpu_set(cpu, rq->rd->online);
5831 }
5832 spin_unlock_irqrestore(&rq->lock, flags);
5833 break; 5831 break;
5834 5832
5835#ifdef CONFIG_HOTPLUG_CPU 5833#ifdef CONFIG_HOTPLUG_CPU
@@ -6105,8 +6103,6 @@ static void rq_attach_root(struct rq *rq, struct root_domain *rd)
6105 rq->rd = rd; 6103 rq->rd = rd;
6106 6104
6107 cpu_set(rq->cpu, rd->span); 6105 cpu_set(rq->cpu, rd->span);
6108 if (cpu_isset(rq->cpu, cpu_online_map))
6109 cpu_set(rq->cpu, rd->online);
6110 6106
6111 for (class = sched_class_highest; class; class = class->next) { 6107 for (class = sched_class_highest; class; class = class->next) {
6112 if (class->join_domain) 6108 if (class->join_domain)
@@ -7625,6 +7621,11 @@ void sched_move_task(struct task_struct *tsk)
7625 7621
7626 set_task_rq(tsk, task_cpu(tsk)); 7622 set_task_rq(tsk, task_cpu(tsk));
7627 7623
7624#ifdef CONFIG_FAIR_GROUP_SCHED
7625 if (tsk->sched_class->moved_group)
7626 tsk->sched_class->moved_group(tsk);
7627#endif
7628
7628 if (on_rq) { 7629 if (on_rq) {
7629 if (unlikely(running)) 7630 if (unlikely(running))
7630 tsk->sched_class->set_curr_task(rq); 7631 tsk->sched_class->set_curr_task(rq);
@@ -7721,9 +7722,7 @@ static unsigned long to_ratio(u64 period, u64 runtime)
7721 if (runtime == RUNTIME_INF) 7722 if (runtime == RUNTIME_INF)
7722 return 1ULL << 16; 7723 return 1ULL << 16;
7723 7724
7724 runtime *= (1ULL << 16); 7725 return div64_64(runtime << 16, period);
7725 div64_64(runtime, period);
7726 return runtime;
7727} 7726}
7728 7727
7729static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime) 7728static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime)
@@ -7747,25 +7746,40 @@ static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime)
7747 return total + to_ratio(period, runtime) < global_ratio; 7746 return total + to_ratio(period, runtime) < global_ratio;
7748} 7747}
7749 7748
7749/* Must be called with tasklist_lock held */
7750static inline int tg_has_rt_tasks(struct task_group *tg)
7751{
7752 struct task_struct *g, *p;
7753 do_each_thread(g, p) {
7754 if (rt_task(p) && rt_rq_of_se(&p->rt)->tg == tg)
7755 return 1;
7756 } while_each_thread(g, p);
7757 return 0;
7758}
7759
7750int sched_group_set_rt_runtime(struct task_group *tg, long rt_runtime_us) 7760int sched_group_set_rt_runtime(struct task_group *tg, long rt_runtime_us)
7751{ 7761{
7752 u64 rt_runtime, rt_period; 7762 u64 rt_runtime, rt_period;
7753 int err = 0; 7763 int err = 0;
7754 7764
7755 rt_period = sysctl_sched_rt_period * NSEC_PER_USEC; 7765 rt_period = (u64)sysctl_sched_rt_period * NSEC_PER_USEC;
7756 rt_runtime = (u64)rt_runtime_us * NSEC_PER_USEC; 7766 rt_runtime = (u64)rt_runtime_us * NSEC_PER_USEC;
7757 if (rt_runtime_us == -1) 7767 if (rt_runtime_us == -1)
7758 rt_runtime = rt_period; 7768 rt_runtime = RUNTIME_INF;
7759 7769
7760 mutex_lock(&rt_constraints_mutex); 7770 mutex_lock(&rt_constraints_mutex);
7771 read_lock(&tasklist_lock);
7772 if (rt_runtime_us == 0 && tg_has_rt_tasks(tg)) {
7773 err = -EBUSY;
7774 goto unlock;
7775 }
7761 if (!__rt_schedulable(tg, rt_period, rt_runtime)) { 7776 if (!__rt_schedulable(tg, rt_period, rt_runtime)) {
7762 err = -EINVAL; 7777 err = -EINVAL;
7763 goto unlock; 7778 goto unlock;
7764 } 7779 }
7765 if (rt_runtime_us == -1)
7766 rt_runtime = RUNTIME_INF;
7767 tg->rt_runtime = rt_runtime; 7780 tg->rt_runtime = rt_runtime;
7768 unlock: 7781 unlock:
7782 read_unlock(&tasklist_lock);
7769 mutex_unlock(&rt_constraints_mutex); 7783 mutex_unlock(&rt_constraints_mutex);
7770 7784
7771 return err; 7785 return err;
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 3df4d46994ca..e2a530515619 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -1353,6 +1353,16 @@ static void set_curr_task_fair(struct rq *rq)
1353 set_next_entity(cfs_rq_of(se), se); 1353 set_next_entity(cfs_rq_of(se), se);
1354} 1354}
1355 1355
1356#ifdef CONFIG_FAIR_GROUP_SCHED
1357static void moved_group_fair(struct task_struct *p)
1358{
1359 struct cfs_rq *cfs_rq = task_cfs_rq(p);
1360
1361 update_curr(cfs_rq);
1362 place_entity(cfs_rq, &p->se, 1);
1363}
1364#endif
1365
1356/* 1366/*
1357 * All the scheduling class methods: 1367 * All the scheduling class methods:
1358 */ 1368 */
@@ -1381,6 +1391,10 @@ static const struct sched_class fair_sched_class = {
1381 1391
1382 .prio_changed = prio_changed_fair, 1392 .prio_changed = prio_changed_fair,
1383 .switched_to = switched_to_fair, 1393 .switched_to = switched_to_fair,
1394
1395#ifdef CONFIG_FAIR_GROUP_SCHED
1396 .moved_group = moved_group_fair,
1397#endif
1384}; 1398};
1385 1399
1386#ifdef CONFIG_SCHED_DEBUG 1400#ifdef CONFIG_SCHED_DEBUG
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index 76e828517541..0a6d2e516420 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -1107,9 +1107,11 @@ static void prio_changed_rt(struct rq *rq, struct task_struct *p,
1107 pull_rt_task(rq); 1107 pull_rt_task(rq);
1108 /* 1108 /*
1109 * If there's a higher priority task waiting to run 1109 * If there's a higher priority task waiting to run
1110 * then reschedule. 1110 * then reschedule. Note, the above pull_rt_task
1111 * can release the rq lock and p could migrate.
1112 * Only reschedule if p is still on the same runqueue.
1111 */ 1113 */
1112 if (p->prio > rq->rt.highest_prio) 1114 if (p->prio > rq->rt.highest_prio && rq->curr == p)
1113 resched_task(p); 1115 resched_task(p);
1114#else 1116#else
1115 /* For UP simply resched on drop of prio */ 1117 /* For UP simply resched on drop of prio */
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index c88b5910e7ab..5fd9b9469770 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -42,12 +42,13 @@ long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */
42long time_freq; /* frequency offset (scaled ppm)*/ 42long time_freq; /* frequency offset (scaled ppm)*/
43static long time_reftime; /* time at last adjustment (s) */ 43static long time_reftime; /* time at last adjustment (s) */
44long time_adjust; 44long time_adjust;
45static long ntp_tick_adj;
45 46
46static void ntp_update_frequency(void) 47static void ntp_update_frequency(void)
47{ 48{
48 u64 second_length = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) 49 u64 second_length = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ)
49 << TICK_LENGTH_SHIFT; 50 << TICK_LENGTH_SHIFT;
50 second_length += (s64)CLOCK_TICK_ADJUST << TICK_LENGTH_SHIFT; 51 second_length += (s64)ntp_tick_adj << TICK_LENGTH_SHIFT;
51 second_length += (s64)time_freq << (TICK_LENGTH_SHIFT - SHIFT_NSEC); 52 second_length += (s64)time_freq << (TICK_LENGTH_SHIFT - SHIFT_NSEC);
52 53
53 tick_length_base = second_length; 54 tick_length_base = second_length;
@@ -342,14 +343,16 @@ int do_adjtimex(struct timex *txc)
342 freq_adj = shift_right(freq_adj, time_constant * 2 + 343 freq_adj = shift_right(freq_adj, time_constant * 2 +
343 (SHIFT_PLL + 2) * 2 - SHIFT_NSEC); 344 (SHIFT_PLL + 2) * 2 - SHIFT_NSEC);
344 if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) { 345 if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) {
346 u64 utemp64;
345 temp64 = time_offset << (SHIFT_NSEC - SHIFT_FLL); 347 temp64 = time_offset << (SHIFT_NSEC - SHIFT_FLL);
346 if (time_offset < 0) { 348 if (time_offset < 0) {
347 temp64 = -temp64; 349 utemp64 = -temp64;
348 do_div(temp64, mtemp); 350 do_div(utemp64, mtemp);
349 freq_adj -= temp64; 351 freq_adj -= utemp64;
350 } else { 352 } else {
351 do_div(temp64, mtemp); 353 utemp64 = temp64;
352 freq_adj += temp64; 354 do_div(utemp64, mtemp);
355 freq_adj += utemp64;
353 } 356 }
354 } 357 }
355 freq_adj += time_freq; 358 freq_adj += time_freq;
@@ -400,3 +403,11 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0)
400 notify_cmos_timer(); 403 notify_cmos_timer();
401 return(result); 404 return(result);
402} 405}
406
407static int __init ntp_tick_adj_setup(char *str)
408{
409 ntp_tick_adj = simple_strtol(str, NULL, 0);
410 return 1;
411}
412
413__setup("ntp_tick_adj=", ntp_tick_adj_setup);
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 2968298f8f36..686da821d376 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -640,7 +640,7 @@ void tick_cancel_sched_timer(int cpu)
640 640
641 if (ts->sched_timer.base) 641 if (ts->sched_timer.base)
642 hrtimer_cancel(&ts->sched_timer); 642 hrtimer_cancel(&ts->sched_timer);
643 ts->tick_stopped = 0; 643
644 ts->nohz_mode = NOHZ_MODE_INACTIVE; 644 ts->nohz_mode = NOHZ_MODE_INACTIVE;
645} 645}
646#endif /* HIGH_RES_TIMERS */ 646#endif /* HIGH_RES_TIMERS */
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 1af9fb050fe2..671af612b768 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -187,8 +187,7 @@ static void change_clocksource(void)
187 187
188 clock->error = 0; 188 clock->error = 0;
189 clock->xtime_nsec = 0; 189 clock->xtime_nsec = 0;
190 clocksource_calculate_interval(clock, 190 clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
191 (unsigned long)(current_tick_length()>>TICK_LENGTH_SHIFT));
192 191
193 tick_clock_notify(); 192 tick_clock_notify();
194 193
@@ -245,8 +244,7 @@ void __init timekeeping_init(void)
245 ntp_clear(); 244 ntp_clear();
246 245
247 clock = clocksource_get_next(); 246 clock = clocksource_get_next();
248 clocksource_calculate_interval(clock, 247 clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
249 (unsigned long)(current_tick_length()>>TICK_LENGTH_SHIFT));
250 clock->cycle_last = clocksource_read(clock); 248 clock->cycle_last = clocksource_read(clock);
251 249
252 xtime.tv_sec = sec; 250 xtime.tv_sec = sec;