Skip to contentSkip to conversation

Restructuring hpet timer generic clock interfaces

PATCH In review Venki Pallipadi 2 participants 6 messages May 7, 2007 – May 8, 2007

lore
Share & tools
lore
#0 lore raw

PATCH 1/8 Restructuring hpet timer generic clock interfaces

i386 HPET changes.

Patchset does the following changes to HPET support:
* Add HPET force detect to ICH chipsets, and detect the
presence of HPET through PCI quirk.
* Enable HPET timer to function in standard interrupt delivery mode, against the current legacy replacement mode
* Enable HPET as a PER CPU time event, which will help in laptops that supports C3 and hence has unreliable LAPIC timer.

The changes enable processors to stay in idle longer, by increasing the average time spend in an idle state per call, by more than twice, on my dual core laptop. It reduces the number of interrupts on a totally idle system, compared to when I use PIT.

The patchset is split as below:
* 1/8 - Restructuring of current HPET code
* 2/8 - Change clockevent brodcast timer code and enable switching to broadcast timer with a higher rating
* 3/8 - kernel irq balance bug fixes
* 4/8 - ICH detecting and enabling HPET through PCI quirk
* 5/8 - Late init HPET, after detection from PCI quirk
* 6/8 - Major part of the changes in this patchset are in this patch. Add support HPET timer in standard interrupt delivery mode
* 7/8 - Boot option changes for HPET in standard interrupt delivery mode
* 8/8 - Changes related to registering with HPET character driver

The patchset applies to 2.6.21. There will be conflicts with patchset that Thomas posted yesterday. Will work on resolving those differences.

This patch:

Restructure and rename legacy replacement mode HPET timer support. Just the code structural changes and should be zero functionality change.

arch/i386/kernel/hpet.c +69 -54
Index: linux-2.6.21-rc-mm-hpet/arch/i386/kernel/hpet.c
===================================================================
@@ -110,9 +110,9 @@
  */
 static unsigned long hpet_period;
 
-static void hpet_set_mode(enum clock_event_mode mode,
+static void hpet_legacy_set_mode(enum clock_event_mode mode,
 			  struct clock_event_device *evt);
-static int hpet_next_event(unsigned long delta,
+static int hpet_legacy_next_event(unsigned long delta,
 			   struct clock_event_device *evt);
 
 /*
@@ -121,8 +121,8 @@
 static struct clock_event_device hpet_clockevent = {
 	.name		= "hpet",
 	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode	= hpet_set_mode,
-	.set_next_event = hpet_next_event,
+	.set_mode	= hpet_legacy_set_mode,
+	.set_next_event = hpet_legacy_next_event,
 	.shift		= 32,
 	.irq		= 0,
 };
@@ -139,7 +139,7 @@
 	hpet_writel(cfg, HPET_CFG);
 }
 
-static void hpet_enable_int(void)
+static void hpet_enable_legacy_int(void)
 {
 	unsigned long cfg = hpet_readl(HPET_CFG);
 
@@ -148,7 +148,39 @@
 	hpet_legacy_int_enabled = 1;
 }
 
-static void hpet_set_mode(enum clock_event_mode mode,
+static void hpet_legacy_clockevent_register(void)
+{
+	uint64_t hpet_freq;
+
+	/* Start HPET legacy interrupts */
+	hpet_enable_legacy_int();
+
+	/*
+	 * The period is a femto seconds value. We need to calculate the
+	 * scaled math multiplication factor for nanosecond to hpet tick
+	 * conversion.
+	 */
+	hpet_freq = 1000000000000000ULL;
+	do_div(hpet_freq, hpet_period);
+	hpet_clockevent.mult = div_sc((unsigned long) hpet_freq,
+				      NSEC_PER_SEC, 32);
+	/* Calculate the min / max delta */
+	hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
+							   &hpet_clockevent);
+	hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30,
+							   &hpet_clockevent);
+
+	/*
+	 * Start hpet with the boot cpu mask and make it
+	 * global after the IO_APIC has been initialized.
+	 */
+	hpet_clockevent.cpumask = cpumask_of_cpu(0);
+	clockevents_register_device(&hpet_clockevent);
+	global_clock_event = &hpet_clockevent;
+	printk(KERN_DEBUG "hpet clockevent registered\n");
+}
+
+static void hpet_legacy_set_mode(enum clock_event_mode mode,
 			  struct clock_event_device *evt)
 {
 	unsigned long cfg, cmp, now;
@@ -190,7 +222,7 @@
 	}
 }
 
-static int hpet_next_event(unsigned long delta,
+static int hpet_legacy_next_event(unsigned long delta,
 			   struct clock_event_device *evt)
 {
 	unsigned long cnt;
@@ -219,14 +251,39 @@
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+static void hpet_clocksource_register(void)
+{
+	u64 tmp;
+
+	/* Start the counter */
+	hpet_start_counter();
+
+	/* Initialize and register HPET clocksource
+	 *
+	 * hpet period is in femto seconds per cycle
+	 * so we need to convert this to ns/cyc units
+	 * aproximated by mult/2^shift
+	 *
+	 *  fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift
+	 *  fsec/cyc * 1ns/1000000fsec * 2^shift = mult
+	 *  fsec/cyc * 2^shift * 1nsec/1000000fsec = mult
+	 *  (fsec/cyc << shift)/1000000 = mult
+	 *  (hpet_period << shift)/FSEC_PER_NSEC = mult
+	 */
+	tmp = (u64)hpet_period << HPET_SHIFT;
+	do_div(tmp, FSEC_PER_NSEC);
+	clocksource_hpet.mult = (u32)tmp;
+
+	clocksource_register(&clocksource_hpet);
+	printk(KERN_DEBUG "hpet clocksource registered\n");
+}
+
 /*
  * Try to setup the HPET timer
  */
 int __init hpet_enable(void)
 {
 	unsigned long id;
-	uint64_t hpet_freq;
-	u64 tmp;
 
 	if (!is_hpet_capable())
 		return 0;
@@ -241,21 +298,6 @@
 		goto out_nohpet;
 
 	/*
-	 * The period is a femto seconds value. We need to calculate the
-	 * scaled math multiplication factor for nanosecond to hpet tick
-	 * conversion.
-	 */
-	hpet_freq = 1000000000000000ULL;
-	do_div(hpet_freq, hpet_period);
-	hpet_clockevent.mult = div_sc((unsigned long) hpet_freq,
-				      NSEC_PER_SEC, 32);
-	/* Calculate the min / max delta */
-	hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
-							   &hpet_clockevent);
-	hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30,
-							   &hpet_clockevent);
-
-	/*
 	 * Read the HPET ID register to retrieve the IRQ routing
 	 * information and the number of channels
 	 */
@@ -270,38 +312,11 @@
 		goto out_nohpet;
 #endif
 
-	/* Start the counter */
-	hpet_start_counter();
-
-	/* Initialize and register HPET clocksource
-	 *
-	 * hpet period is in femto seconds per cycle
-	 * so we need to convert this to ns/cyc units
-	 * aproximated by mult/2^shift
-	 *
-	 *  fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift
-	 *  fsec/cyc * 1ns/1000000fsec * 2^shift = mult
-	 *  fsec/cyc * 2^shift * 1nsec/1000000fsec = mult
-	 *  (fsec/cyc << shift)/1000000 = mult
-	 *  (hpet_period << shift)/FSEC_PER_NSEC = mult
-	 */
-	tmp = (u64)hpet_period << HPET_SHIFT;
-	do_div(tmp, FSEC_PER_NSEC);
-	clocksource_hpet.mult = (u32)tmp;
-
-	clocksource_register(&clocksource_hpet);
-
+	hpet_clocksource_register();
 
 	if (id & HPET_ID_LEGSUP) {
-		hpet_enable_int();
 		hpet_reserve_platform_timers(id);
-		/*
-		 * Start hpet with the boot cpu mask and make it
-		 * global after the IO_APIC has been initialized.
-		 */
-		hpet_clockevent.cpumask =cpumask_of_cpu(0);
-		clockevents_register_device(&hpet_clockevent);
-		global_clock_event = &hpet_clockevent;
+		hpet_legacy_clockevent_register();
 		return 1;
 	}
 	return 0;
@@ -551,7 +566,7 @@
 	id = hpet_readl(HPET_ID);
 
 	if (id & HPET_ID_LEGSUP)
-		hpet_enable_int();
+		hpet_enable_legacy_int();
 
 	return 0;
 }
#1 lore raw

Hi;

07 May 2007 Pts tarihinde, Venki Pallipadi şunları yazmıştı:

Quoted 10 lines

i386 HPET changes.

Patchset does the following changes to HPET support:
* Add HPET force detect to ICH chipsets, and detect the presence of HPET through PCI quirk.
* Enable HPET timer to function in standard interrupt delivery mode, against the current legacy replacement mode
* Enable HPET as a PER CPU time event, which will help in laptops that supports C3 and hence has unreliable LAPIC timer.

Quoted 4 lines

The changes enable processors to stay in idle longer, by increasing the average time spend in an idle state per call, by more than twice, on my dual core laptop. It reduces the number of interrupts on a totally idle system, compared to when I use PIT.

My machine (SONY VAIO FS-215B) just hangs/freezes (no oops, no MAGIC_SYSRQ) after writing "ACPI: Power Button (CM) [PWRB]" on screen

...
Machine check exception polling timer started.
apm: BIOS version 1.2 Flags 0x03 (Driver version 1.16ac)
audit: initializing netlink socket (disabled) audit(1178591695.734:1): initialized
highmem bounce pool size: 64 pages
VFS: Disk quotas dquot_6.5.1
Dquot-cache hash table entries: 1024 (order 0, 4096 bytes) io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
ACPI: AC Adapter [ADP1] (on-line)
ACPI: Battery Slot [BAT0] (battery present)
input: Power Button (FF) as /class/input/input0
ACPI: Power Button (FF) [PWRF]
input: Lid Switch as /class/input/input1
ACPI: Lid Switch [LID0]
input: Power Button (CM) as /class/input/input2
ACPI: Power Button (CM) [PWRB]

Normal boot sequence continues with following;

ACPI: CPU0 (power states: C1[C1] C2[C2])
ACPI: Processor [CPU0] (supports 8 throttling states)
ACPI Exception (processor_core-0783): AE_NOT_FOUND, Processor Device is not present [20070126]
ACPI: Thermal Zone [THRM] (98 C)
isapnp: Scanning for PnP cards...
Time: acpi_pm clocksource has been installed.
isapnp: No Plug & Play device found
Real Time Clock Driver v1.12ac
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing enabled Clocksource tsc unstable (delta = -490158796 ns)
floppy0: no floppy controllers found
RAMDISK driver initialized: 16 RAM disks of 16384K size 1024 blocksize
loop: loaded (max 8 devices)
...

System boots fine with hpet=disable and by the way, i tried the first version of this patchset without a problem (if i remembered correctly, it was just force detects the hpet but only enables for x86_64)

zangetsu ~ # lspci
00:00.0 Host bridge: Intel Corporation Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (rev 03)
00:02.0 VGA compatible controller: Intel Corporation Mobile 915GM/GMS/910GML Express Graphics Controller (rev 03)
00:02.1 Display controller: Intel Corporation Mobile 915GM/GMS/910GML Express Graphics Controller (rev 03)
00:1b.0 Audio device: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (rev 03)
00:1d.0 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (rev 03)
00:1d.1 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (rev 03)
00:1d.2 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (rev 03)
00:1d.3 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 (rev 03)
00:1d.7 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (rev 03)
00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev d3) 00:1f.0 ISA bridge: Intel Corporation 82801FBM (ICH6M) LPC Interface Bridge (rev 03)
00:1f.1 IDE interface: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (rev 03)
00:1f.3 SMBus: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller (rev 03)
06:03.0 CardBus bridge: Texas Instruments PCI7420 CardBus Controller 06:03.2 FireWire (IEEE 1394): Texas Instruments PCI7x20 1394a-2000 OHCI Two-Port PHY/Link-Layer Controller
06:03.3 Mass storage controller: Texas Instruments PCI7420/7620 Combo CardBus, 1394a-2000 OHCI and SD/MS-Pro Controller
06:04.0 Network controller: Intel Corporation PRO/Wireless 2200BG Network Connection (rev 05)
06:08.0 Ethernet controller: Intel Corporation 82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller Mobile (rev 03)

Cheers

Signature · 4 lines
S.Çağlar Onur <[email protected]>
http://cekirdek.pardus.org.tr/~caglar/

Linux is like living in a teepee. No Windows, no Gates and an Apache in house!
#2 lore raw
Quoted 134 lines

-----Original Message-----
From: S.Çağlar Onur [mailto:[email protected]]
Sent: Monday, May 07, 2007 4:48 PM
To: Pallipadi, Venkatesh
Cc: linux-kernel; Andrew Morton; Thomas Gleixner; Andi Kleen; Ingo Molnar; Chris Wright
Subject: Re: [PATCH 1/8] Restructuring hpet timer generic clock interfaces

Hi;

07 May 2007 Pts tarihinde, Venki Pallipadi şunları yazmıştı:

Quoted 8 lines

i386 HPET changes.

Patchset does the following changes to HPET support:
* Add HPET force detect to ICH chipsets, and detect the presence of HPET through PCI quirk.
* Enable HPET timer to function in standard interrupt delivery mode, against the current legacy replacement mode
* Enable HPET as a PER CPU time event, which will help in

laptops that

Quoted 3 lines

supports C3 and hence has unreliable LAPIC timer.

The changes enable processors to stay in idle longer, by

increasing the

Quoted 3 lines

average time spend in an idle state per call, by more than twice, on my dual core laptop. It reduces the number of interrupts on a totally idle system, compared to when I use PIT.

My machine (SONY VAIO FS-215B) just hangs/freezes (no oops, no MAGIC_SYSRQ)
after writing "ACPI: Power Button (CM) [PWRB]" on screen

...
Machine check exception polling timer started.
apm: BIOS version 1.2 Flags 0x03 (Driver version 1.16ac)
audit: initializing netlink socket (disabled) audit(1178591695.734:1): initialized
highmem bounce pool size: 64 pages
VFS: Disk quotas dquot_6.5.1
Dquot-cache hash table entries: 1024 (order 0, 4096 bytes) io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
ACPI: AC Adapter [ADP1] (on-line)
ACPI: Battery Slot [BAT0] (battery present)
input: Power Button (FF) as /class/input/input0
ACPI: Power Button (FF) [PWRF]
input: Lid Switch as /class/input/input1
ACPI: Lid Switch [LID0]
input: Power Button (CM) as /class/input/input2
ACPI: Power Button (CM) [PWRB]

Normal boot sequence continues with following;

ACPI: CPU0 (power states: C1[C1] C2[C2])
ACPI: Processor [CPU0] (supports 8 throttling states)
ACPI Exception (processor_core-0783): AE_NOT_FOUND, Processor Device is not
present [20070126]
ACPI: Thermal Zone [THRM] (98 C)
isapnp: Scanning for PnP cards...
Time: acpi_pm clocksource has been installed.
isapnp: No Plug & Play device found
Real Time Clock Driver v1.12ac
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing enabled
Clocksource tsc unstable (delta = -490158796 ns)
floppy0: no floppy controllers found
RAMDISK driver initialized: 16 RAM disks of 16384K size 1024 blocksize
loop: loaded (max 8 devices)
...

System boots fine with hpet=disable and by the way, i tried the first version
of this patchset without a problem (if i remembered correctly, it was just
force detects the hpet but only enables for x86_64)

zangetsu ~ # lspci
00:00.0 Host bridge: Intel Corporation Mobile 915GM/PM/GMS/910GML Express
Processor to DRAM Controller (rev 03)
00:02.0 VGA compatible controller: Intel Corporation Mobile 915GM/GMS/910GML
Express Graphics Controller (rev 03)
00:02.1 Display controller: Intel Corporation Mobile 915GM/GMS/910GML Express
Graphics Controller (rev 03)
00:1b.0 Audio device: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family)
High Definition Audio Controller (rev 03)
00:1d.0 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family)
USB UHCI #1 (rev 03)
00:1d.1 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family)
USB UHCI #2 (rev 03)
00:1d.2 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family)
USB UHCI #3 (rev 03)
00:1d.3 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family)
USB UHCI #4 (rev 03)
00:1d.7 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family)
USB2 EHCI Controller (rev 03)
00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev d3) 00:1f.0 ISA bridge: Intel Corporation 82801FBM (ICH6M) LPC Interface Bridge
(rev 03)
00:1f.1 IDE interface: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family)
IDE Controller (rev 03)
00:1f.3 SMBus: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus
Controller (rev 03)
06:03.0 CardBus bridge: Texas Instruments PCI7420 CardBus Controller 06:03.2 FireWire (IEEE 1394): Texas Instruments PCI7x20 1394a-2000 OHCI
Two-Port PHY/Link-Layer Controller
06:03.3 Mass storage controller: Texas Instruments PCI7420/7620 Combo CardBus,
1394a-2000 OHCI and SD/MS-Pro Controller
06:04.0 Network controller: Intel Corporation PRO/Wireless 2200BG Network
Connection (rev 05)
06:08.0 Ethernet controller: Intel Corporation 82562ET/EZ/GT/GZ - PRO/100 VE
(LOM) Ethernet Controller Mobile (rev 03)

Quoted 8 lines

Cheers

Signature · 5 lines
S.Çağlar Onur <[email protected]>
http://cekirdek.pardus.org.tr/~caglar/

Linux is like living in a teepee. No Windows, no Gates and an 
Apache in house!

Hmm. Looks like timer was somehow not set correctly.
Can you try only the first 5 patches in the patchset and leave out the last three and check whether it works.

Thanks,
Venki

#3 lore raw

08 May 2007 Sal tarihinde, Pallipadi, Venkatesh şunları yazmıştı:

Quoted 3 lines

Hmm. Looks like timer was somehow not set correctly.
Can you try only the first 5 patches in the patchset and leave out the last three and check whether it works.

Yep, first 5 patches works fine,

[caglar@zangetsu][~]> dmesg | grep hpet
hpet clocksource registered
hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0
hpet0: 3 64-bit timers, 14318180 Hz
hpet clockevent registered
Time: hpet clocksource has been installed.

[caglar@zangetsu][~]> cat /proc/timer_list
...
Tick Device: mode: 1
Clock Event Device: hpet

 max_delta_ns:   2147483647
 min_delta_ns:   3352
 mult:           61496110
 shift:          32
 mode:           3
 next_event:     9223372036854775807 nsecs

set_next_event: hpet_legacy_next_event
set_mode: hpet_legacy_set_mode
event_handler: tick_handle_oneshot_broadcast
tick_broadcast_mask: 00000001
tick_broadcast_oneshot_mask: 00000000
...

If you need more output/log etc. please just say :)

Cheers

Signature · 4 lines
S.Çağlar Onur <[email protected]>
http://cekirdek.pardus.org.tr/~caglar/

Linux is like living in a teepee. No Windows, no Gates and an Apache in house!
#4 lore raw
Quoted 11 lines

-----Original Message-----
From: S.Çağlar Onur [mailto:[email protected]]
Sent: Tuesday, May 08, 2007 2:08 PM
To: Pallipadi, Venkatesh
Cc: linux-kernel; Andrew Morton; Thomas Gleixner; Andi Kleen; Ingo Molnar; Chris Wright
Subject: Re: [PATCH 1/8] Restructuring hpet timer generic clock interfaces

Quoted 8 lines

08 May 2007 Sal tarihinde, Pallipadi, Venkatesh şunları yazmıştı:

Quoted 2 lines

Hmm. Looks like timer was somehow not set correctly. Can you try only the first 5 patches in the patchset and

leave out the last

Quoted 1 line

three and check whether it works.

Yep, first 5 patches works fine,

That's good news :-).

Can you send me the full dmesg with the 5 patches and also the config file you are using. Also, did you try these patches against 2.6.21-vanilla or recent git?

Thanks,
Venki

#5 lore raw

09 May 2007 Çar tarihinde, Pallipadi, Venkatesh şunları yazmıştı:

Quoted 5 lines

That's good news :-).

Can you send me the full dmesg with the 5 patches and also the config file you are using. Also, did you try these patches against 2.6.21-vanilla or recent git?

I'm trying these on top of 2.6.21.1 + CFS-v11 and with some other patches (bootsplash + apparmor + swap prefetch + your ondemand timer patch)

You can find config.gz and full dmesg at [1]

[1] http://cekirdek.pardus.org.tr/~caglar/hpet/

Signature · 4 lines
S.Çağlar Onur <[email protected]>
http://cekirdek.pardus.org.tr/~caglar/

Linux is like living in a teepee. No Windows, no Gates and an Apache in house!