[RFC/PATCH 5/7] ARM: Move get_thread_info macro definition to <asm/assembler.h>
Russell King - ARM Linux
linux at arm.linux.org.uk
Thu Oct 13 10:34:20 EDT 2011
On Wed, Oct 12, 2011 at 02:04:33AM -0400, gdavis at mvista.com wrote:
> diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
> index 78397d0..eaf4939 100644
> --- a/arch/arm/include/asm/assembler.h
> +++ b/arch/arm/include/asm/assembler.h
> @@ -36,6 +36,20 @@
> .endm
> #endif /* !CONFIG_THUMB2_KERNEL */
>
> + .macro preempt_disable, tsk, cnt
> + get_thread_info \tsk
> + ldr \cnt, [\tsk, #TI_PREEMPT]
> + add \cnt, \cnt, #1
> + str \cnt, [\tsk, #TI_PREEMPT]
> + .endm
> +
> + .macro preempt_enable, tsk, cnt
> + get_thread_info \tsk
> + ldr \cnt, [\tsk, #TI_PREEMPT]
> + sub \cnt, \cnt, #1
> + str \cnt, [\tsk, #TI_PREEMPT]
> + .endm
> +
> /*
> * Endian independent macros for shifting bytes within registers.
> */
>
>
> Not as efficient as it could be but I imagine the macros could
> be written to support optional load of \tsk and/or optional \tmp
> parameters to cover other common cases.
It's actually not that simple either: if you disable preemption, then you
need to check for a preempt event after re-enabling preemption. The
C level code does this:
#define preempt_enable_no_resched() \
do { \
barrier(); \
dec_preempt_count(); \
} while (0)
#define preempt_check_resched() \
do { \
if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \
preempt_schedule(); \
} while (0)
#define preempt_enable() \
do { \
preempt_enable_no_resched(); \
barrier(); \
preempt_check_resched(); \
} while (0)
Note that preempt_schedule() will check the preempt count itself and
return immediately if non-zero or irqs are disabled.
More information about the linux-arm-kernel
mailing list