mm/hugetlb_cgroup.c

Source file repositories/reference/linux-study-clean/mm/hugetlb_cgroup.c

File Facts

System
Linux kernel
Corpus path
mm/hugetlb_cgroup.c
Extension
.c
Size
23874 bytes
Lines
921
Domain
Core OS
Bucket
Memory Management
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (parent_h_cgroup) {
			fault_parent = hugetlb_cgroup_counter_from_cgroup(
				parent_h_cgroup, idx);
			rsvd_parent = hugetlb_cgroup_counter_from_cgroup_rsvd(
				parent_h_cgroup, idx);
		}
		fault = hugetlb_cgroup_counter_from_cgroup(h_cgroup, idx);
		rsvd = hugetlb_cgroup_counter_from_cgroup_rsvd(h_cgroup, idx);

		page_counter_init(fault, fault_parent, false);
		page_counter_init(rsvd, rsvd_parent, false);

		if (!cgroup_subsys_on_dfl(hugetlb_cgrp_subsys)) {
			fault->track_failcnt = true;
			rsvd->track_failcnt = true;
		}

		limit = round_down(PAGE_COUNTER_MAX,
				   pages_per_huge_page(&hstates[idx]));

		VM_BUG_ON(page_counter_set_max(fault, limit));
		VM_BUG_ON(page_counter_set_max(rsvd, limit));
	}
}

static void hugetlb_cgroup_free(struct hugetlb_cgroup *h_cgroup)
{
	int node;

	for_each_node(node)
		kfree(h_cgroup->nodeinfo[node]);
	kfree(h_cgroup);
}

static struct cgroup_subsys_state *
hugetlb_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
{
	struct hugetlb_cgroup *parent_h_cgroup = hugetlb_cgroup_from_css(parent_css);
	struct hugetlb_cgroup *h_cgroup;
	int node;

	h_cgroup = kzalloc_flex(*h_cgroup, nodeinfo, nr_node_ids);

	if (!h_cgroup)
		return ERR_PTR(-ENOMEM);

	if (!parent_h_cgroup)
		root_h_cgroup = h_cgroup;

	/*
	 * TODO: this routine can waste much memory for nodes which will
	 * never be onlined. It's better to use memory hotplug callback
	 * function.
	 */
	for_each_node(node) {
		/* Set node_to_alloc to NUMA_NO_NODE for offline nodes. */
		int node_to_alloc =
			node_state(node, N_NORMAL_MEMORY) ? node : NUMA_NO_NODE;
		h_cgroup->nodeinfo[node] =
			kzalloc_node(sizeof(struct hugetlb_cgroup_per_node),
				     GFP_KERNEL, node_to_alloc);
		if (!h_cgroup->nodeinfo[node])
			goto fail_alloc_nodeinfo;
	}

	hugetlb_cgroup_init(h_cgroup, parent_h_cgroup);
	return &h_cgroup->css;

fail_alloc_nodeinfo:
	hugetlb_cgroup_free(h_cgroup);
	return ERR_PTR(-ENOMEM);
}

static void hugetlb_cgroup_css_free(struct cgroup_subsys_state *css)
{
	hugetlb_cgroup_free(hugetlb_cgroup_from_css(css));
}

/*
 * Should be called with hugetlb_lock held.
 * Since we are holding hugetlb_lock, pages cannot get moved from
 * active list or uncharged from the cgroup, So no need to get
 * page reference and test for page active here. This function
 * cannot fail.
 */
static void hugetlb_cgroup_move_parent(int idx, struct hugetlb_cgroup *h_cg,
				       struct folio *folio)
{
	unsigned int nr_pages;
	struct page_counter *counter;

Annotation

Implementation Notes