27.03.2014 Views

SEKE 2012 Proceedings - Knowledge Systems Institute

SEKE 2012 Proceedings - Knowledge Systems Institute

SEKE 2012 Proceedings - Knowledge Systems Institute

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

1<br />

2<br />

3<br />

4<br />

5<br />

6<br />

7<br />

8<br />

9<br />

10<br />

11<br />

12<br />

13<br />

14<br />

15<br />

16<br />

17<br />

18<br />

19<br />

20<br />

21<br />

22<br />

23<br />

24<br />

25<br />

26<br />

27<br />

28<br />

29<br />

1<br />

2<br />

3<br />

4<br />

5<br />

6<br />

7<br />

8<br />

9<br />

10<br />

11<br />

12<br />

13<br />

14<br />

15<br />

static int lapic_suspend(struct sys_device *dev) {<br />

unsigned long flags;<br />

int maxlvt;<br />

if (!apic_pm_state.active)<br />

return 0;<br />

maxlvt = lapic_get_maxlvt();<br />

apic_pm_state.apic_id = apic_read(APIC_ID);<br />

apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI);<br />

apic_pm_state.apic_ldr = apic_read(APIC_LDR);<br />

apic_pm_state.apic_dfr = apic_read(APIC_DFR);<br />

apic_pm_state.apic_spiv = apic_read(APIC_SPIV);<br />

apic_pm_state.apic_lvtt = apic_read(APIC_LVTT);<br />

if (maxlvt >= 4)<br />

apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC);<br />

apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0);<br />

apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1);<br />

apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR);<br />

apic_pm_state.apic_tmict = apic_read(APIC_TMICT);<br />

apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);<br />

#ifdef CONFIG_X86_THERMAL_VECTOR<br />

if (maxlvt >= 5)<br />

apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);<br />

#endif<br />

local_irq_save(flags);<br />

disable_local_APIC();<br />

if (intr_remapping_enabled)<br />

disable_intr_remapping();<br />

local_irq_restore(flags);<br />

return 0; }<br />

Figure 4. Lapic suspend<br />

void disable_local_APIC(void) {<br />

unsigned int value;<br />

if (!x2apic_mode && !apic_phys)<br />

return;<br />

clear_local_APIC();<br />

value = apic_read(APIC_SPIV);<br />

value &= ~APIC_SPIV_APIC_ENABLED;<br />

apic_write(APIC_SPIV, value);<br />

#ifdef CONFIG_X86_32<br />

if (enabled_via_apicbase) {<br />

unsigned int l, h;<br />

rdmsr(MSR_IA32_APICBASE, l, h);<br />

l &= ~MSR_IA32_APICBASE_ENABLE;<br />

wrmsr(MSR_IA32_APICBASE, l, h); }<br />

#endif }<br />

Figure 5. Disable Local APIC<br />

It is also n ecessary to include a system call between steps<br />

10 and 11 to enable clock interrupts again on the chosen CPU;<br />

otherwise it would become inaccessible to oth er processes<br />

after the execution of the experiment. Figure 6 shows the<br />

necessary code to re-enable clock ticks.<br />

1<br />

2<br />

3<br />

4<br />

5<br />

6<br />

7<br />

8<br />

9<br />

10<br />

11<br />

12<br />

13<br />

14<br />

15<br />

16<br />

17<br />

static int lapic_resume(struct sys_device *dev) {<br />

unsigned int l, h;<br />

unsigned long flags;<br />

int maxlvt;<br />

int ret = 0;<br />

struct IO_APIC_route_entry **ioapic_entries = NULL;<br />

if (!apic_pm_state.active)<br />

return 0;<br />

local_irq_save(flags);<br />

if (intr_remapping_enabled) {<br />

ioapic_entries = alloc_ioapic_entries();<br />

if (!ioapic_entries) {<br />

WARN(1, "Alloc ioapiclapic resume failed.");<br />

ret = -ENOMEM;<br />

goto restore; }<br />

ret = save_IO_APIC_setup(ioapic_entries);<br />

if (ret) {<br />

18<br />

19<br />

20<br />

21<br />

22<br />

23<br />

24<br />

25<br />

26<br />

27<br />

28<br />

29<br />

30<br />

31<br />

32<br />

33<br />

34<br />

35<br />

36<br />

37<br />

38<br />

39<br />

40<br />

41<br />

42<br />

43<br />

44<br />

45<br />

46<br />

47<br />

48<br />

49<br />

50<br />

51<br />

52<br />

WARN(1, "Saving IO-APIC state failed: %d\n", ret);<br />

free_ioapic_entries(ioapic_entries);<br />

goto restore; }<br />

mask_IO_APIC_setup(ioapic_entries);<br />

mask_8259A();<br />

}<br />

if (x2apic_mode)<br />

enable_x2apic();<br />

else {<br />

rdmsr(MSR_IA32_APICBASE, l, h);<br />

l &= ~MSR_IA32_APICBASE_BASE;<br />

l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr;<br />

wrmsr(MSR_IA32_APICBASE, l, h); }<br />

maxlvt = lapic_get_maxlvt();<br />

apic_write(APIC_ID, apic_pm_state.apic_id);<br />

apic_write(APIC_DFR, apic_pm_state.apic_dfr);<br />

apic_write(APIC_LDR, apic_pm_state.apic_ldr);<br />

...<br />

apic_write(APIC_TDCR, apic_pm_state.apic_tdcr);<br />

apic_write(APIC_TMICT, apic_pm_state.apic_tmict);<br />

apic_write(APIC_ESR, 0);<br />

apic_read(APIC_ESR);<br />

apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr);<br />

apic_write(APIC_ESR, 0);<br />

apic_read(APIC_ESR);<br />

if (intr_remapping_enabled) {<br />

reenable_intr_remapping(x2apic_mode);<br />

unmask_8259A();<br />

restore_IO_APIC_setup(ioapic_entries);<br />

free_ioapic_entries(ioapic_entries); }<br />

restore:<br />

local_irq_restore(flags);<br />

return ret;<br />

}<br />

Figure 6. Fragment of lapic_resume<br />

The resulted trace af ter running the instrumented system<br />

with clock tick disabling should be compared with the trace<br />

where clock ticks were not disabled, in order to see if the<br />

filtering process th at selected the considered function(s) to<br />

implement clock tick handling was correct. In order to confirm<br />

the correction, that function(s) should not be present in the<br />

new trace.<br />

Another adopted validation step was to verifying the<br />

number of calls to the function(s) that are supposed to be the<br />

one(s) that handle clock ticks using the SystemTap script<br />

shown in Figure 7. A complementary SystemTap script shown<br />

in Figure 8 calculates the duration of the execution of these<br />

respective functions that can indicate some measure of the OS<br />

jitter.<br />

1<br />

2<br />

3<br />

4<br />

5<br />

6<br />

7<br />

8<br />

9<br />

10<br />

11<br />

12<br />

13<br />

14<br />

15<br />

global var1<br />

probe begin {<br />

var1[0]=0; var1[1]=0; var1[2]=0; var1[3]=0; }<br />

probe kernel.function("").call {<br />

j=cpu();<br />

var1[j]=var1[j]+1;<br />

}<br />

probe end {<br />

printf("ID: %d Count: %d\n",0, var1[0]);<br />

printf("ID: %d Count: %d\n",1, var1[1]);<br />

printf("ID: %d Count: %d\n",2, var1[2]);<br />

printf("ID: %d Count: %d\n",3, var1[3]);<br />

}<br />

Figure 7. Script to verify the number of clock tick handling<br />

177

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!