Browse Source

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

Pull timer fixes from Thomas Gleixner:
 "The itimer removal one is not strictly a fix, but I really wanted to
  avoid a rebase of the urgent ones."

* 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  Revert "clocksource: Load the ACPI PM clocksource asynchronously"
  clockevents: tTack broadcast device mode change in tick_broadcast_switch_to_oneshot()
  itimer: Use printk_once instead of WARN_ONCE
  nohz: Fix stale jiffies update in tick_nohz_restart()
  tick: Document TICK_ONESHOT config option
  proc: stats: Use arch_idle_time for idle and iowait times if available
  itimer: Schedule silent NULL pointer fixup in setitimer() for removal
Linus Torvalds 13 years ago
parent
commit
ccb1ec95e9

+ 8 - 0
Documentation/feature-removal-schedule.txt

@@ -531,3 +531,11 @@ Why:	There appear to be no production users of the get_robust_list syscall,
 	of ASLR. It was only ever intended for debugging, so it should be
 	of ASLR. It was only ever intended for debugging, so it should be
 	removed.
 	removed.
 Who:	Kees Cook <keescook@chromium.org>
 Who:	Kees Cook <keescook@chromium.org>
+
+----------------------------
+
+What:	setitimer accepts user NULL pointer (value)
+When:	3.6
+Why:	setitimer is not returning -EFAULT if user pointer is NULL. This
+	violates the spec.
+Who:	Sasikantha Babu <sasikanth.v19@gmail.com>

+ 8 - 16
drivers/clocksource/acpi_pm.c

@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
-#include <linux/async.h>
 #include <asm/io.h>
 #include <asm/io.h>
 
 
 /*
 /*
@@ -180,15 +179,17 @@ static int verify_pmtmr_rate(void)
 /* Number of reads we try to get two different values */
 /* Number of reads we try to get two different values */
 #define ACPI_PM_READ_CHECKS 10000
 #define ACPI_PM_READ_CHECKS 10000
 
 
-static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie)
+static int __init init_acpi_pm_clocksource(void)
 {
 {
 	cycle_t value1, value2;
 	cycle_t value1, value2;
 	unsigned int i, j = 0;
 	unsigned int i, j = 0;
 
 
+	if (!pmtmr_ioport)
+		return -ENODEV;
 
 
 	/* "verify" this timing source: */
 	/* "verify" this timing source: */
 	for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
 	for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
-		usleep_range(100 * j, 100 * j + 100);
+		udelay(100 * j);
 		value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
 		value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
 		for (i = 0; i < ACPI_PM_READ_CHECKS; i++) {
 		for (i = 0; i < ACPI_PM_READ_CHECKS; i++) {
 			value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
 			value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
@@ -202,34 +203,25 @@ static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie
 			       " 0x%#llx, 0x%#llx - aborting.\n",
 			       " 0x%#llx, 0x%#llx - aborting.\n",
 			       value1, value2);
 			       value1, value2);
 			pmtmr_ioport = 0;
 			pmtmr_ioport = 0;
-			return;
+			return -EINVAL;
 		}
 		}
 		if (i == ACPI_PM_READ_CHECKS) {
 		if (i == ACPI_PM_READ_CHECKS) {
 			printk(KERN_INFO "PM-Timer failed consistency check "
 			printk(KERN_INFO "PM-Timer failed consistency check "
 			       " (0x%#llx) - aborting.\n", value1);
 			       " (0x%#llx) - aborting.\n", value1);
 			pmtmr_ioport = 0;
 			pmtmr_ioport = 0;
-			return;
+			return -ENODEV;
 		}
 		}
 	}
 	}
 
 
 	if (verify_pmtmr_rate() != 0){
 	if (verify_pmtmr_rate() != 0){
 		pmtmr_ioport = 0;
 		pmtmr_ioport = 0;
-		return;
+		return -ENODEV;
 	}
 	}
 
 
-	clocksource_register_hz(&clocksource_acpi_pm,
+	return clocksource_register_hz(&clocksource_acpi_pm,
 						PMTMR_TICKS_PER_SEC);
 						PMTMR_TICKS_PER_SEC);
 }
 }
 
 
-static int __init init_acpi_pm_clocksource(void)
-{
-	if (!pmtmr_ioport)
-		return -ENODEV;
-
-	async_schedule(acpi_pm_clocksource_async, NULL);
-	return 0;
-}
-
 /* We use fs_initcall because we want the PCI fixups to have run
 /* We use fs_initcall because we want the PCI fixups to have run
  * but we still need to load before device_initcall
  * but we still need to load before device_initcall
  */
  */

+ 28 - 6
fs/proc/stat.c

@@ -18,19 +18,39 @@
 #ifndef arch_irq_stat
 #ifndef arch_irq_stat
 #define arch_irq_stat() 0
 #define arch_irq_stat() 0
 #endif
 #endif
-#ifndef arch_idle_time
-#define arch_idle_time(cpu) 0
-#endif
+
+#ifdef arch_idle_time
+
+static cputime64_t get_idle_time(int cpu)
+{
+	cputime64_t idle;
+
+	idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE];
+	if (cpu_online(cpu) && !nr_iowait_cpu(cpu))
+		idle += arch_idle_time(cpu);
+	return idle;
+}
+
+static cputime64_t get_iowait_time(int cpu)
+{
+	cputime64_t iowait;
+
+	iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT];
+	if (cpu_online(cpu) && nr_iowait_cpu(cpu))
+		iowait += arch_idle_time(cpu);
+	return iowait;
+}
+
+#else
 
 
 static u64 get_idle_time(int cpu)
 static u64 get_idle_time(int cpu)
 {
 {
 	u64 idle, idle_time = get_cpu_idle_time_us(cpu, NULL);
 	u64 idle, idle_time = get_cpu_idle_time_us(cpu, NULL);
 
 
-	if (idle_time == -1ULL) {
+	if (idle_time == -1ULL)
 		/* !NO_HZ so we can rely on cpustat.idle */
 		/* !NO_HZ so we can rely on cpustat.idle */
 		idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE];
 		idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE];
-		idle += arch_idle_time(cpu);
-	} else
+	else
 		idle = usecs_to_cputime64(idle_time);
 		idle = usecs_to_cputime64(idle_time);
 
 
 	return idle;
 	return idle;
@@ -49,6 +69,8 @@ static u64 get_iowait_time(int cpu)
 	return iowait;
 	return iowait;
 }
 }
 
 
+#endif
+
 static int show_stat(struct seq_file *p, void *v)
 static int show_stat(struct seq_file *p, void *v)
 {
 {
 	int i, j;
 	int i, j;

+ 6 - 2
kernel/itimer.c

@@ -284,8 +284,12 @@ SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value,
 	if (value) {
 	if (value) {
 		if(copy_from_user(&set_buffer, value, sizeof(set_buffer)))
 		if(copy_from_user(&set_buffer, value, sizeof(set_buffer)))
 			return -EFAULT;
 			return -EFAULT;
-	} else
-		memset((char *) &set_buffer, 0, sizeof(set_buffer));
+	} else {
+		memset(&set_buffer, 0, sizeof(set_buffer));
+		printk_once(KERN_WARNING "%s calls setitimer() with new_value NULL pointer."
+			    " Misfeature support will be removed\n",
+			    current->comm);
+	}
 
 
 	error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL);
 	error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL);
 	if (error || !ovalue)
 	if (error || !ovalue)

+ 4 - 0
kernel/time/Kconfig

@@ -1,6 +1,10 @@
 #
 #
 # Timer subsystem related configuration options
 # Timer subsystem related configuration options
 #
 #
+
+# Core internal switch. Selected by NO_HZ / HIGH_RES_TIMERS. This is
+# only related to the tick functionality. Oneshot clockevent devices
+# are supported independ of this.
 config TICK_ONESHOT
 config TICK_ONESHOT
 	bool
 	bool
 
 

+ 3 - 1
kernel/time/tick-broadcast.c

@@ -575,10 +575,12 @@ void tick_broadcast_switch_to_oneshot(void)
 	unsigned long flags;
 	unsigned long flags;
 
 
 	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
 	raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
+
+	tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT;
+
 	if (cpumask_empty(tick_get_broadcast_mask()))
 	if (cpumask_empty(tick_get_broadcast_mask()))
 		goto end;
 		goto end;
 
 
-	tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT;
 	bc = tick_broadcast_device.evtdev;
 	bc = tick_broadcast_device.evtdev;
 	if (bc)
 	if (bc)
 		tick_broadcast_setup_oneshot(bc);
 		tick_broadcast_setup_oneshot(bc);

+ 2 - 2
kernel/time/tick-sched.c

@@ -534,9 +534,9 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now)
 				hrtimer_get_expires(&ts->sched_timer), 0))
 				hrtimer_get_expires(&ts->sched_timer), 0))
 				break;
 				break;
 		}
 		}
-		/* Update jiffies and reread time */
-		tick_do_update_jiffies64(now);
+		/* Reread time and update jiffies */
 		now = ktime_get();
 		now = ktime_get();
+		tick_do_update_jiffies64(now);
 	}
 	}
 }
 }