|
@@ -16,6 +16,7 @@
|
|
|
#include <linux/compiler.h>
|
|
|
#include <linux/types.h>
|
|
|
#include <asm/byteorder.h>
|
|
|
+#include <asm/system.h>
|
|
|
|
|
|
/* this is used only to give gcc a clue about good code generation */
|
|
|
union cnt32_to_63 {
|
|
@@ -53,11 +54,19 @@ union cnt32_to_63 {
|
|
|
* needed increment. And any race in updating the value in memory is harmless
|
|
|
* as the same value would simply be stored more than once.
|
|
|
*
|
|
|
- * The only restriction for the algorithm to work properly is that this
|
|
|
- * code must be executed at least once per each half period of the 32-bit
|
|
|
- * counter to properly update the state bit in memory. This is usually not a
|
|
|
- * problem in practice, but if it is then a kernel timer could be scheduled
|
|
|
- * to manage for this code to be executed often enough.
|
|
|
+ * The restrictions for the algorithm to work properly are:
|
|
|
+ *
|
|
|
+ * 1) this code must be called at least once per each half period of the
|
|
|
+ * 32-bit counter;
|
|
|
+ *
|
|
|
+ * 2) this code must not be preempted for a duration longer than the
|
|
|
+ * 32-bit counter half period minus the longest period between two
|
|
|
+ * calls to this code.
|
|
|
+ *
|
|
|
+ * Those requirements ensure proper update to the state bit in memory.
|
|
|
+ * This is usually not a problem in practice, but if it is then a kernel
|
|
|
+ * timer should be scheduled to manage for this code to be executed often
|
|
|
+ * enough.
|
|
|
*
|
|
|
* Note that the top bit (bit 63) in the returned value should be considered
|
|
|
* as garbage. It is not cleared here because callers are likely to use a
|
|
@@ -68,9 +77,10 @@ union cnt32_to_63 {
|
|
|
*/
|
|
|
#define cnt32_to_63(cnt_lo) \
|
|
|
({ \
|
|
|
- static volatile u32 __m_cnt_hi; \
|
|
|
+ static u32 __m_cnt_hi; \
|
|
|
union cnt32_to_63 __x; \
|
|
|
__x.hi = __m_cnt_hi; \
|
|
|
+ smp_rmb(); \
|
|
|
__x.lo = (cnt_lo); \
|
|
|
if (unlikely((s32)(__x.hi ^ __x.lo) < 0)) \
|
|
|
__m_cnt_hi = __x.hi = (__x.hi ^ 0x80000000) + (__x.hi >> 31); \
|