Why a “barrier()” is enough for disabling or enabling the preemption?

Nan Xiao xiaonan830818 at gmail.com
Mon Nov 23 20:11:11 EST 2015


Hi all,

Below is the preemption disable/enable code:

#ifdef CONFIG_PREEMPT_COUNT

#define preempt_disable() \
do { \
        inc_preempt_count(); \
        barrier(); \
} while (0)

......
#define preempt_enable() \
do { \
        preempt_enable_no_resched(); \
        barrier(); \
preempt_check_resched(); \
} while (0)

#else /* !CONFIG_PREEMPT_COUNT */

/*
 * Even if we don't have any preemption, we need preempt disable/enable
 * to be barriers, so that we don't have things like get_user/put_user
 * that can cause faults and scheduling migrate into our preempt-protected
 * region.
 */
#define preempt_disable() barrier()
......
#define preempt_enable() barrier()

......

#endif /* CONFIG_PREEMPT_COUNT */

And I have a question about it:If the CONFIG_PREEMPT_COUNT is OFF,
while CONFIG_PREEMPT is ON,
why only a barrier()can disable/enable preemption? What is the magic
behind it? Or On SMP, the
CONFIG_PREEMPT_COUNT should always be ON?

BTW, I also post this issue on
SO(http://stackoverflow.com/questions/33864903/why-a-barrier-is-enough-for-disabling-or-enabling-the-preemption),
but can't receive clear answers.

Thanks in advance!

Best Regards
Nan Xiao



More information about the Kernelnewbies mailing list