Additional compiler barrier required in sched_preempt_enable_no_resched?

From: Vikram Mulukutla
Date: Fri May 13 2016 - 02:40:21 EST


Hi,

I came across a piece of engineering code that looked like:

preempt_disable();
/* --cut, lots of code-- */
preempt_enable_no_resched();
put_user()
preempt_disable();

(If you wish to seriously question the usage of the preempt API in this manner, I unfortunately have no comment since I didn't write the code.)

This particular block of code was causing lockups and crashes on a certain ARM64 device. The generated assembly revealed that the compiler was simply optimizing out the increment and decrement of the preempt count, allowing put_user to run without preemption enabled, causing all sorts of badness. Since put_user doesn't actually access the preempt count and translates to just a few instructions without any branching, I suppose that the compiler figured it was OK to optimize.

The immediate solution is to add a compiler barrier to the code above, but should sched_preempt_enable_no_resched have an additional compiler barrier after (has one before already) the preempt-count decrement to prevent this sort of thing?

Thanks,
Vikram

--
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project