Skip to content

Commit

Permalink
52th
Browse files Browse the repository at this point in the history
  • Loading branch information
prifri committed May 21, 2022
1 parent 77a18ef commit bfaeb8d
Show file tree
Hide file tree
Showing 15 changed files with 531 additions and 2 deletions.
37 changes: 37 additions & 0 deletions arch/arm64/kernel/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,43 @@
#include <asm/cpufeature.h>
#include <asm/syscall.h>

/*
* IAMROOT, 2022.05.21:
* - arm64 sys_mmap
*
* ex) user에서 malloc을 사용했을때 strace 사용결과
* sh) strace ./test
* == strace
* mmap(NULL, 1000001536, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb4af7ee000
*
* == smaps log(heap 측 부분)
* 7fb4af7ee000-7fb4eb19b000 rw-p 00000000 00:00 0
* Size: 976564 kB
* KernelPageSize: 4 kB
* MMUPageSize: 4 kB
* Rss: 976564 kB
* Pss: 976564 kB
* Shared_Clean: 0 kB
* Shared_Dirty: 0 kB
* Private_Clean: 0 kB
* Private_Dirty: 976564 kB
* Referenced: 976564 kB
* Anonymous: 976564 kB
* LazyFree: 0 kB
* AnonHugePages: 0 kB
* ShmemPmdMapped: 0 kB
* FilePmdMapped: 0 kB
* Shared_Hugetlb: 0 kB
* Private_Hugetlb: 0 kB
* Swap: 0 kB
* SwapPss: 0 kB
* Locked: 0 kB
* THPeligible: 0
* VmFlags: rd wr mr(may read) mw(may write) me(may execute) ac sd
*
* read, write 권한이 있는 vma라는것을 알수있다.
* malloc을 호출하면 항상 위와같은 prot, flag를 사용한다.
*/
SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
unsigned long, prot, unsigned long, flags,
unsigned long, fd, unsigned long, off)
Expand Down
5 changes: 5 additions & 0 deletions include/asm-generic/tlb.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,11 @@ static inline void tlb_start_vma(struct mmu_gather *tlb, struct vm_area_struct *
#endif

#ifndef tlb_end_vma

/*
* IAMROOT, 2022.05.21:
* - tlb flush
*/
static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
{
if (tlb->fullmm)
Expand Down
13 changes: 13 additions & 0 deletions include/linux/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -2842,6 +2842,11 @@ extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned lon
* Returns: The first VMA within the provided range, %NULL otherwise. Assumes
* start_addr < end_addr.
*/

/*
* IAMROOT, 2022.05.21:
* - 겹치는 vma를 찾아온다.
*/
static inline
struct vm_area_struct *find_vma_intersection(struct mm_struct *mm,
unsigned long start_addr,
Expand Down Expand Up @@ -2872,6 +2877,10 @@ struct vm_area_struct *vma_lookup(struct mm_struct *mm, unsigned long addr)
return vma;
}

/*
* IAMROOT, 2022.05.21:
* - @vma가 아래로 내려가는 stack인 경우 보정.
*/
static inline unsigned long vm_start_gap(struct vm_area_struct *vma)
{
unsigned long vm_start = vma->vm_start;
Expand All @@ -2884,6 +2893,10 @@ static inline unsigned long vm_start_gap(struct vm_area_struct *vma)
return vm_start;
}

/*
* IAMROOT, 2022.05.21:
* - @vma가 위로 올라가는 stack인 경우 보정.
*/
static inline unsigned long vm_end_gap(struct vm_area_struct *vma)
{
unsigned long vm_end = vma->vm_end;
Expand Down
12 changes: 12 additions & 0 deletions include/linux/mm_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,13 @@ struct vm_area_struct {
* VMAs below us in the VMA rbtree and its ->vm_prev. This helps
* get_unmapped_area find a free area of the right size.
*/
/*
* IAMROOT, 2022.05.21:
* - 이 VMA의 왼쪽에 있는 최대 사용 가능한 메모리 간격(바이트)입니다.
* 이 VMA와 vma->vm_prev 사이 또는 VMArbtree에서 아래 VMA 중 하나와
* 해당 ->vm_prev 사이입니다. 이렇게 하면 get_unmapped_area가 올바른
* 크기의 빈 영역을 찾을 수 있습니다.
*/
unsigned long rb_subtree_gap;

/* Second cache line starts here. */
Expand Down Expand Up @@ -594,6 +601,11 @@ struct mm_struct {
unsigned long total_vm; /* Total pages mapped */
unsigned long locked_vm; /* Pages that have PG_mlocked set */
atomic64_t pinned_vm; /* Refcount permanently increased */
/*
* IAMROOT, 2022.05.21:
* - data공간이라 하면 주석과 같이 not stack, not shared를 의미한다.
* (is_data_mapping() 참고)
*/
unsigned long data_vm; /* VM_WRITE & ~VM_SHARED & ~VM_STACK */
unsigned long exec_vm; /* VM_EXEC & ~VM_WRITE & ~VM_STACK */
unsigned long stack_vm; /* VM_STACK */
Expand Down
22 changes: 22 additions & 0 deletions include/linux/mman.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ static inline bool arch_validate_flags(unsigned long flags)
* but this version is faster.
* ("bit1" and "bit2" must be single bits)
*/
/*
* IAMROOT, 2022.05.21:
* - bit1이 있으면 bit2 return 이라는뜻.
*/
#define _calc_vm_trans(x, bit1, bit2) \
((!(bit1) || !(bit2)) ? 0 : \
((bit1) <= (bit2) ? ((x) & (bit1)) * ((bit2) / (bit1)) \
Expand All @@ -138,6 +142,16 @@ static inline bool arch_validate_flags(unsigned long flags)
/*
* Combine the mmap "prot" argument into "vm_flags" used internally.
*/
/*
* IAMROOT, 2022.05.21:
* - prot flag를 vm flag로 변환하고 arch 에 따른 flag 추가가 있으면
* 추가 한다.
* - PROT_READ -> VM_READ
* PROT_WRITE -> VM_WRITE
* PROT_EXEC -> VM_EXEC
* PROT_BTI -> VM_ARM64_BTI
* PROT_MTE -> VM_MTE
*/
static inline unsigned long
calc_vm_prot_bits(unsigned long prot, unsigned long pkey)
{
Expand All @@ -150,6 +164,14 @@ calc_vm_prot_bits(unsigned long prot, unsigned long pkey)
/*
* Combine the mmap "flags" argument into "vm_flags" used internally.
*/
/*
* IAMROOT, 2022.05.21:
* - map flags를 vm flags로 변환한다.
* - MAP_GROWSDOWN -> VM_GROWSDOWN
* MAP_LOCKED -> VM_LOCKED
* MAP_SYNC -> VM_SYNC
* MAP_ANONYMOUS -> VM_MTE_ALLOWED
*/
static inline unsigned long
calc_vm_flag_bits(unsigned long flags)
{
Expand Down
4 changes: 4 additions & 0 deletions include/linux/sched/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,10 @@ static inline unsigned long task_rlimit_max(const struct task_struct *task,
return READ_ONCE(task->signal->rlim[limit].rlim_max);
}

/*
* IAMROOT, 2022.05.21:
* - 해당 task가 @limit에 해당하는 제한 값을 읽어온다.
*/
static inline unsigned long rlimit(unsigned int limit)
{
return task_rlimit(current, limit);
Expand Down
15 changes: 15 additions & 0 deletions include/uapi/asm-generic/mman-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,27 @@

/* 0x01 - 0x03 are defined in linux/mman.h */
#define MAP_TYPE 0x0f /* Mask for type of mapping */

/*
* IAMROOT, 2022.05.21:
* - 가상공간의 특정영역에 고정시키고 싶을때 사용한다.
*/
#define MAP_FIXED 0x10 /* Interpret addr exactly */
#define MAP_ANONYMOUS 0x20 /* don't use a file */

/* 0x0100 - 0x4000 flags are defined in asm-generic/mman.h */

/*
* IAMROOT, 2022.05.21:
* - mapping을 바로 하고싶을때 사용한다.
*/
#define MAP_POPULATE 0x008000 /* populate (prefault) pagetables */
#define MAP_NONBLOCK 0x010000 /* do not block on IO */

/*
* IAMROOT, 2022.05.21:
* - user stack만들때 brk를 호출하거나 MAP_STACK을 사용해서 sys_mmap을 호출에서 사용하게 될것이다.
*/
#define MAP_STACK 0x020000 /* give out an address that is best suited for process/thread stacks */
#define MAP_HUGETLB 0x040000 /* create a huge page mapping */
#define MAP_SYNC 0x080000 /* perform synchronous page faults for the mapping */
Expand Down
4 changes: 4 additions & 0 deletions include/uapi/asm-generic/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
* then it defines them prior including asm-generic/resource.h. )
*/

/*
* IAMROOT, 2022.05.21:
* - resource 제한에 대한것들.
*/
#define RLIMIT_CPU 0 /* CPU time in sec */
#define RLIMIT_FSIZE 1 /* Maximum filesize */
#define RLIMIT_DATA 2 /* max data size */
Expand Down
5 changes: 5 additions & 0 deletions mm/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,11 @@ static inline bool is_stack_mapping(vm_flags_t flags)
/*
* Data area - private, writable, not stack
*/
/*
* IAMROOT, 2022.05.21:
* stack을 제외한 data 공간.
* Data area - private, writable, not stack
*/
static inline bool is_data_mapping(vm_flags_t flags)
{
return (flags & (VM_WRITE | VM_SHARED | VM_STACK)) == VM_WRITE;
Expand Down
44 changes: 43 additions & 1 deletion mm/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -1539,6 +1539,10 @@ static inline unsigned long zap_p4d_range(struct mmu_gather *tlb,
return addr;
}

/*
* IAMROOT, 2022.05.21:
* - 해당 영역의 정규 mapping을 unmap
*/
void unmap_page_range(struct mmu_gather *tlb,
struct vm_area_struct *vma,
unsigned long addr, unsigned long end,
Expand All @@ -1556,10 +1560,17 @@ void unmap_page_range(struct mmu_gather *tlb,
continue;
next = zap_p4d_range(tlb, vma, pgd, addr, next, details);
} while (pgd++, addr = next, addr != end);
/*
* IAMROOT, 2022.05.21:
* - @vma에 대한 tlb flush
*/
tlb_end_vma(tlb, vma);
}


/*
* IAMROOT, 2022.05.21:
* - @vma unmmap
*/
static void unmap_single_vma(struct mmu_gather *tlb,
struct vm_area_struct *vma, unsigned long start_addr,
unsigned long end_addr,
Expand Down Expand Up @@ -1621,6 +1632,33 @@ static void unmap_single_vma(struct mmu_gather *tlb,
* ensure that any thus-far unmapped pages are flushed before unmap_vmas()
* drops the lock and schedules.
*/

/*
* IAMROOT, 2022.05.21:
*
* ^ ---- vm_end
* | <- vma4
* | --- end
* | ^ <- vma3->next = vma4
* v ---- vm_start |
* |
* ... ..
*
* ^ ---- vm_end |
* | |
* | | <- vma2->next = vma3
* v ---- vm_start |
* |
* ... ..
* |
* ^ ---- vm_end |
* | v <- vma->next = vma2
* | --- start
* | <-- prev
* v ---- vm_start
*
* vma부터 ~ vma4까지 unmap될것이다.(unmap_vmas())
*/
void unmap_vmas(struct mmu_gather *tlb,
struct vm_area_struct *vma, unsigned long start_addr,
unsigned long end_addr)
Expand Down Expand Up @@ -3717,6 +3755,10 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
* but allow concurrent faults), and pte mapped but not yet locked.
* We return with mmap_lock still held, but pte unmapped and unlocked.
*/
/*
* IAMROOT, 2022.05.21:
* - anon page fault시 이 함수로 진입하게 될것이다.
*/
static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
{
struct vm_area_struct *vma = vmf->vma;
Expand Down
16 changes: 16 additions & 0 deletions mm/mempolicy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1840,6 +1840,10 @@ nodemask_t *policy_nodemask(gfp_t gfp, struct mempolicy *policy)
* policy_node() is always coupled with policy_nodemask(), which
* secures the nodemask limit for 'bind' and 'prefer-many' policy.
*/
/*
* IAMROOT, 2022.05.21:
* - @policy->mode 가 MPOL_PREFERRED인 경우 first node를 return한다.
*/
static int policy_node(gfp_t gfp, struct mempolicy *policy, int nd)
{
if (policy->mode == MPOL_PREFERRED) {
Expand Down Expand Up @@ -2193,6 +2197,14 @@ static struct page *alloc_pages_preferred_many(gfp_t gfp, unsigned int order,
*
* Return: The page on success or NULL if allocation fails.
*/
/*
* IAMROOT, 2022.05.21:
* - numa Policy는 주로 app을 위한 정책이다. policy에 따라 alloc_pages를 호출한다.
*
* ---
* - kernel같은 경우은 local이 preferred 인 개념이되고(나머지는 cost순),
* app같은 경우엔 사용자가 설정한 node policy에 따르게 된다.
*/
struct page *alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma,
unsigned long addr, int node, bool hugepage)
{
Expand All @@ -2218,6 +2230,10 @@ struct page *alloc_pages_vma(gfp_t gfp, int order, struct vm_area_struct *vma,
goto out;
}

/*
* IAMROOT, 2022.05.21:
* - PASS
*/
if (unlikely(IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && hugepage)) {
int hpage_node = node;

Expand Down
Loading

0 comments on commit bfaeb8d

Please sign in to comment.