用某个bit表示特定属性通常有两种方式:
1.指定某个特定的value
#define _PAGE_VALID 0x0001
0bit 为 1 时表示此时的page entry是有效的
用法如下,此时这种用法不能保证是原子操作。
if (pte_val(*ptep) & _PAGE_VALID) {
/*page valid*/
} else {
/*page unvalid*/
}
2.也可以是指定某个特定的bit
#define _PAGE_VALID_BIT 0
0bit用来表示page entry是否有效,具体的 0 有效还是 1 有效需要自己清楚。
针对第二种用法,kernel中提供了一组内联函数,通过这组函数可以保证该操作是原子操作。
static inline void set_bit(int nr, volatile unsigned long *addr);
static inline void clear_bit(int nr, volatile unsigned long *addr);
static inline void change_bit(int nr, volatile unsigned long *addr);
static inline int test_and_set_bit(int nr, volatile unsigned long *addr);
static inline int test_and_clear_bit(int nr, volatile unsigned long *addr);
static inline int test_and_change_bit(int nr, volatile unsigned long *addr);
上述两种用法关系是
(_PAGE_VALID)、(0x01 << _PAGE_VALID_BIT) 意思是一样的
BUG出现原因是:
//错误示范!!!
if (pte_val(*ptep) & _PAGE_VALID_BIT) {
/*page valid*/
} else {
/*page unvalid*/
}
一个value一个bit offset做与操作,得出了不伦不类的结果。
如何避免:
1.定义bit offset时候建议以 _BIT 结尾
2.定义value时候数值为 0x0001,定义bit offset时候为1,2,3 数字
最后,check code时候尽量避免思维惯性,想象CPU的执行过程单步执行,思维惯性往往就是想当然。