new_TSC_based_delay_tsc()
PATCH 1/1 new_TSC_based_delay_tsc()
Hi all,
This is a patch based on the Ingo's idea/patch to track delay_tsc() migration to another cpu by comparing smp_processor_id(). It is against kernel-2.6.24-rc3.
What is different:
1. Using unsigned (instead of long) to unify for i386/x86_64.
2. Minimal preempt_disable/enable() critical sections (more room for preemption)
3. some statements have been rearranged, to account for possible under/overflow of left/TSC
Tested on both: 32/64 bit SMP PREEMPT kernel-2.6.24-rc3
Hope it is correct. Comments, please.
=========================================
arch/x86/lib/delay_32.c +29 -6
@@ -38,18 +38,41 @@ :"0" (loops)); } -/* TSC based delay: */ +/* TSC based delay: +* +* We are careful about preemption as TSC's are per-CPU. +*/ static void delay_tsc (unsigned long loops) { -unsigned long bclock, now; +unsigned prev, now; +unsigned left = loops; +unsigned prev_cpu, cpu; + +preempt_disable (); +rdtscl (prev); + prev_cpu =smp_processor_id (); +preempt_enable (); + now = prev; -preempt_disable ();/* TSC's are per-cpu */ -rdtscl (bclock);do {rep_nop (); + + left -= now - prev; + prev = now; + +preempt_disable ();rdtscl (now); - }while ((now-bclock) < loops); -preempt_enable (); + cpu =smp_processor_id (); +preempt_enable (); + +if (prev_cpu != cpu){ +/* +* We have migrated, we skip this small amount of time: +*/ + prev = now; + prev_cpu = cpu; + } + }while ((now-prev) < left); }/*
arch/x86/lib/delay_64.c +30 -6
@@ -26,18 +26,42 @@return 0 ; } +/* TSC based delay: +* +* We are careful about preemption as TSC's are per-CPU. +*/ void __delay (unsigned long loops) { -unsigned bclock, now; +unsigned prev, now; +unsigned left = loops; +unsigned prev_cpu, cpu; + +preempt_disable (); +rdtscl (prev); + prev_cpu =smp_processor_id (); +preempt_enable (); + now = prev; -preempt_disable ();/* TSC's are pre-cpu */ -rdtscl (bclock);do { -rep_nop (); +rep_nop (); + + left -= now - prev; + prev = now; + +preempt_disable ();rdtscl (now); + cpu =smp_processor_id (); +preempt_enable (); + +if (prev_cpu != cpu){ +/* +* We have migrated, we skip this small amount of time: +*/ + prev = now; + prev_cpu = cpu; + } } -while ((now-bclock) < loops); -preempt_enable (); +while ((now-prev) < left); }EXPORT_SYMBOL (__delay);
Re: [PATCH] new TSC based delay_tsc()
Quoted 13 lines · Marin Mitov
Hi all,
This is a patch based on the Ingo's idea/patch to track
delay_tsc()migration to another cpu by comparingsmp_processor_id(). It is against kernel-2.6.24-rc3.What is different:
1. Using unsigned (instead of long) to unify for i386/x86_64.
2. Minimal preempt_disable/enable() critical sections (more room for preemption)
3. some statements have been rearranged, to account for possible under/overflow of left/TSC
Quoted 3 lines
Tested on both: 32/64 bit SMP PREEMPT kernel-2.6.24-rc3
Hope it is correct. Comments, please.
thanks! The changes look certainly good to me.
Quoted 1 line
Signed-off-by Marin Mitov <[email protected]>
Ingo