OpenVZ Forum - RDF feed
type: channel
items: [PATCH v3 2/2] decrement static keys on real destroy time
items: Re: [PATCH v3 2/2] decrement static keys on real destroy time

[PATCH v3 2/2] decrement static keys on real destroy time
type: item
description: We call the destroy function when a cgroup starts to be removed, such as by a rmdir event. However, because of our reference counters, some objects are still inflight. Right now, we are decrementing the static_keys at destroy() time, meaning that if we get rid of the last static_key reference, some objects will still have charges, but the code to properly uncharge them won't be run. This becomes a problem specially if it is ever enabled again, because now new charges will be added to the staled charges making keeping it pretty much impossible. We just need to be careful with the static branch activation: since there is no particular preferred order of their activation, we need to make sure that we only start using it after all call sites are active. This is achieved by having a per-memcg flag that is only updated after static_key_slow_inc() returns. At this time, we are sure all sites are active. This is made per-memcg, not global, for a reason: it also has the effect of making socket accounting more consistent. The first memcg to be limited will trigger static_key() activation, therefore, accounting. But all the others will then be accounted no matter what. After this patch, only limited memcgs will have its sockets accounted. [v2: changed a tcp limited flag for a generic proto limited flag ] [v3: update the current active flag only after the static_key update ] [v4: disarm_static_keys() inside free_work ] Signed-off-by: Glauber Costa <glommer@parallels.com> --- include/net/sock.h | 9 ++++++ mm/memcontrol.c | 31 ++++++++++++++++++- net/ipv4/tcp_memcontrol.c | 70 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 101 insertions(+), 9 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index b3ebe6b..c5a2010 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -914,6 +914,15 @@ struct cg_proto { int *memory_pressure; long *sysctl_mem; /* + * active means it is currently active, and new sockets should + * be assigned to cgroups. + * + *…
creator: Glauber Costa
date: 2012-04-26T21:24:23-00:00

Re: [PATCH v3 2/2] decrement static keys on real destroy time
type: item
description: Hello, Glauber. Overall, I like this approach much better. Just some nits below. On Thu, Apr 26, 2012 at 06:24:23PM -0300, Glauber Costa wrote: > @@ -4836,6 +4851,18 @@ static void free_work(struct work_struct *work) > int size = sizeof(struct mem_cgroup); > > memcg = container_of(work, struct mem_cgroup, work_freeing); > + /* > + * We need to make sure that (at least for now), the jump label > + * destruction code runs outside of the cgroup lock. It is in theory > + * possible to call the cgroup destruction function outside of that > + * lock, but it is not yet done. rate limiting plus the deferred > + * interface for static_branch destruction guarantees that it will > + * run through schedule_work(), therefore, not holding any cgroup > + * related lock (this is, of course, until someone decides to write > + * a schedule_work cgroup :p ) > + */ Isn't the above a bit too verbose? Wouldn't just stating the locking dependency be enough? > + disarm_static_keys(memcg); > if (size < PAGE_SIZE) > kfree(memcg); > else > diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c > index 1517037..7790008 100644 > --- a/net/ipv4/tcp_memcontrol.c > +++ b/net/ipv4/tcp_memcontrol.c > @@ -54,6 +54,8 @@ int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss) > cg_proto->sysctl_mem = tcp->tcp_prot_mem; > cg_proto->memory_allocated = &tcp->tcp_memory_allocated; > cg_proto->sockets_allocated = &tcp->tcp_sockets_allocated; > + cg_proto->active = false; > + cg_proto->activated = false; Isn't the memory zallocd? I find 0 / NULL / false inits unnecessary and even misleading (can the memory be non-zero here?). Another side effect is that it tends to get out of sync as more fields are added. > +/* > + * This is to prevent two writes arriving at the same time > + * at kmem.tcp.limit_in_bytes. > + * > + * There is a race at the first time we write to this file: > + * > + * - cg_proto->activated == false for all writers. > + * - They all do a static_key_slow_inc(). > +…
creator: Tejun Heo
date: 2012-04-26T21:39:16-00:00

Re: [PATCH v3 2/2] decrement static keys on real destroy time
type: item
description: On 04/26/2012 06:39 PM, Tejun Heo wrote: > Hello, Glauber. > > Overall, I like this approach much better. Just some nits below. > > On Thu, Apr 26, 2012 at 06:24:23PM -0300, Glauber Costa wrote: >> @@ -4836,6 +4851,18 @@ static void free_work(struct work_struct *work) >> int size = sizeof(struct mem_cgroup); >> >> memcg = container_of(work, struct mem_cgroup, work_freeing); >> + /* >> + * We need to make sure that (at least for now), the jump label >> + * destruction code runs outside of the cgroup lock. It is in theory >> + * possible to call the cgroup destruction function outside of that >> + * lock, but it is not yet done. rate limiting plus the deferred >> + * interface for static_branch destruction guarantees that it will >> + * run through schedule_work(), therefore, not holding any cgroup >> + * related lock (this is, of course, until someone decides to write >> + * a schedule_work cgroup :p ) >> + */ > > Isn't the above a bit too verbose? Wouldn't just stating the locking > dependency be enough? I used a lot of verbosity here because it is a tricky and racy issue. I am fine with trimming the comments if this is considered too much. >> cg_proto->sysctl_mem = tcp->tcp_prot_mem; >> cg_proto->memory_allocated =&tcp->tcp_memory_allocated; >> cg_proto->sockets_allocated =&tcp->tcp_sockets_allocated; >> + cg_proto->active = false; >> + cg_proto->activated = false; > > Isn't the memory zallocd? I find 0 / NULL / false inits unnecessary > and even misleading (can the memory be non-zero here?). Another side > effect is that it tends to get out of sync as more fields are added. I can take them off. > >> +/* >> + * This is to prevent two writes arriving at the same time >> + * at kmem.tcp.limit_in_bytes. >> + * >> + * There is a race at the first time we write to this file: >> + * >> + * - cg_proto->activated == false for all writers. >> + * - They all do a static_key_slow_inc(). >> + * - When we are finally read to decrement the static_keys, > ^ > ready Thanks. >> + *…
creator: Glauber Costa
date: 2012-04-26T21:58:37-00:00

Re: [PATCH v3 2/2] decrement static keys on real destroy time
type: item
description: Hello, Glauber. On Thu, Apr 26, 2012 at 06:58:37PM -0300, Glauber Costa wrote: > At first I though that we could get rid of all this complication by > calling stop machine from the static_branch API. This would all > magically go away. I actually even tried it. > > However, reading the code for other architectures (other than x86), > I found that they usually rely on the fixed instruction size to just > patch an instruction atomically and go home happy. > > Using stop machine and the like would slow them down considerably. > Not only slow down the static branch update (which is acceptable), > but everybody else (which is horrible). It seemed to defeat the > purpose of static branches a bit. > > The other users of static branches seems to be fine coping with the > fact that in cases with multiple-sites, they will spread in time. No, what I mean is that why can't you do about the same mutexed activated inside static_key API function instead of requiring every user to worry about the function returning asynchronously. ie. synchronize inside static_key API instead of in the callers. Thanks. -- tejun
creator: Tejun Heo
date: 2012-04-26T22:13:24-00:00

Re: [PATCH v3 2/2] decrement static keys on real destroy time
type: item
description: > No, what I mean is that why can't you do about the same mutexed > activated inside static_key API function instead of requiring every > user to worry about the function returning asynchronously. > ie. synchronize inside static_key API instead of in the callers. > Like this?
creator: Glauber Costa
date: 2012-04-26T22:17:36-00:00

Re: [PATCH v3 2/2] decrement static keys on real destroy time
type: item
description: Hello, On Thu, Apr 26, 2012 at 3:17 PM, Glauber Costa <glommer@parallels.com> wrote: > >> No, what I mean is that why can't you do about the same mutexed >> activated inside static_key API function instead of requiring every >> user to worry about the function returning asynchronously. >> ie. synchronize inside static_key API instead of in the callers. >> > > Like this? Yeah, something like that. If keeping the inc operation a single atomic op is important for performance or whatever reasons, you can play some trick with large negative bias value while activation is going on and use atomic_add_return() to determine both whether it's the first incrementer and someone else is in the process of activating. Thanks. -- tejun
creator: Tejun Heo
date: 2012-04-26T22:22:33-00:00

Re: [PATCH v3 2/2] decrement static keys on real destroy time
type: item
description: On 04/26/2012 07:22 PM, Tejun Heo wrote: > Hello, > > On Thu, Apr 26, 2012 at 3:17 PM, Glauber Costa<glommer@parallels.com> wrote: >> >>> No, what I mean is that why can't you do about the same mutexed >>> activated inside static_key API function instead of requiring every >>> user to worry about the function returning asynchronously. >>> ie. synchronize inside static_key API instead of in the callers. >>> >> >> Like this? > > Yeah, something like that. If keeping the inc operation a single > atomic op is important for performance or whatever reasons, you can > play some trick with large negative bias value while activation is > going on and use atomic_add_return() to determine both whether it's > the first incrementer and someone else is in the process of > activating. > > Thanks. > We need a broader audience for this, but if I understand the interface right, those functions should not be called in fast paths at all (contrary to the static_branch tests) The static_branch tests can be called from irq context, so we can't just get rid of the atomic op and use the mutex everywhere, we'd have to live with both. I will repost this series, with some more people in the CC list.
creator: Glauber Costa
date: 2012-04-26T22:28:39-00:00

Re: [PATCH v3 2/2] decrement static keys on real destroy time
type: item
description: On Thu, Apr 26, 2012 at 3:28 PM, Glauber Costa <glommer@parallels.com> wrote: > We need a broader audience for this, but if I understand the interface > right, those functions should not be called in fast paths at all (contrary > to the static_branch tests) > > The static_branch tests can be called from irq context, so we can't just get > rid of the atomic op and use the mutex everywhere, we'd have > to live with both. > > I will repost this series, with some more people in the CC list. Great, thanks! -- tejun
creator: Tejun Heo
date: 2012-04-26T22:32:14-00:00