On 31.07.2020 15:54, Valeriy Vdovin wrote: > Implemented function 've_cleanup_per_cgroot_data' that is called in two > resource release cases. > > 1. At container stop procedure, container' init process goes through > exit process routines, and calls ve_exit_ns. ve_exit_ns knows about > ve from it's agrument it and can call ve_cleanup_per_cgroot_data with > ve argument. > 2. At destruction of cgroup mount point, 'cgroup_drop_root' will be called > from cgroup's unmount implementation code. Also same code will be executed > during cgroup_mount function when error happens and cleanup is needed. > In both cases cgroup_drop_root will call 've_cleanup_per_cgroot_data'. > All those codepaths will know cgroup and pass it as an argument. > > 've_cleaup_per_cgroot_data' releases per-cgroup-root resources stored in ve > It expects any of two arguments (ve or cgroup) to be non-NULL to derive > type of cleanup, that is needed. If cgroup is NULL, it cleans up values > for all cgroup roots that it possesses. > If cgroup is non-NULL it only cleans out values for this particular > cgroup. > > Signed-off-by: Valeriy Vdovin <[email protected]>
Reviewed-by: Kirill Tkhai <[email protected]> > --- > include/linux/ve.h | 2 ++ > kernel/cgroup.c | 1 + > kernel/ve/ve.c | 30 +++++++++++++++++++++--------- > 3 files changed, 24 insertions(+), 9 deletions(-) > > diff --git a/include/linux/ve.h b/include/linux/ve.h > index 5bf275f..2dcd7bb 100644 > --- a/include/linux/ve.h > +++ b/include/linux/ve.h > @@ -220,6 +220,8 @@ int ve_set_release_agent_path(struct cgroup *cgroot, > > const char *ve_get_release_agent_path(struct cgroup *cgrp_root); > > +void ve_cleanup_per_cgroot_data(struct ve_struct *ve, struct cgroup *cgrp); > + > extern struct ve_struct *get_ve(struct ve_struct *ve); > extern void put_ve(struct ve_struct *ve); > > diff --git a/kernel/cgroup.c b/kernel/cgroup.c > index 989f73e..3305032 100644 > --- a/kernel/cgroup.c > +++ b/kernel/cgroup.c > @@ -1591,6 +1591,7 @@ static void cgroup_drop_root(struct cgroupfs_root *root) > { > if (!root) > return; > + ve_cleanup_per_cgroot_data(NULL, &root->top_cgroup); > > BUG_ON(!root->hierarchy_id); > spin_lock(&hierarchy_id_lock); > diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c > index 8d78270..db26cbd4 100644 > --- a/kernel/ve/ve.c > +++ b/kernel/ve/ve.c > @@ -745,21 +745,33 @@ err_list: > return err; > } > > -static void ve_per_cgroot_free(struct ve_struct *ve) > +static inline void per_cgroot_data_free(struct per_cgroot_data *data) > +{ > + struct cgroup_rcu_string *release_agent = data->release_agent_path; > + > + RCU_INIT_POINTER(data->release_agent_path, NULL); > + if (release_agent) > + kfree_rcu(release_agent, rcu_head); > + kfree(data); > +} > + > +void ve_cleanup_per_cgroot_data(struct ve_struct *ve, struct cgroup *cgrp) > { > struct per_cgroot_data *data, *saved; > - struct cgroup_rcu_string *release_agent; > > + BUG_ON(!ve && !cgrp); > + rcu_read_lock(); > + if (!ve) > + ve = cgroup_get_ve_owner(cgrp); > raw_spin_lock(&ve->per_cgroot_list_lock); > list_for_each_entry_safe(data, saved, &ve->per_cgroot_list, list) { > - release_agent = data->release_agent_path; > - RCU_INIT_POINTER(data->release_agent_path, NULL); > - if (release_agent) > - kfree_rcu(release_agent, rcu_head); > - list_del_init(&data->list); > - kfree(data); > + if (!cgrp || data->cgroot == cgrp) { > + list_del_init(&data->list); > + per_cgroot_data_free(data); > + } > } > raw_spin_unlock(&ve->per_cgroot_list_lock); > + rcu_read_unlock(); > } > > void ve_stop_ns(struct pid_namespace *pid_ns) > @@ -812,7 +824,7 @@ void ve_exit_ns(struct pid_namespace *pid_ns) > > ve_workqueue_stop(ve); > > - ve_per_cgroot_free(ve); > + ve_cleanup_per_cgroot_data(ve, NULL); > > /* > * At this point all userspace tasks in container are dead. > _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
