66
66
#include "internal.h"
67
67
#include <net/sock.h>
68
68
#include <net/ip.h>
69
- #include <net/tcp_memcontrol.h>
70
69
#include "slab.h"
71
70
72
71
#include <asm/uaccess.h>
@@ -242,6 +241,7 @@ enum res_type {
242
241
_MEMSWAP ,
243
242
_OOM_TYPE ,
244
243
_KMEM ,
244
+ _TCP ,
245
245
};
246
246
247
247
#define MEMFILE_PRIVATE (x , val ) ((x) << 16 | (val))
@@ -2842,6 +2842,11 @@ static u64 mem_cgroup_read_u64(struct cgroup_subsys_state *css,
2842
2842
case _KMEM :
2843
2843
counter = & memcg -> kmem ;
2844
2844
break ;
2845
+ #if defined(CONFIG_MEMCG_LEGACY_KMEM ) && defined(CONFIG_INET )
2846
+ case _TCP :
2847
+ counter = & memcg -> tcp_mem .memory_allocated ;
2848
+ break ;
2849
+ #endif
2845
2850
default :
2846
2851
BUG ();
2847
2852
}
@@ -3028,6 +3033,48 @@ static int memcg_update_kmem_limit(struct mem_cgroup *memcg,
3028
3033
#endif /* CONFIG_MEMCG_LEGACY_KMEM */
3029
3034
3030
3035
3036
+ #if defined(CONFIG_MEMCG_LEGACY_KMEM ) && defined(CONFIG_INET )
3037
+ static int memcg_update_tcp_limit (struct mem_cgroup * memcg , unsigned long limit )
3038
+ {
3039
+ int ret ;
3040
+
3041
+ mutex_lock (& memcg_limit_mutex );
3042
+
3043
+ ret = page_counter_limit (& memcg -> tcp_mem .memory_allocated , limit );
3044
+ if (ret )
3045
+ goto out ;
3046
+
3047
+ if (!memcg -> tcp_mem .active ) {
3048
+ /*
3049
+ * The active flag needs to be written after the static_key
3050
+ * update. This is what guarantees that the socket activation
3051
+ * function is the last one to run. See sock_update_memcg() for
3052
+ * details, and note that we don't mark any socket as belonging
3053
+ * to this memcg until that flag is up.
3054
+ *
3055
+ * We need to do this, because static_keys will span multiple
3056
+ * sites, but we can't control their order. If we mark a socket
3057
+ * as accounted, but the accounting functions are not patched in
3058
+ * yet, we'll lose accounting.
3059
+ *
3060
+ * We never race with the readers in sock_update_memcg(),
3061
+ * because when this value change, the code to process it is not
3062
+ * patched in yet.
3063
+ */
3064
+ static_branch_inc (& memcg_sockets_enabled_key );
3065
+ memcg -> tcp_mem .active = true;
3066
+ }
3067
+ out :
3068
+ mutex_unlock (& memcg_limit_mutex );
3069
+ return ret ;
3070
+ }
3071
+ #else
3072
+ static int memcg_update_tcp_limit (struct mem_cgroup * memcg , unsigned long limit )
3073
+ {
3074
+ return - EINVAL ;
3075
+ }
3076
+ #endif /* CONFIG_MEMCG_LEGACY_KMEM && CONFIG_INET */
3077
+
3031
3078
/*
3032
3079
* The user of this function is...
3033
3080
* RES_LIMIT.
@@ -3060,6 +3107,9 @@ static ssize_t mem_cgroup_write(struct kernfs_open_file *of,
3060
3107
case _KMEM :
3061
3108
ret = memcg_update_kmem_limit (memcg , nr_pages );
3062
3109
break ;
3110
+ case _TCP :
3111
+ ret = memcg_update_tcp_limit (memcg , nr_pages );
3112
+ break ;
3063
3113
}
3064
3114
break ;
3065
3115
case RES_SOFT_LIMIT :
@@ -3086,6 +3136,11 @@ static ssize_t mem_cgroup_reset(struct kernfs_open_file *of, char *buf,
3086
3136
case _KMEM :
3087
3137
counter = & memcg -> kmem ;
3088
3138
break ;
3139
+ #if defined(CONFIG_MEMCG_LEGACY_KMEM ) && defined(CONFIG_INET )
3140
+ case _TCP :
3141
+ counter = & memcg -> tcp_mem .memory_allocated ;
3142
+ break ;
3143
+ #endif
3089
3144
default :
3090
3145
BUG ();
3091
3146
}
@@ -4072,6 +4127,31 @@ static struct cftype mem_cgroup_legacy_files[] = {
4072
4127
.seq_show = memcg_slab_show ,
4073
4128
},
4074
4129
#endif
4130
+ #ifdef CONFIG_INET
4131
+ {
4132
+ .name = "kmem.tcp.limit_in_bytes" ,
4133
+ .private = MEMFILE_PRIVATE (_TCP , RES_LIMIT ),
4134
+ .write = mem_cgroup_write ,
4135
+ .read_u64 = mem_cgroup_read_u64 ,
4136
+ },
4137
+ {
4138
+ .name = "kmem.tcp.usage_in_bytes" ,
4139
+ .private = MEMFILE_PRIVATE (_TCP , RES_USAGE ),
4140
+ .read_u64 = mem_cgroup_read_u64 ,
4141
+ },
4142
+ {
4143
+ .name = "kmem.tcp.failcnt" ,
4144
+ .private = MEMFILE_PRIVATE (_TCP , RES_FAILCNT ),
4145
+ .write = mem_cgroup_reset ,
4146
+ .read_u64 = mem_cgroup_read_u64 ,
4147
+ },
4148
+ {
4149
+ .name = "kmem.tcp.max_usage_in_bytes" ,
4150
+ .private = MEMFILE_PRIVATE (_TCP , RES_MAX_USAGE ),
4151
+ .write = mem_cgroup_reset ,
4152
+ .read_u64 = mem_cgroup_read_u64 ,
4153
+ },
4154
+ #endif
4075
4155
#endif
4076
4156
{ }, /* terminate */
4077
4157
};
@@ -4241,6 +4321,10 @@ mem_cgroup_css_online(struct cgroup_subsys_state *css)
4241
4321
memcg -> soft_limit = PAGE_COUNTER_MAX ;
4242
4322
page_counter_init (& memcg -> memsw , & parent -> memsw );
4243
4323
page_counter_init (& memcg -> kmem , & parent -> kmem );
4324
+ #if defined(CONFIG_MEMCG_LEGACY_KMEM ) && defined(CONFIG_INET )
4325
+ page_counter_init (& memcg -> tcp_mem .memory_allocated ,
4326
+ & parent -> tcp_mem .memory_allocated );
4327
+ #endif
4244
4328
4245
4329
/*
4246
4330
* No need to take a reference to the parent because cgroup
@@ -4252,6 +4336,9 @@ mem_cgroup_css_online(struct cgroup_subsys_state *css)
4252
4336
memcg -> soft_limit = PAGE_COUNTER_MAX ;
4253
4337
page_counter_init (& memcg -> memsw , NULL );
4254
4338
page_counter_init (& memcg -> kmem , NULL );
4339
+ #if defined(CONFIG_MEMCG_LEGACY_KMEM ) && defined(CONFIG_INET )
4340
+ page_counter_init (& memcg -> tcp_mem .memory_allocated , NULL );
4341
+ #endif
4255
4342
/*
4256
4343
* Deeper hierachy with use_hierarchy == false doesn't make
4257
4344
* much sense so let cgroup subsystem know about this
@@ -4267,12 +4354,6 @@ mem_cgroup_css_online(struct cgroup_subsys_state *css)
4267
4354
return ret ;
4268
4355
4269
4356
#ifdef CONFIG_INET
4270
- #ifdef CONFIG_MEMCG_LEGACY_KMEM
4271
- ret = tcp_init_cgroup (memcg );
4272
- if (ret )
4273
- return ret ;
4274
- #endif
4275
-
4276
4357
if (cgroup_subsys_on_dfl (memory_cgrp_subsys ) && !cgroup_memory_nosocket )
4277
4358
static_branch_inc (& memcg_sockets_enabled_key );
4278
4359
#endif
@@ -4330,7 +4411,8 @@ static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
4330
4411
memcg_free_kmem (memcg );
4331
4412
4332
4413
#if defined(CONFIG_MEMCG_LEGACY_KMEM ) && defined(CONFIG_INET )
4333
- tcp_destroy_cgroup (memcg );
4414
+ if (memcg -> tcp_mem .active )
4415
+ static_branch_dec (& memcg_sockets_enabled_key );
4334
4416
#endif
4335
4417
4336
4418
__mem_cgroup_free (memcg );
0 commit comments