OpenCloudOS-Kernel/include/linux/async_fork.h

169 lines
3.9 KiB
C

#ifndef _LINUX_ASYNC_FORK_H
#define _LINUX_ASYNC_FORK_H
#ifdef CONFIG_ASYNC_FORK
#define ASYNC_FORK_CANDIDATE 0
#define ASYNC_FORK_PENDING 1
#define ASYNC_FORK_FALLBACK 2
DECLARE_STATIC_KEY_FALSE(async_fork_enabled_key);
DECLARE_STATIC_KEY_FALSE(async_fork_staging_key);
void async_fork_mm_bind(struct mm_struct *oldmm, struct mm_struct *mm,
int err);
void async_fork_rest(struct mm_struct *mm);
void async_fork_fast_done(struct mm_struct *mm, int err);
int async_fork_prepare(struct mm_struct *oldmm, struct mm_struct *mm);
int __async_fork_fixup_pmd(struct vm_area_struct *mpnt, pmd_t *pmd,
unsigned long addr);
void __async_fork_fixup_vma(struct vm_area_struct *mpnt);
void __async_fork_madvise_vma(struct vm_area_struct *mpnt,
unsigned long start,
unsigned long end);
int __async_fork_fast(struct mm_struct *dst_mm, struct mm_struct *src_mm,
struct vm_area_struct *dst_vma,
struct vm_area_struct *src_vma);
void async_fork_fixup_vmas(struct mm_struct *mm);
static inline bool async_fork_enabled(void)
{
return static_branch_unlikely(&async_fork_enabled_key);
}
static inline bool async_fork_staging(void)
{
return static_branch_unlikely(&async_fork_staging_key);
}
static inline int
async_fork_fast(struct mm_struct *dst_mm, struct mm_struct *src_mm,
struct vm_area_struct *dst_vma,
struct vm_area_struct *src_vma)
{
return __copy_page_range(dst_mm, src_mm, dst_vma, src_vma,
__async_fork_fast);
}
static inline bool is_pmd_async_fork(pmd_t pmd)
{
if (is_swap_pmd(pmd) || pmd_trans_huge(pmd) || pmd_devmap(pmd))
return false;
return !pmd_none(pmd) && !pmd_write(pmd);
}
static inline bool is_async_fork_pending(struct mm_struct *mm)
{
return mm && test_bit(ASYNC_FORK_PENDING, &mm->async_fork_flags);
}
static inline bool is_async_fork_fallback(struct mm_struct *mm)
{
return mm && test_bit(ASYNC_FORK_FALLBACK, &mm->async_fork_flags);
}
static inline bool is_vma_async_fork(struct vm_area_struct *vma)
{
return !!vma->async_fork_vma;
}
static inline void async_fork_set_flags(struct mm_struct *mm, int flags)
{
set_bit(flags, &mm->async_fork_flags);
}
static inline void
async_fork_fixup_pmd(struct vm_area_struct *mpnt, pmd_t *pmd,
unsigned long addr)
{
if (async_fork_staging() && is_vma_async_fork(mpnt) &&
is_pmd_async_fork(*pmd))
__async_fork_fixup_pmd(mpnt, pmd, addr);
}
static inline void async_fork_fixup_vma(struct vm_area_struct *mpnt)
{
if (async_fork_staging() && is_vma_async_fork(mpnt))
__async_fork_fixup_vma(mpnt);
}
static inline void
async_fork_madvise_vma(struct vm_area_struct *mpnt, unsigned long start,
unsigned long end)
{
if (async_fork_staging() && is_vma_async_fork(mpnt))
__async_fork_madvise_vma(mpnt, start, end);
}
static inline struct mutex
*async_fork_vma_lock(struct vm_area_struct *vma)
{
return (void *)&vma->async_fork_lock;
}
#else
static inline bool async_fork_enabled(void)
{
return false;
}
static inline bool async_fork_staging(void)
{
return false;
}
static inline int
async_fork_fast(struct mm_struct *dst_mm, struct mm_struct *src_mm,
struct vm_area_struct *dst_vma,
struct vm_area_struct *src_vma)
{
return -EOPNOTSUPP;
}
static inline void
async_fork_mm_bind(struct mm_struct *oldmm, struct mm_struct *mm, int err)
{
}
static inline void async_fork_rest(struct mm_struct *mm)
{
}
static inline void async_fork_fast_done(struct mm_struct *mm, int err)
{
}
static inline bool is_pmd_async_fork(pmd_t pmd)
{
return false;
}
static inline void
async_fork_fixup_pmd(struct vm_area_struct *mpnt, pmd_t *pmd,
unsigned long addr)
{
}
static inline void async_fork_fixup_vma(struct vm_area_struct *mpnt)
{
}
static inline int
async_fork_prepare(struct mm_struct *oldmm, struct mm_struct *mm)
{
return 0;
}
static inline void
async_fork_madvise_vma(struct vm_area_struct *mpnt, unsigned long start,
unsigned long end)
{
}
static inline void async_fork_fixup_vmas(struct mm_struct *mm)
{
}
#endif /* CONFIG_ASYNC_FORK */
#endif /* _LINUX_ASYNC_FORK_H */