> +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL > +static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, > + unsigned long addr, pte_t *ptep, int full) > +{ > + pte_t orig_pte = __ptep_get(ptep); > + > + if (!pte_valid_cont(orig_pte) || !full) { > + contpte_try_unfold(mm, addr, ptep, orig_pte); > + return __ptep_get_and_clear(mm, addr, ptep); > + } else > + return contpte_ptep_get_and_clear_full(mm, addr, ptep); > +} > + Hi Ryan, I feel quite hard to understand the code. when !pte_valid_cont(orig_pte), we will call contpte_try_unfold(mm, addr, ptep, orig_pte); but in contpte_try_unfold(), we call unfold only if pte_valid_cont() is true: static inline void contpte_try_unfold(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) { if (contpte_is_enabled(mm) && pte_valid_cont(pte)) __contpte_try_unfold(mm, addr, ptep, pte); } so do you mean the below? if (!pte_valid_cont(orig_pte)) return __ptep_get_and_clear(mm, addr, ptep); if (!full) { contpte_try_unfold(mm, addr, ptep, orig_pte); return __ptep_get_and_clear(mm, addr, ptep); } else { return contpte_ptep_get_and_clear_full(mm, addr, ptep); } Thanks Barry