Commit 7f203bc8 authored by Tejun Heo's avatar Tejun Heo

cgroup: Replace cgroup->ancestor_ids[] with ->ancestors[]

Every cgroup knows all its ancestors through its ->ancestor_ids[]. There's
no advantage to remembering the IDs instead of the pointers directly and
this makes the array useless for finding an actual ancestor cgroup forcing
cgroup_ancestor() to iteratively walk up the hierarchy instead. Let's
replace cgroup->ancestor_ids[] with ->ancestors[] and remove the walking-up
from cgroup_ancestor().

While at it, improve comments around cgroup_root->cgrp_ancestor_storage.

This patch shouldn't cause user-visible behavior differences.

v2: Update cgroup_ancestor() to use ->ancestors[].

v3: cgroup_root->cgrp_ancestor_storage's type is updated to match
    cgroup->ancestors[]. Better comments.
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarNamhyung Kim <namhyung@kernel.org>
parent 568035b0
...@@ -384,7 +384,7 @@ struct cgroup { ...@@ -384,7 +384,7 @@ struct cgroup {
/* /*
* The depth this cgroup is at. The root is at depth zero and each * The depth this cgroup is at. The root is at depth zero and each
* step down the hierarchy increments the level. This along with * step down the hierarchy increments the level. This along with
* ancestor_ids[] can determine whether a given cgroup is a * ancestors[] can determine whether a given cgroup is a
* descendant of another without traversing the hierarchy. * descendant of another without traversing the hierarchy.
*/ */
int level; int level;
...@@ -504,8 +504,8 @@ struct cgroup { ...@@ -504,8 +504,8 @@ struct cgroup {
/* Used to store internal freezer state */ /* Used to store internal freezer state */
struct cgroup_freezer_state freezer; struct cgroup_freezer_state freezer;
/* ids of the ancestors at each level including self */ /* All ancestors including self */
u64 ancestor_ids[]; struct cgroup *ancestors[];
}; };
/* /*
...@@ -522,11 +522,15 @@ struct cgroup_root { ...@@ -522,11 +522,15 @@ struct cgroup_root {
/* Unique id for this hierarchy. */ /* Unique id for this hierarchy. */
int hierarchy_id; int hierarchy_id;
/* The root cgroup. Root is destroyed on its release. */ /*
* The root cgroup. The containing cgroup_root will be destroyed on its
* release. cgrp->ancestors[0] will be used overflowing into the
* following field. cgrp_ancestor_storage must immediately follow.
*/
struct cgroup cgrp; struct cgroup cgrp;
/* for cgrp->ancestor_ids[0] */ /* must follow cgrp for cgrp->ancestors[0], see above */
u64 cgrp_ancestor_id_storage; struct cgroup *cgrp_ancestor_storage;
/* Number of cgroups in the hierarchy, used only for /proc/cgroups */ /* Number of cgroups in the hierarchy, used only for /proc/cgroups */
atomic_t nr_cgrps; atomic_t nr_cgrps;
......
...@@ -574,7 +574,7 @@ static inline bool cgroup_is_descendant(struct cgroup *cgrp, ...@@ -574,7 +574,7 @@ static inline bool cgroup_is_descendant(struct cgroup *cgrp,
{ {
if (cgrp->root != ancestor->root || cgrp->level < ancestor->level) if (cgrp->root != ancestor->root || cgrp->level < ancestor->level)
return false; return false;
return cgrp->ancestor_ids[ancestor->level] == cgroup_id(ancestor); return cgrp->ancestors[ancestor->level] == ancestor;
} }
/** /**
...@@ -591,11 +591,9 @@ static inline bool cgroup_is_descendant(struct cgroup *cgrp, ...@@ -591,11 +591,9 @@ static inline bool cgroup_is_descendant(struct cgroup *cgrp,
static inline struct cgroup *cgroup_ancestor(struct cgroup *cgrp, static inline struct cgroup *cgroup_ancestor(struct cgroup *cgrp,
int ancestor_level) int ancestor_level)
{ {
if (cgrp->level < ancestor_level) if (ancestor_level < 0 || ancestor_level > cgrp->level)
return NULL; return NULL;
while (cgrp && cgrp->level > ancestor_level) return cgrp->ancestors[ancestor_level];
cgrp = cgroup_parent(cgrp);
return cgrp;
} }
/** /**
......
...@@ -2049,7 +2049,7 @@ int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask) ...@@ -2049,7 +2049,7 @@ int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)
} }
root_cgrp->kn = kernfs_root_to_node(root->kf_root); root_cgrp->kn = kernfs_root_to_node(root->kf_root);
WARN_ON_ONCE(cgroup_ino(root_cgrp) != 1); WARN_ON_ONCE(cgroup_ino(root_cgrp) != 1);
root_cgrp->ancestor_ids[0] = cgroup_id(root_cgrp); root_cgrp->ancestors[0] = root_cgrp;
ret = css_populate_dir(&root_cgrp->self); ret = css_populate_dir(&root_cgrp->self);
if (ret) if (ret)
...@@ -5400,8 +5400,7 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name, ...@@ -5400,8 +5400,7 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
int ret; int ret;
/* allocate the cgroup and its ID, 0 is reserved for the root */ /* allocate the cgroup and its ID, 0 is reserved for the root */
cgrp = kzalloc(struct_size(cgrp, ancestor_ids, (level + 1)), cgrp = kzalloc(struct_size(cgrp, ancestors, (level + 1)), GFP_KERNEL);
GFP_KERNEL);
if (!cgrp) if (!cgrp)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
...@@ -5453,7 +5452,7 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name, ...@@ -5453,7 +5452,7 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name,
spin_lock_irq(&css_set_lock); spin_lock_irq(&css_set_lock);
for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp)) { for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp)) {
cgrp->ancestor_ids[tcgrp->level] = cgroup_id(tcgrp); cgrp->ancestors[tcgrp->level] = tcgrp;
if (tcgrp != cgrp) { if (tcgrp != cgrp) {
tcgrp->nr_descendants++; tcgrp->nr_descendants++;
......
...@@ -40,16 +40,17 @@ static noinline bool ...@@ -40,16 +40,17 @@ static noinline bool
nft_sock_get_eval_cgroupv2(u32 *dest, struct sock *sk, const struct nft_pktinfo *pkt, u32 level) nft_sock_get_eval_cgroupv2(u32 *dest, struct sock *sk, const struct nft_pktinfo *pkt, u32 level)
{ {
struct cgroup *cgrp; struct cgroup *cgrp;
u64 cgid;
if (!sk_fullsock(sk)) if (!sk_fullsock(sk))
return false; return false;
cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data); cgrp = cgroup_ancestor(sock_cgroup_ptr(&sk->sk_cgrp_data), level);
if (level > cgrp->level) if (!cgrp)
return false; return false;
memcpy(dest, &cgrp->ancestor_ids[level], sizeof(u64)); cgid = cgroup_id(cgrp);
memcpy(dest, &cgid, sizeof(u64));
return true; return true;
} }
#endif #endif
......
...@@ -68,7 +68,7 @@ static inline int get_cgroup_v1_idx(__u32 *cgrps, int size) ...@@ -68,7 +68,7 @@ static inline int get_cgroup_v1_idx(__u32 *cgrps, int size)
break; break;
// convert cgroup-id to a map index // convert cgroup-id to a map index
cgrp_id = BPF_CORE_READ(cgrp, ancestor_ids[i]); cgrp_id = BPF_CORE_READ(cgrp, ancestors[i], kn, id);
elem = bpf_map_lookup_elem(&cgrp_idx, &cgrp_id); elem = bpf_map_lookup_elem(&cgrp_idx, &cgrp_id);
if (!elem) if (!elem)
continue; continue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment