lib/group_cpus.c
Source file repositories/reference/linux-study-clean/lib/group_cpus.c
File Facts
- System
- Linux kernel
- Corpus path
lib/group_cpus.c- Extension
.c- Size
- 15024 bytes
- Lines
- 586
- Domain
- Kernel Services
- Bucket
- lib
- Inferred role
- Kernel Services: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/slab.hlinux/cpu.hlinux/sort.hlinux/group_cpus.h
Detected Declarations
struct node_groupsfunction Copyrightfunction free_node_to_cpumaskfunction build_node_to_cpumaskfunction get_nodes_in_cpumaskfunction ncpus_cmp_funcfunction alloc_groups_to_nodesfunction alloc_nodes_groupsfunction for_each_node_maskfunction assign_cpus_to_groupsfunction alloc_cluster_groupsfunction __try_group_cluster_cpusfunction __group_cpus_evenlyfunction for_each_node_maskexport group_cpus_evenly
Annotated Snippet
struct node_groups {
unsigned id;
union {
unsigned ngroups;
unsigned ncpus;
};
};
static int ncpus_cmp_func(const void *l, const void *r)
{
const struct node_groups *ln = l;
const struct node_groups *rn = r;
return ln->ncpus - rn->ncpus;
}
static void alloc_groups_to_nodes(unsigned int numgrps,
unsigned int numcpus,
struct node_groups *node_groups,
unsigned int num_nodes)
{
unsigned int n, remaining_ncpus = numcpus;
unsigned int ngroups, ncpus;
sort(node_groups, num_nodes, sizeof(node_groups[0]),
ncpus_cmp_func, NULL);
/*
* Allocate groups for each node according to the ratio of this
* node's nr_cpus to remaining un-assigned ncpus. 'numgrps' is
* bigger than number of active numa nodes. Always start the
* allocation from the node with minimized nr_cpus.
*
* This way guarantees that each active node gets allocated at
* least one group, and the theory is simple: over-allocation
* is only done when this node is assigned by one group, so
* other nodes will be allocated >= 1 groups, since 'numgrps' is
* bigger than number of numa nodes.
*
* One perfect invariant is that number of allocated groups for
* each node is <= CPU count of this node:
*
* 1) suppose there are two nodes: A and B
* ncpu(X) is CPU count of node X
* grps(X) is the group count allocated to node X via this
* algorithm
*
* ncpu(A) <= ncpu(B)
* ncpu(A) + ncpu(B) = N
* grps(A) + grps(B) = G
*
* grps(A) = max(1, round_down(G * ncpu(A) / N))
* grps(B) = G - grps(A)
*
* both N and G are integer, and 2 <= G <= N, suppose
* G = N - delta, and 0 <= delta <= N - 2
*
* 2) obviously grps(A) <= ncpu(A) because:
*
* if grps(A) is 1, then grps(A) <= ncpu(A) given
* ncpu(A) >= 1
*
* otherwise,
* grps(A) <= G * ncpu(A) / N <= ncpu(A), given G <= N
*
* 3) prove how grps(B) <= ncpu(B):
*
* if round_down(G * ncpu(A) / N) == 0, vecs(B) won't be
* over-allocated, so grps(B) <= ncpu(B),
*
* otherwise:
*
* grps(A) =
* round_down(G * ncpu(A) / N) =
* round_down((N - delta) * ncpu(A) / N) =
* round_down((N * ncpu(A) - delta * ncpu(A)) / N) >=
* round_down((N * ncpu(A) - delta * N) / N) =
* cpu(A) - delta
*
* then:
*
* grps(A) - G >= ncpu(A) - delta - G
* =>
* G - grps(A) <= G + delta - ncpu(A)
* =>
* grps(B) <= N - ncpu(A)
* =>
* grps(B) <= cpu(B)
*
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/slab.h`, `linux/cpu.h`, `linux/sort.h`, `linux/group_cpus.h`.
- Detected declarations: `struct node_groups`, `function Copyright`, `function free_node_to_cpumask`, `function build_node_to_cpumask`, `function get_nodes_in_cpumask`, `function ncpus_cmp_func`, `function alloc_groups_to_nodes`, `function alloc_nodes_groups`, `function for_each_node_mask`, `function assign_cpus_to_groups`.
- Atlas domain: Kernel Services / lib.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.