[커널 18차] 51주차
2022.05.14 22:41
git : https://github.com/iamroot18/5.10/commit/19dcf5d089aa06693b35aff049da46f89d5ca3e5
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 3ca2e80a4e2e..f22792b36e22 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -673,6 +673,18 @@ static const struct file_operations proc_lstats_operations = {
* oom_score = 666 + 666 + 333 = 1665
* (oom_score_adj값으로부터 사용자가 전체 memory의 100%에 대한 oom 점수
* 보정값을 넣은것을 알수있다.)
+ *
+ * ex) A task가 빨리 죽이고 싶을때, 전체 memory는 1GB.
+ *
+ * 예를들어 A task는 30%(300MB)를 쓰고 있고
+ * B task가 전체 memory의 70%(700MB)상황에서 oom이 발생했다.
+ * 이 상황에서 B task를 안죽일려면 B와 A 사용량의 차이 이상(400MB+. 즉 40.0%이상)
+ * 에 한 oom_score_adj값을 A의 oom_score_adj에 넣어야되며,
+ * 이값을 400이상이 될것이다.
+ *
+ * oom_score_adj memory사용량 oom_score
+ * A 410 300MBs 666 + 6.66*41.0 + 666*0.3 = 1161
+ * B 0 700MB 666 + 0 + 666*0.7 = 1132
*/
static int proc_oom_score(struct seq_file *m, struct pid_namespace *ns,
struct pid *pid, struct task_struct *task)
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 64ba87ee72fc..3fd68654c4a2 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -790,6 +790,12 @@ static inline struct page *alloc_pages(gfp_t gfp_mask, unsigned int order)
alloc_pages(gfp_mask, order)
#endif
#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - gfp_mask : GFP_HIGHUSER_MOVABLE
+ * user app용 vma에 mapping되있는 anon memory alloc.(do_cow_fault() 참고)
+ */
#define alloc_page_vma(gfp_mask, vma, addr) \
alloc_pages_vma(gfp_mask, 0, vma, addr, numa_node_id(), false)
@@ -824,6 +830,11 @@ static inline void *page_frag_alloc(struct page_frag_cache *nc,
extern void page_frag_free(void *addr);
#define __free_page(page) __free_pages((page), 0)
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - order 0로 free_pages 수행
+ */
#define free_page(addr) free_pages((addr), 0)
void page_alloc_init(void);
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 044ad789c25f..771445153c27 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3109,6 +3109,11 @@ static inline bool page_poisoning_enabled_static(void)
{
return static_branch_unlikely(&_page_poisoning_enabled);
}
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - poison.
+ */
static inline void kernel_poison_pages(struct page *page, int numpages)
{
if (page_poisoning_enabled_static())
@@ -3354,6 +3359,11 @@ static inline bool vma_is_special_huge(const struct vm_area_struct *vma)
#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
+/*
+ * IAMROOT, 2022.05.14:
+ * - page alloc debug. alloc을 받을때마다 1 page를 guard page로 더 할당 받는다.
+ * memory 침해 여부등을 판별할때 사용한다.
+ */
#ifdef CONFIG_DEBUG_PAGEALLOC
extern unsigned int _debug_guardpage_minorder;
DECLARE_STATIC_KEY_FALSE(_debug_guardpage_enabled);
@@ -3368,6 +3378,12 @@ static inline bool debug_guardpage_enabled(void)
return static_branch_unlikely(&_debug_guardpage_enabled);
}
+
+/*
+ * IAMROOT, 2022.05.14:
+ * ex) order 3 page를 할당받앗을때 guard page가 1page가 추가 될수있다.
+ * (debug등의 이유) 이런 경우 merge가 안될수있다.
+ */
static inline bool page_is_guard(struct page *page)
{
if (!debug_guardpage_enabled())
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index c79e9cbbd00b..6b18fa566f15 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -470,6 +470,11 @@ struct vm_area_struct {
const struct vm_operations_struct *vm_ops;
/* Information about our backing store: */
+/*
+ * IAMROOT, 2022.05.14:
+ * 어떤 start로부터의 page offset.
+ * file일 경우 file 내의 offset이 될것이다.
+ */
unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
units */
struct file * vm_file; /* File we map to (can be NULL). */
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index 705bcb78dd51..12213b25d045 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -246,6 +246,10 @@ static inline int __nodes_full(const nodemask_t *srcp, unsigned int nbits)
}
#define nodes_weight(nodemask) __nodes_weight(&(nodemask), MAX_NUMNODES)
+/*
+ * IAMROOT, 2022.05.14:
+ * - set된 bit 개수
+ */
static inline int __nodes_weight(const nodemask_t *srcp, unsigned int nbits)
{
return bitmap_weight(srcp->bits, nbits);
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 0d3f4d7e14b8..8c2ee271b969 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -562,6 +562,10 @@ static inline pgoff_t page_to_pgoff(struct page *page)
/*
* Return byte-offset into filesystem object for page.
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - page index(file page offset)를 byte단위로 변환한다.
+ */
static inline loff_t page_offset(struct page *page)
{
return ((loff_t)page->index) << PAGE_SHIFT;
@@ -575,12 +579,45 @@ static inline loff_t page_file_offset(struct page *page)
extern pgoff_t linear_hugepage_index(struct vm_area_struct *vma,
unsigned long address);
+/*
+ * IAMROOT, 2022.05.14:
+ * - @vma의 address로 대한 file에 대한 pgoff를 구한다.
+ */
static inline pgoff_t linear_page_index(struct vm_area_struct *vma,
unsigned long address)
{
pgoff_t pgoff;
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - pass
+ */
if (unlikely(is_vm_hugetlb_page(vma)))
return linear_hugepage_index(vma, address);
+/*
+ * IAMROOT, 2022.05.14:
+ * - 현재 vm_offset(byte) >> PAGE_SHIFT => vm_offset(page).
+ * vm_pgoff + vm_offset = page offset
+ *
+ * - ex) file 기준 설명
+ *
+ * FILE VMA
+ * +-----+
+ * | |
+ * |=====| ------ mapping ------> +=====+ vm_end
+ * | | | |
+ * | | |-----| <-- address
+ * | | | | ^
+ * | | | | | address - vm_start
+ * | | | | v
+ * |=====| ------ mapping ------> +=====+ vm_start
+ * | | ^
+ * | | |
+ * | | |<- vm_pgoff
+ * pgoff = 0 +-----+ +
+ *
+ * 즉 vm_pgoff + (address - vm_start)를 하면 file에 대한 pgoff가 구해진다.
+ */
pgoff = (address - vma->vm_start) >> PAGE_SHIFT;
pgoff += vma->vm_pgoff;
return pgoff;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index d4b188919468..f72cb434afd7 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1235,6 +1235,13 @@ struct task_struct {
#ifdef CONFIG_NUMA
/* Protected by alloc_lock: */
struct mempolicy *mempolicy;
+/*
+ * IAMROOT, 2022.05.14:
+ * - il_prev(interleave prev)
+ * numa policy에서 사용한다.
+ * interlev_nodes()에서 node를 순회할때 이전에 순회했던 node가 뭐였는지
+ * nid형태로 기록한다.
+ */
short il_prev;
short pref_node_fork;
#endif
diff --git a/include/linux/sched/coredump.h b/include/linux/sched/coredump.h
index 4d9e3a656875..30f7b7b37503 100644
--- a/include/linux/sched/coredump.h
+++ b/include/linux/sched/coredump.h
@@ -66,6 +66,11 @@ static inline int get_dumpable(struct mm_struct *mm)
#define MMF_HAS_UPROBES 19 /* has uprobes */
#define MMF_RECALC_UPROBES 20 /* MMF_HAS_UPROBES can be wrong */
+/*
+ * IAMROOT, 2022.05.14:
+ * - oom_reap_task()등에서 set된다. lock등의 이유로 process가 oom kill이 안될때,
+ * 반복적으로 해당 process가 oom대상이 되는것을 방지한다.
+ */
#define MMF_OOM_SKIP 21 /* mm is of no interest for the OOM killer */
#define MMF_UNSTABLE 22 /* mm is unstable for copy_from_user */
#define MMF_HUGE_ZERO_PAGE 23 /* mm has ever used the global huge zero page */
diff --git a/include/uapi/linux/mempolicy.h b/include/uapi/linux/mempolicy.h
index 4000010a9833..5428de7f0161 100644
--- a/include/uapi/linux/mempolicy.h
+++ b/include/uapi/linux/mempolicy.h
@@ -38,6 +38,10 @@ enum {
* - cpu가 있는 node에서만 할당.
*/
MPOL_LOCAL,
+/*
+ * IAMROOT, 2022.05.14:
+ * - 선호
+ */
MPOL_PREFERRED_MANY,
MPOL_MAX, /* always last member of enum */
};
diff --git a/kernel/signal.c b/kernel/signal.c
index 487bf4f5dadf..df6bdaf2be85 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1284,6 +1284,10 @@ __group_send_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *
return send_signal(sig, info, p, PIDTYPE_TGID);
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - @p한테 sig를 보낸다.
+ */
int do_send_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *p,
enum pid_type type)
{
diff --git a/lib/nodemask.c b/lib/nodemask.c
index 3aa454c54c0d..71c4a1d051a4 100644
--- a/lib/nodemask.c
+++ b/lib/nodemask.c
@@ -3,6 +3,11 @@
#include <linux/module.h>
#include <linux/random.h>
+/*
+ * IAMROOT, 2022.05.14:
+ * - @srcp에서 @node의 next를 찾아서 return한다. @srcp를 끝까지 조회한경우
+ * @srcp의 first return.
+ */
int __next_node_in(int node, const nodemask_t *srcp)
{
int ret = __next_node(node, srcp);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 72951f568571..6ea5cf4a2f26 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2084,6 +2084,10 @@ bool mem_cgroup_oom_synchronize(bool handle)
*
* Caller has to call mem_cgroup_put() on the returned non-NULL memcg.
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - @victim의 mem_cgroup을 찾는다.
+ */
struct mem_cgroup *mem_cgroup_get_oom_group(struct task_struct *victim,
struct mem_cgroup *oom_domain)
{
@@ -2107,6 +2111,11 @@ struct mem_cgroup *mem_cgroup_get_oom_group(struct task_struct *victim,
* memory cgroup, we might end up killing tasks outside oom_domain.
* In this case it's better to ignore memory.group.oom.
*/
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - cgroup 조회전 task의 cgroup이 변경되있는지 확인한다.
+ */
if (unlikely(!mem_cgroup_is_descendant(memcg, oom_domain)))
goto out;
@@ -2115,6 +2124,11 @@ struct mem_cgroup *mem_cgroup_get_oom_group(struct task_struct *victim,
* cgroup up to the OOMing cgroup (or root) to find the
* highest-level memory cgroup with oom.group set.
*/
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - @oom_domain과 일치하는 parent memcg를 찾는다.
+ */
for (; memcg; memcg = parent_mem_cgroup(memcg)) {
if (memcg->oom_group)
oom_group = memcg;
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index d177e6063070..f6374420b604 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -159,6 +159,12 @@ int numa_map_to_online_node(int node)
}
EXPORT_SYMBOL_GPL(numa_map_to_online_node);
+/*
+ * IAMROOT, 2022.05.14:
+ * - @p에서 mempolicy를 가져온다.
+ * 만약 없다면 현재 numa에 지정된 preferred_node_policy에서 가져온다.
+ * 그것도 없다면 default_policy에서 가져온다.
+ */
struct mempolicy *get_task_policy(struct task_struct *p)
{
struct mempolicy *pol = p->mempolicy;
@@ -1675,11 +1681,19 @@ bool vma_migratable(struct vm_area_struct *vma)
return true;
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - @vma->ops나 @vma->vm_policy에서 mempolicy를 가져온다.
+ */
struct mempolicy *__get_vma_policy(struct vm_area_struct *vma,
unsigned long addr)
{
struct mempolicy *pol = NULL;
+/*
+ * IAMROOT, 2022.05.14:
+ * - vm_ops 에서 우선적으로 가져와보고 아니면 vm_policy를 사용한다.
+ */
if (vma) {
if (vma->vm_ops && vma->vm_ops->get_policy) {
pol = vma->vm_ops->get_policy(vma, addr);
@@ -1712,6 +1726,15 @@ struct mempolicy *__get_vma_policy(struct vm_area_struct *vma,
* freeing by another task. It is the caller's responsibility to free the
* extra reference for shared policies.
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - 다음 우선순위로 mempolicy를 가져온다.
+ * 1. vma->ops
+ * 2. vma->vm_policy
+ * 3. current task의 mempolicy
+ * 4. preferred_node_policy에서 mode가 있는 경우.
+ * 5. default_policy
+ */
static struct mempolicy *get_vma_policy(struct vm_area_struct *vma,
unsigned long addr)
{
@@ -1745,6 +1768,15 @@ bool vma_policy_mof(struct vm_area_struct *vma)
return pol->flags & MPOL_F_MOF;
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - policy_zone에는 최상위 zone(64bit면 normal)이 들어 있을것이다.
+ * policy_nodes가 high_memory에 없는 node범위라면 비교대상을 normal에서 movable로
+ * 변경한다.
+ * 즉 64bit에서는 highmem이 없으므로 항상 movable과 비교될것이다.
+ * 정말 왠간한 경우엔 movable만이되고 특별한 경우에 zone device가 포함된다.
+ * - @zone이 dynamic_policy_zone보다 같거나 높으면 true.
+ */
static int apply_policy_zone(struct mempolicy *policy, enum zone_type zone)
{
enum zone_type dynamic_policy_zone = policy_zone;
@@ -1769,16 +1801,32 @@ static int apply_policy_zone(struct mempolicy *policy, enum zone_type zone)
* Return a nodemask representing a mempolicy for filtering nodes for
* page allocation
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - @policy->mode에 따라 policy->nodes를 가져올지 null을 return할지 결정한다.
+ * MPOL_BIND면 현재 task와 겹치는 node가 있는지와 gfp가 policy
+ */
nodemask_t *policy_nodemask(gfp_t gfp, struct mempolicy *policy)
{
int mode = policy->mode;
/* Lower zones don't get a nodemask applied for MPOL_BIND */
+/*
+ * IAMROOT, 2022.05.14:
+ * - bind인 경우엔 gfp에서 허락하는 zone보다 policy가 같거나 높은경우
+ * (64bit에서는 보통 movable)와 current에서 허락하는 node와 겹치는 경우에만
+ * policy_nodes를 사용한다.
+ */
if (unlikely(mode == MPOL_BIND) &&
apply_policy_zone(policy, gfp_zone(gfp)) &&
cpuset_nodemask_valid_mems_allowed(&policy->nodes))
return &policy->nodes;
+/*
+ * IAMROOT, 2022.05.14:
+ * - many에서는 bind처럼 zone과 current를 비교하는 것과는 다르게 policy node로
+ * return시킨다.
+ */
if (mode == MPOL_PREFERRED_MANY)
return &policy->nodes;
@@ -1809,6 +1857,11 @@ static int policy_node(gfp_t gfp, struct mempolicy *policy, int nd)
}
/* Do dynamic interleaving for a process */
+/*
+ * IAMROOT, 2022.05.14:
+ * - 이전에 조회했던 node에서 @policy에 허락된 node list에서 next를 골라서
+ * il_prev에 기록하고 return 한다.
+ */
static unsigned interleave_nodes(struct mempolicy *policy)
{
unsigned next;
@@ -1872,6 +1925,10 @@ unsigned int mempolicy_slab_node(void)
* node in pol->nodes (starting from n=0), wrapping around if n exceeds the
* number of present nodes.
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - @p에 따라 node를 선택한다.
+ */
static unsigned offset_il_node(struct mempolicy *pol, unsigned long n)
{
nodemask_t nodemask = pol->nodes;
@@ -1890,6 +1947,25 @@ static unsigned offset_il_node(struct mempolicy *pol, unsigned long n)
nnodes = nodes_weight(nodemask);
if (!nnodes)
return numa_node_id();
+/*
+ * IAMROOT, 2022.05.14:
+ * - nodemask에 set된 node개수로 나눈 나머지를 target으로 하여
+ * 그 개수번째에 있는 nid를 선택한다.
+ * - vma address에 따라 node를 선택하게 하기 위함이다.
+ * - ex) nnodes = 3, nodemask = 0b111 일때
+ * n target nid
+ * 0 0 0
+ * 1 1 1
+ * 2 2 2
+ * 3 0 0
+ *
+ * - ex) nnodes = 2, nodemask = 0b101 일때
+ * n target nid
+ * 0 0 0
+ * 1 1 2
+ * 2 0 0
+ * 3 1 2
+ */
target = (unsigned int)n % nnodes;
nid = first_node(nodemask);
for (i = 0; i < target; i++)
@@ -1898,6 +1974,11 @@ static unsigned offset_il_node(struct mempolicy *pol, unsigned long n)
}
/* Determine a node number for interleave */
+/*
+ * IAMROOT, 2022.05.14:
+ * - @pol에 대한 interleave node를 결정한다. vma가 있을경우 page 할당 단위로,
+ * 아니면 current에 기록된 이전 node를 참고하여 다음 node를 결정한다.
+ */
static inline unsigned interleave_nid(struct mempolicy *pol,
struct vm_area_struct *vma, unsigned long addr, int shift)
{
@@ -1912,6 +1993,12 @@ static inline unsigned interleave_nid(struct mempolicy *pol,
* a useful offset.
*/
BUG_ON(shift < PAGE_SHIFT);
+/*
+ * IAMROOT, 2022.05.14:
+ * linear_page_index() 주석참고.
+ * (shift - PAGE_SHIFT)의 만큼 더 SHIFT시킨다는게 차이점이다.
+ * page 할당 단위로 node가 바뀌게 하기위함이다.
+ */
off = vma->vm_pgoff >> (shift - PAGE_SHIFT);
off += (addr - vma->vm_start) >> shift;
return offset_il_node(pol, off);
@@ -2042,6 +2129,10 @@ bool mempolicy_in_oom_domain(struct task_struct *tsk,
/* Allocate a page in interleaved policy.
Own path because it needs to do special accounting. */
+/*
+ * IAMROOT, 2022.05.14:
+ * - @nid에서 alloc이 성공했으면 hit count를 증가시켜준다.
+ */
static struct page *alloc_page_interleave(gfp_t gfp, unsigned order,
unsigned nid)
{
@@ -2059,6 +2150,12 @@ static struct page *alloc_page_interleave(gfp_t gfp, unsigned order,
return page;
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - @nid에서 nofail, reclaim을 뺀채로 시도(nid에서 실패한다면 pol->nodes)
+ * 해보고 실패한다면 모든 node제한 및 gfp를 원복하고 현재 node로 다시한번
+ * 시도해본다.
+ */
static struct page *alloc_pages_preferred_many(gfp_t gfp, unsigned int order,
int nid, struct mempolicy *pol)
{
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 89432bfdac71..be2a9cd136f2 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -263,6 +263,13 @@ static bool should_dump_unreclaim_slab(void)
/*
* IAMROOT, 2022.05.07:
* @return adj가중치 + @p의 실제 메모리사용량.
+ * --- badness의 범위
+ *
+ * [LONG_MIN, totalpages * adj / 1000 + point]
+ *
+ * LOING_MIN은 대상이 아니거나 adj가 -1000일때 return하므로 이것을 예외사항이라 치면
+ *
+ * [0, totalpages * adj / 1000 + point]
*
* --- return값
* @p의 memory 사용값을 points라고 하면 return값은 다음과 같다.
@@ -798,6 +805,11 @@ static bool oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm)
}
#define MAX_OOM_REAP_RETRIES 10
+/*
+ * IAMROOT, 2022.05.14:
+ * - lock때문에 못죽이는 process들에 대해서 해제될까지 기다리며 잘 죽었는지에 대해
+ * 최대 1초동안 감시한다.
+ */
static void oom_reap_task(struct task_struct *tsk)
{
int attempts = 0;
@@ -829,6 +841,10 @@ static void oom_reap_task(struct task_struct *tsk)
put_task_struct(tsk);
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - oom_reaper_list에 member가 있으면 oom_reap_task를 호출한다.
+ */
static int oom_reaper(void *unused)
{
while (true) {
@@ -1120,12 +1136,22 @@ static bool task_will_free_mem(struct task_struct *task)
return ret;
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - @victim을 포함하여 관련있는 process에 sig kill을 보낸다.
+ */
static void __oom_kill_process(struct task_struct *victim, const char *message)
{
struct task_struct *p;
struct mm_struct *mm;
bool can_oom_reap = true;
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - @victim에 속한 task중에 아직 종료중이 아닌걸 찾는다. 자기자신이 종료중이 아니면
+ * 자기가 대상이 될것이다.(p == victim)
+ */
p = find_lock_task_mm(victim);
if (!p) {
pr_info("%s: OOM victim %d (%s) is already exiting. Skip killing the task\n",
@@ -1178,7 +1204,23 @@ static void __oom_kill_process(struct task_struct *victim, const char *message)
* That thread will now get access to memory reserves since it has a
* pending fatal signal.
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - papgo
+ * 다른 스레드 그룹에서 victim->mm를 공유하는 모든 사용자 프로세스를 삭제합니다
+ * (있는 경우). 하지만 그들은 모든 기억의 고갈을 피하기 위해 기억 보유량에
+ * 접근하지 못한다. 이것은 oom killed 스레드를 종료할 수 없을 때 mm->mmap_lock
+ * 라이브락을 방지한다. 왜냐하면 메모리 자체를 할당하려는 다른 스레드와
+ * 세마포어가 필요하기 때문이다.
+ * 이 스레드는 대기 중인 치명적인 신호를 가지고 있으므로 이제 메모리 예약에
+ * 액세스할 수 있습니다.
+ */
rcu_read_lock();
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - mm을 공유하고있는 process를 찾아 SIGKILL을 보낸다.
+ */
for_each_process(p) {
if (!process_shares_mm(p, mm))
continue;
@@ -1202,6 +1244,10 @@ static void __oom_kill_process(struct task_struct *victim, const char *message)
}
rcu_read_unlock();
+/*
+ * IAMROOT, 2022.05.14:
+ * - init process와 mm을 공유하고 있지 않았을때만 reaper를 호출한다.
+ */
if (can_oom_reap)
wake_oom_reaper(victim);
@@ -1224,10 +1270,19 @@ static int oom_kill_memcg_member(struct task_struct *task, void *message)
return 0;
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - @oc->chosen 및 관련 process들을 죽인다.
+ */
static void oom_kill_process(struct oom_control *oc, const char *message)
{
struct task_struct *victim = oc->chosen;
struct mem_cgroup *oom_group;
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - 너무 자주 print를 안하기 위한 방어. static변수.
+ */
static DEFINE_RATELIMIT_STATE(oom_rs, DEFAULT_RATELIMIT_INTERVAL,
DEFAULT_RATELIMIT_BURST);
@@ -1236,6 +1291,11 @@ static void oom_kill_process(struct oom_control *oc, const char *message)
* its children or threads, just give it access to memory reserves
* so it can die quickly
*/
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - oom kill을 하기전에 victim이 이미 죽고 있는 task라면 mark, puit을 하고 끝낸다.
+ */
task_lock(victim);
if (task_will_free_mem(victim)) {
mark_oom_victim(victim);
@@ -1246,6 +1306,11 @@ static void oom_kill_process(struct oom_control *oc, const char *message)
}
task_unlock(victim);
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - print가 자주 출력이 안되게 조정.
+ */
if (__ratelimit(&oom_rs))
dump_header(oc, victim);
@@ -1261,6 +1326,10 @@ static void oom_kill_process(struct oom_control *oc, const char *message)
/*
* If necessary, kill all tasks in the selected memory cgroup.
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - memcg에 속한 task들에 대해서 oom_kill_memcg_member()를 실행한다.
+ */
if (oom_group) {
mem_cgroup_print_oom_group(oom_group);
mem_cgroup_scan_tasks(oom_group, oom_kill_memcg_member,
@@ -1336,6 +1405,12 @@ EXPORT_SYMBOL_GPL(unregister_oom_notifier);
* OR try to be smart about which process to kill. Note that we
* don't have to be perfect here, we just have to be good.
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * @return kill등의 이유로 memory가 확보됬다고 예상되면 true. 아니면 false
+ *
+ * - oom 대상 process를 찾고 oom kill을 수행한다.
+ */
bool out_of_memory(struct oom_control *oc)
{
unsigned long freed = 0;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8dcf4d75f185..3be387b4ba2b 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -890,6 +890,11 @@ static inline bool pcp_allowed_order(unsigned int order)
return false;
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - @page를 order 만큼 free 수행한다.
+ * order에 따라 head / tail에 들어갈지 결정된다.
+ */
static inline void free_the_page(struct page *page, unsigned int order)
{
if (pcp_allowed_order(order)) /* Via pcp? */
@@ -1135,9 +1140,29 @@ static inline void set_buddy_order(struct page *page, unsigned int order)
*
* For recording page's order, we use page_private(page).
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - papago
+ * 이 함수는 페이지가 비어 있는지 확인합니다. 그리고 다음 경우 페이지와 해당
+ * 버디를 병합할 수 있는 버디인지 확인합니다.
+ * (a) 버디가 hole에 있지 않습니다(호출하기 전에 확인하세요!). &&
+ * (b) 버디가 버디 시스템에 있는지 확인한다. &&
+ * (c) 한 페이지와 그 버디는 같은 order를 가지고 있다. &&
+ * (d) 페이지와 해당 버디가 같은 zone에 있습니다.
+ *
+ * 페이지가 버디 시스템에 있는지 여부를 기록하기 위해 페이지 버디를 설정합니다.
+ * 페이지 버디의 설정, 지우기 및 테스트는 영역->잠금별로 직렬화됩니다.
+ * 페이지 순서를 기록할 때는 page_private(page)를 사용합니다.
+ *
+ * - merge가 가능한 buddy인지 확인한다.
+ */
static inline bool page_is_buddy(struct page *page, struct page *buddy,
unsigned int order)
{
+/*
+ * IAMROOT, 2022.05.14:
+ * - guard page면 못한다.(alloc debug를 켜놓으면 merge가 안되는 상황이 생길수있다.)
+ */
if (!page_is_guard(buddy) && !PageBuddy(buddy))
return false;
@@ -1167,6 +1192,13 @@ static inline struct capture_control *task_capc(struct zone *zone)
capc->cc->zone == zone ? capc : NULL;
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - capture 요청이 왔을때, capture 요청에 대한 order와 @page가 일치하면
+ * @capc에 매달아 놓는다.
+ * 이때 cma, isolate는 capture 대상에서 제외하며
+ * @page가 movable이라면 pageblock_order 이상인 경우에만 달아놓는다.
+ */
static inline bool
compaction_capture(struct capture_control *capc, struct page *page,
int order, int migratetype)
@@ -1278,6 +1310,16 @@ static inline void del_page_from_free_list(struct page *page, struct zone *zone,
* so it's less likely to be used soon and more likely to be merged
* as a higher order page
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - papgo
+ * 가장 큰 페이지가 아닌 경우, 차순위 버디가 무료인지 확인하십시오.
+ * 만약 그렇다면, 페이지들은 곧 합쳐질 자유로워질 가능성이 있다.
+ * 그런 경우 목록의 맨 끝에 무료 페이지를 추가하여 곧 사용되지 않고
+ * 상위 페이지로 병합될 가능성이 높습니다.
+ * - next order의 page가 buddy에 있는지 확인한다. buddy에 있으면 다음에 merge가
+ * 될 가능성이 높아지므로 tail에 넣어놔 할당이 잘 안되게한다.
+ */
static inline bool
buddy_merge_likely(unsigned long pfn, unsigned long buddy_pfn,
struct page *page, unsigned int order)
@@ -1320,6 +1362,10 @@ buddy_merge_likely(unsigned long pfn, unsigned long buddy_pfn,
* -- nyc
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - buddy를 찾아 merge가 가능하면 merge를 한다.
+ */
static inline void __free_one_page(struct page *page,
unsigned long pfn,
struct zone *zone, unsigned int order,
@@ -1345,30 +1391,77 @@ static inline void __free_one_page(struct page *page,
VM_BUG_ON_PAGE(bad_range(zone, page), page);
continue_merging:
+/*
+ * IAMROOT, 2022.05.14:
+ * - buddy가 free상태면 merge를 한다.
+ */
while (order < max_order) {
if (compaction_capture(capc, page, order, migratetype)) {
__mod_zone_freepage_state(zone, -(1 << order),
migratetype);
return;
}
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - @page의 buddy를 구한다.
+ */
buddy_pfn = __find_buddy_pfn(pfn, order);
buddy = page + (buddy_pfn - pfn);
+/*
+ * IAMROOT, 2022.05.14:
+ * - buddy
+ */
if (!page_is_buddy(page, buddy, order))
goto done_merging;
/*
* Our buddy is free or it is CONFIG_DEBUG_PAGEALLOC guard page,
* merge with it and move up one order.
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - pagealloc debug가 켜진경우
+ * -- !buddy && guard => guard만 푼다. buddy는 buddy list에 없으므로 delete불필요.
+ * -- buddy && !guard => buddy list에 있으므로 buddy list에서 buddy삭제
+ * -- buddy && guard => (존재안함)
+ */
if (page_is_guard(buddy))
clear_page_guard(zone, buddy, order, migratetype);
else
del_page_from_free_list(buddy, zone, order);
+/*
+ * IAMROOT, 2022.05.14:
+ * - buddy_pfn & pfn
+ * 둘중 낮은 주소가 나온다.
+ * combined_pfn = buddy_pfn < pfn ? buddy_pfn : pfn
+ *
+ * - ex) buddy_pfn = 0, pfn = 1
+ * combined_pfn = 0
+ * page = page + (0 - 1) = page - 1
+ *
+ * - ex) buddy_pfn = 0, pfn = 2
+ * combined_pfn = 0
+ * page = page + (0 - 2) = page - 2
+ *
+ * - ex) buddy_pfn = 2, pfn = 0
+ * combined_pfn = 0
+ * page = page + (0 - 0) = page - 0
+ *
+ * order 0 : (0, 1) (2, 3), (4, 5) ..
+ * order 1 : (0, 2) (4, 6), (8, 10) ..
+ * order 2 : (0, 4),(8, 12), (16, 20) ..
+ */
combined_pfn = buddy_pfn & pfn;
page = page + (combined_pfn - pfn);
pfn = combined_pfn;
order++;
}
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - max_order <= order < MAX_ORDER - 1
+ */
if (order < MAX_ORDER - 1) {
/* If we are here, it means order is >= pageblock_order.
* We want to prevent merge between freepages on isolate
@@ -1378,6 +1471,11 @@ static inline void __free_one_page(struct page *page,
* We don't want to hit this code for the more frequent
* low-order merging.
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - zone이 isolate를 가지고 있는상황에서, 두개의 migratetype이 다른 상태에서
+ * 둘중 하라나라도 isolate면 merge를 종료한다.
+ */
if (unlikely(has_isolate_pageblock(zone))) {
int buddy_mt;
@@ -1390,6 +1488,10 @@ static inline void __free_one_page(struct page *page,
is_migrate_isolate(buddy_mt)))
goto done_merging;
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - 위의 경우가 아니면 max_order를 1증가해서 merge를 한번더 수행한다.
+ */
max_order = order + 1;
goto continue_merging;
}
@@ -1397,6 +1499,13 @@ static inline void __free_one_page(struct page *page,
done_merging:
set_buddy_order(page, order);
+/*
+ * IAMROOT, 2022.05.14:
+ * 1. flag로 tail넣으라는경우 tail
+ * 2. order == 10인 경우. random
+ * 3. order == 9인 경우 head
+ * 4. 그외
+ */
if (fpi_flags & FPI_TO_TAIL)
to_tail = true;
else if (is_shuffle_order(order))
@@ -1490,6 +1599,11 @@ static inline int check_free_page(struct page *page)
return 1;
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - mapping, compound head를 초기화한다.
+ * - debug가 켜져있ㅎ을 경우 compound tail page의 data가 맞는지 검사한다.
+ */
static int free_tail_pages_check(struct page *head_page, struct page *page)
{
int ret = 1;
@@ -1565,6 +1679,18 @@ static void kernel_init_free_pages(struct page *page, int numpages, bool zero_ta
kasan_enable_current();
}
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - free를 하기 적당한 page인지 검사한다.
+ * 1. order 0 posison 검사
+ * 2. mapping 해제
+ * 3. tail page 검사
+ * 4. hwpoison flag clear
+ * 5. reset page owner
+ * 6. free poison 기록.
+ * 7. memset 0 여부 확인.
+ */
static __always_inline bool free_pages_prepare(struct page *page,
unsigned int order, bool check_free, fpi_t fpi_flags)
{
@@ -1575,6 +1701,15 @@ static __always_inline bool free_pages_prepare(struct page *page,
trace_mm_page_free(page, order);
+/*
+ * IAMROOT, 2022.05.14:
+ * - hw poison이 식별됬는데 order 0면 skip.
+ * migrate수행중이라는 page라고 예상하며 해당 page가 migrate종료 후 자동으로
+ * buddy등에 돌아갈것이라 여기서 종료시킨다.
+ *
+ * - Git blame
+ * page_handle_poison sets the HWPoison flag and does the last put_page.
+ */
if (unlikely(PageHWPoison(page)) && !order) {
/*
* Do not let hwpoison pages hit pcplists/buddy
@@ -1590,6 +1725,11 @@ static __always_inline bool free_pages_prepare(struct page *page,
* Check tail pages before head page information is cleared to
* avoid checking PageCompound for order-0 pages.
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - order가 존재하는 page에 대해서 다음을 수행한다.
+ * DoubleMap, HasHWPoisoned를 cler.
+ */
if (unlikely(order)) {
bool compound = PageCompound(page);
@@ -1645,6 +1785,11 @@ static __always_inline bool free_pages_prepare(struct page *page,
if (!skip_kasan_poison)
kasan_free_pages(page, order);
} else {
+
+/*
+ * IAMROOT, 2022.05.14:
+ * - free후 0으로 clear할지를 정한다.
+ */
bool init = want_init_on_free();
if (init)
@@ -1690,6 +1835,10 @@ static bool bulkfree_pcp_prepare(struct page *page)
* debug_pagealloc enabled, they are checked also immediately when being freed
* to the pcp lists.
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - @page가 free 가능한지를 검사하고, 가능하면 free를 위한 초기화를 수행한다.
+ */
static bool free_pcp_prepare(struct page *page, unsigned int order)
{
if (debug_pagealloc_enabled_static())
@@ -1859,6 +2008,12 @@ static void free_pcppages_bulk(struct zone *zone, int count,
spin_unlock(&zone->lock);
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - buddy로 free.
+ * - @zone에 isolate pageblock이 존재하거나, @page가 isolate일 경우
+ * 대표 migratetype으로 변경한다.
+ */
static void free_one_page(struct zone *zone,
struct page *page, unsigned long pfn,
unsigned int order,
@@ -1979,7 +2134,7 @@ void __meminit reserve_bootmem_region(phys_addr_t start, phys_addr_t end)
/*
* IAMROOT, 2022.03.22:
- * - TODO
+ * - buddy에 넣는다.
*/
static void __free_pages_ok(struct page *page, unsigned int order,
fpi_t fpi_flags)
@@ -1995,6 +2150,11 @@ static void __free_pages_ok(struct page *page, unsigned int order,
migratetype = get_pfnblock_migratetype(page, pfn);
spin_lock_irqsave(&zone->lock, flags);
+/*
+ * IAMROOT, 2022.05.14:
+ * - @page가 isolate migrate이거나 @zone이 isolate를 가지고 있을 경우
+ * migratetype을 @page의 대표 migrate로 바꾼다.
+ */
if (unlikely(has_isolate_pageblock(zone) ||
is_migrate_isolate(migratetype))) {
migratetype = get_pfnblock_migratetype(page, pfn);
@@ -2765,6 +2925,16 @@ static inline void expand(struct zone *zone, struct page *page,
* Corresponding page table entries will not be touched,
* pages will stay not present in virtual address space
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - papago
+ * 버디가 해방될 때 할당자에 다시 병합할 수 있도록 가드 페이지(또는 페이지)로
+ * 표시합니다.
+ * 해당 페이지 테이블 항목은 터치되지 않으며 페이지는 가상 주소 공간에 존재하지
+ * 않습니다.
+ * - debug alloc이 켜져있고 debug minorder 보다 작은 경우엔 guard page로 만들고
+ * buddy에 안넣는다.
+ */
if (set_page_guard(zone, &page[size], high, migratetype))
continue;
@@ -4192,6 +4362,10 @@ void mark_free_pages(struct zone *zone)
}
#endif /* CONFIG_PM */
+/*
+ * IAMROOT, 2022.05.14:
+ * - free를 위한 설정을 진행하고 migratetype을 @page->index에 set한다.
+ */
static bool free_unref_page_prepare(struct page *page, unsigned long pfn,
unsigned int order)
{
@@ -4200,11 +4374,20 @@ static bool free_unref_page_prepare(struct page *page, unsigned long pfn,
if (!free_pcp_prepare(page, order))
return false;
+/*
+ * IAMROOT, 2022.05.14:
+ * - pageblock의 migratetype을 가져와 page->index에 set한다.
+ * pcp를 넣기전에 기준 migratetype으로 전체 block을 통일시킨다.
+ */
migratetype = get_pfnblock_migratetype(page, pfn);
set_pcppage_migratetype(page, migratetype);
return true;
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - @pcp에서 batch만큼 free를 시키지에 대한 개수를 확정한다.
+ */
static int nr_pcp_free(struct per_cpu_pages *pcp, int high, int batch)
{
int min_nr_free, max_nr_free;
@@ -4221,6 +4404,13 @@ static int nr_pcp_free(struct per_cpu_pages *pcp, int high, int batch)
* Double the number of pages freed each time there is subsequent
* freeing of pages without any allocation.
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - batch가 max_nr_free보다 높은 경우에 한해서 free_factor가 증가한다.
+ * 이후 할당요청이 없는 상태에서 계속 batch요청(pcp<->buddy)이 오면 한번에
+ * 더 많이 하기 위함이다.
+ * 만약 한번이라도 pcp할당(rmqueue_pcplist())이 오면 free_factor가 반씩 감소한다.
+ */
batch <<= pcp->free_factor;
if (batch < max_nr_free)
pcp->free_factor++;
@@ -4229,6 +4419,10 @@ static int nr_pcp_free(struct per_cpu_pages *pcp, int high, int batch)
return batch;
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - pcplist batch high을 가져온다.
+ */
static int nr_pcp_high(struct per_cpu_pages *pcp, struct zone *zone)
{
int high = READ_ONCE(pcp->high);
@@ -4246,6 +4440,10 @@ static int nr_pcp_high(struct per_cpu_pages *pcp, struct zone *zone)
return min(READ_ONCE(pcp->batch) << 2, high);
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - pcp에 넣고, 만약 pcp overflow면 buddy에 넣는다.
+ */
static void free_unref_page_commit(struct page *page, unsigned long pfn,
int migratetype, unsigned int order)
{
@@ -4254,12 +4452,21 @@ static void free_unref_page_commit(struct page *page, unsigned long pfn,
int high;
int pindex;
+/*
+ * IAMROOT, 2022.05.14:
+ * - pcp에 넣는다.
+ */
__count_vm_event(PGFREE);
pcp = this_cpu_ptr(zone->per_cpu_pageset);
pindex = order_to_pindex(migratetype, order);
list_add(&page->lru, &pcp->lists[pindex]);
pcp->count += 1 << order;
high = nr_pcp_high(pcp, zone);
+/*
+ * IAMROOT, 2022.05.14:
+ * - pcp에 넣어봤더니 pcp에 있는 page가 한도(high)를 초과했으면
+ * batch에 free_factor를 고려한 개수만큼 buddy로 이동시킨다.
+ */
if (pcp->count >= high) {
int batch = READ_ONCE(pcp->batch);
@@ -4270,6 +4477,10 @@ static void free_unref_page_commit(struct page *page, unsigned long pfn,
/*
* Free a pcp page
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - page를 free해서 pcp에 넣는다.
+ */
void free_unref_page(struct page *page, unsigned int order)
{
unsigned long flags;
@@ -4287,7 +4498,15 @@ void free_unref_page(struct page *page, unsigned int order)
* excessively into the page allocator
*/
migratetype = get_pcppage_migratetype(page);
+/*
+ * IAMROOT, 2022.05.14:
+ * - UNMOVABLE, MOVABLE, RECLAIMABLE은 바로 pcp로 간다.
+ */
if (unlikely(migratetype >= MIGRATE_PCPTYPES)) {
+/*
+ * IAMROOT, 2022.05.14:
+ * - isolate는 buddy로, cma, highatomic은 movable로 변경후 pcp로 보낸다.
+ */
if (unlikely(is_migrate_isolate(migratetype))) {
free_one_page(page_zone(page), page, pfn, order, migratetype, FPI_NONE);
return;
@@ -4577,6 +4796,15 @@ static struct page *rmqueue_pcplist(struct zone *preferred_zone,
* frees.
*/
pcp = this_cpu_ptr(zone->per_cpu_pageset);
+/*
+ * IAMROOT, 2022.05.14:
+ * - batch가 max_nr_free보다 높은 경우에 한해서 free_factor가 증가한다.
+ * 이후 할당요청이 없는 상태에서 계속 batch요청(pcp<->buddy)이 오면 한번에
+ * 더 많이 하기 위함이다.
+ * - batch요청시 free_factor을 보고 더 많이 batch를 하는지에 대한 여부를
+ * 결정하는데 만약 이와같은 pcp 할당요청이 이뤄지면 batch요청을 절반식 줄인다.
+ * (nr_pcp_free())
+ */
pcp->free_factor >>= 1;
list = &pcp->lists[order_to_pindex(migratetype, order)];
page = __rmqueue_pcplist(zone, order, migratetype, alloc_flags, pcp, list);
@@ -5506,6 +5734,9 @@ __alloc_pages_cpuset_fallback(gfp_t gfp_mask, unsigned int order,
/*
* IAMROOT, 2022.05.13:
* @did_some_progress[out] oom kill을 한경우 return 1, 아니면 return 0
+ *
+ * - 최종적으로 watermark high로 alloc을 시도하고, 그게 실패하면 costly order이내에
+ * 한해서 oom을 실행한다.
*/
static inline struct page *
__alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order,
@@ -5620,6 +5851,10 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order,
* Help non-failing allocations by giving them access to memory
* reserves
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - __GFP_NOFAIL이 있으면 no watermark로 할당시도를 한다.
+ */
if (gfp_mask & __GFP_NOFAIL)
page = __alloc_pages_cpuset_fallback(gfp_mask, order,
ALLOC_NO_WATERMARKS, ac);
@@ -6390,6 +6625,14 @@ check_retry_cpuset(int cpuset_mems_cookie, struct alloc_context *ac)
return false;
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - alloc을 시도한다.
+ * - 실패시 다음을 시도한다.
+ * -- direct compact 시도
+ * -- direct reclaim 시도
+ * -- oom kill
+ */
static inline struct page *
__alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
struct alloc_context *ac)
@@ -6706,6 +6949,10 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
goto nopage;
/* Retry as long as the OOM killer is making progress */
+/*
+ * IAMROOT, 2022.05.14:
+ * - oom이 실행됬거나 free 공간이 생김.
+ */
if (did_some_progress) {
no_progress_loops = 0;
goto retry;
@@ -7186,6 +7433,10 @@ EXPORT_SYMBOL(get_zeroed_page);
* Context: May be called in interrupt context or while holding a normal
* spinlock, but not in NMI context or while holding a raw spinlock.
*/
+/*
+ * IAMROOT, 2022.05.14:
+ * - @page를 order 단위로 free 수행
+ */
void __free_pages(struct page *page, unsigned int order)
{
if (put_page_testzero(page))
@@ -7196,6 +7447,10 @@ void __free_pages(struct page *page, unsigned int order)
}
EXPORT_SYMBOL(__free_pages);
+/*
+ * IAMROOT, 2022.05.14:
+ * - order 단위로 free page수행
+ */
void free_pages(unsigned long addr, unsigned int order)
{
if (addr != 0) {
diff --git a/mm/page_poison.c b/mm/page_poison.c
index 4223f7ccb69b..cb86e9dcd200 100644
--- a/mm/page_poison.c
+++ b/mm/page_poison.c
@@ -24,6 +24,10 @@ static int __init early_page_poison_param(char *buf)
}
early_param("page_poison", early_page_poison_param);
+/*
+ * IAMROOT, 2022.05.14:
+ * - posion
+ */
static void poison_page(struct page *page)
{
void *addr = kmap_atomic(page);
diff --git a/mm/shuffle.c b/mm/shuffle.c
index c13c33b247e8..3c809289300d 100644
--- a/mm/shuffle.c
+++ b/mm/shuffle.c
@@ -159,6 +159,11 @@ void __meminit __shuffle_free_memory(pg_data_t *pgdat)
shuffle_zone(z);
}
+/*
+ * IAMROOT, 2022.05.14:
+ * - 64번마다 한번씩만 get_random_u64()를 호출한다.
+ * - 홀짝만 구할때 사용한다.
+ */
bool shuffle_pick_tail(void)
{
static u64 rand;
댓글 0
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
공지 | [공지] 스터디 정리 노트 공간입니다. | woos | 2016.05.14 | 626 |
127 | [커널 18차] 56주차 | kkr | 2022.06.18 | 71 |
126 | [커널 17차] 92~93주차 | ㅇㅇㅇ | 2022.06.11 | 93 |
125 | [커널 18차] 54주차 | kkr | 2022.06.04 | 82 |
124 | [커널 19차] 3주차 | 리턴 | 2022.06.04 | 217 |
123 | [커널 18차] 53주차 | kkr | 2022.05.29 | 93 |
122 | [커널 17차] 91주차 | ㅇㅇㅇ | 2022.05.28 | 64 |
121 | [커널 19차] 2주차 | 리턴 | 2022.05.28 | 169 |
120 | [커널 17차] 90주차 | ㅇㅇㅇ | 2022.05.22 | 149 |
119 | [커널 18차] 52주차 | kkr | 2022.05.21 | 123 |
118 | [커널 19차] 1주차 | 리턴 | 2022.05.16 | 456 |
117 | [커널 17차] 89주차 | ㅇㅇㅇ | 2022.05.15 | 65 |
» | [커널 18차] 51주차 | kkr | 2022.05.14 | 159 |
115 | [커널 18차] 50주차 | kkr | 2022.05.10 | 205 |
114 | [커널 17차] 88주차 | ㅇㅇㅇ | 2022.05.08 | 101 |
113 | [커널 19차] 0주차 - 오리엔테이션 | 리턴 | 2022.05.07 | 599 |
112 | [커널 17차] 86~87주차 | ㅇㅇㅇ | 2022.04.30 | 101 |
111 | [커널 17차] 84~85주차 | JSYoo5B | 2022.04.16 | 86 |
110 | [커널 17차] 83주차 | ㅇㅇㅇ | 2022.04.03 | 92 |
109 | [커널 17차] 82주차 | ㅇㅇㅇ | 2022.03.27 | 65 |
108 | [커널 17차] 81주차 | ㅇㅇㅇ | 2022.03.19 | 132 |
.