tcp_memcontrol.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. #include <net/tcp.h>
  2. #include <net/tcp_memcontrol.h>
  3. #include <net/sock.h>
  4. #include <net/ip.h>
  5. #include <linux/nsproxy.h>
  6. #include <linux/memcontrol.h>
  7. #include <linux/module.h>
  8. static u64 tcp_cgroup_read(struct cgroup *cont, struct cftype *cft);
  9. static int tcp_cgroup_write(struct cgroup *cont, struct cftype *cft,
  10. const char *buffer);
  11. static int tcp_cgroup_reset(struct cgroup *cont, unsigned int event);
  12. static struct cftype tcp_files[] = {
  13. {
  14. .name = "kmem.tcp.limit_in_bytes",
  15. .write_string = tcp_cgroup_write,
  16. .read_u64 = tcp_cgroup_read,
  17. .private = RES_LIMIT,
  18. },
  19. {
  20. .name = "kmem.tcp.usage_in_bytes",
  21. .read_u64 = tcp_cgroup_read,
  22. .private = RES_USAGE,
  23. },
  24. {
  25. .name = "kmem.tcp.failcnt",
  26. .private = RES_FAILCNT,
  27. .trigger = tcp_cgroup_reset,
  28. .read_u64 = tcp_cgroup_read,
  29. },
  30. {
  31. .name = "kmem.tcp.max_usage_in_bytes",
  32. .private = RES_MAX_USAGE,
  33. .trigger = tcp_cgroup_reset,
  34. .read_u64 = tcp_cgroup_read,
  35. },
  36. };
  37. static inline struct tcp_memcontrol *tcp_from_cgproto(struct cg_proto *cg_proto)
  38. {
  39. return container_of(cg_proto, struct tcp_memcontrol, cg_proto);
  40. }
  41. static void memcg_tcp_enter_memory_pressure(struct sock *sk)
  42. {
  43. if (sk->sk_cgrp->memory_pressure)
  44. *sk->sk_cgrp->memory_pressure = 1;
  45. }
  46. EXPORT_SYMBOL(memcg_tcp_enter_memory_pressure);
  47. int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
  48. {
  49. /*
  50. * The root cgroup does not use res_counters, but rather,
  51. * rely on the data already collected by the network
  52. * subsystem
  53. */
  54. struct res_counter *res_parent = NULL;
  55. struct cg_proto *cg_proto, *parent_cg;
  56. struct tcp_memcontrol *tcp;
  57. struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
  58. struct mem_cgroup *parent = parent_mem_cgroup(memcg);
  59. struct net *net = current->nsproxy->net_ns;
  60. cg_proto = tcp_prot.proto_cgroup(memcg);
  61. if (!cg_proto)
  62. goto create_files;
  63. tcp = tcp_from_cgproto(cg_proto);
  64. tcp->tcp_prot_mem[0] = net->ipv4.sysctl_tcp_mem[0];
  65. tcp->tcp_prot_mem[1] = net->ipv4.sysctl_tcp_mem[1];
  66. tcp->tcp_prot_mem[2] = net->ipv4.sysctl_tcp_mem[2];
  67. tcp->tcp_memory_pressure = 0;
  68. parent_cg = tcp_prot.proto_cgroup(parent);
  69. if (parent_cg)
  70. res_parent = parent_cg->memory_allocated;
  71. res_counter_init(&tcp->tcp_memory_allocated, res_parent);
  72. percpu_counter_init(&tcp->tcp_sockets_allocated, 0);
  73. cg_proto->enter_memory_pressure = memcg_tcp_enter_memory_pressure;
  74. cg_proto->memory_pressure = &tcp->tcp_memory_pressure;
  75. cg_proto->sysctl_mem = tcp->tcp_prot_mem;
  76. cg_proto->memory_allocated = &tcp->tcp_memory_allocated;
  77. cg_proto->sockets_allocated = &tcp->tcp_sockets_allocated;
  78. cg_proto->memcg = memcg;
  79. create_files:
  80. return cgroup_add_files(cgrp, ss, tcp_files,
  81. ARRAY_SIZE(tcp_files));
  82. }
  83. EXPORT_SYMBOL(tcp_init_cgroup);
  84. void tcp_destroy_cgroup(struct cgroup *cgrp)
  85. {
  86. struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
  87. struct cg_proto *cg_proto;
  88. struct tcp_memcontrol *tcp;
  89. u64 val;
  90. cg_proto = tcp_prot.proto_cgroup(memcg);
  91. if (!cg_proto)
  92. return;
  93. tcp = tcp_from_cgproto(cg_proto);
  94. percpu_counter_destroy(&tcp->tcp_sockets_allocated);
  95. val = res_counter_read_u64(&tcp->tcp_memory_allocated, RES_LIMIT);
  96. if (val != RESOURCE_MAX)
  97. static_key_slow_dec(&memcg_socket_limit_enabled);
  98. }
  99. EXPORT_SYMBOL(tcp_destroy_cgroup);
  100. static int tcp_update_limit(struct mem_cgroup *memcg, u64 val)
  101. {
  102. struct net *net = current->nsproxy->net_ns;
  103. struct tcp_memcontrol *tcp;
  104. struct cg_proto *cg_proto;
  105. u64 old_lim;
  106. int i;
  107. int ret;
  108. cg_proto = tcp_prot.proto_cgroup(memcg);
  109. if (!cg_proto)
  110. return -EINVAL;
  111. if (val > RESOURCE_MAX)
  112. val = RESOURCE_MAX;
  113. tcp = tcp_from_cgproto(cg_proto);
  114. old_lim = res_counter_read_u64(&tcp->tcp_memory_allocated, RES_LIMIT);
  115. ret = res_counter_set_limit(&tcp->tcp_memory_allocated, val);
  116. if (ret)
  117. return ret;
  118. for (i = 0; i < 3; i++)
  119. tcp->tcp_prot_mem[i] = min_t(long, val >> PAGE_SHIFT,
  120. net->ipv4.sysctl_tcp_mem[i]);
  121. if (val == RESOURCE_MAX && old_lim != RESOURCE_MAX)
  122. static_key_slow_dec(&memcg_socket_limit_enabled);
  123. else if (old_lim == RESOURCE_MAX && val != RESOURCE_MAX)
  124. static_key_slow_inc(&memcg_socket_limit_enabled);
  125. return 0;
  126. }
  127. static int tcp_cgroup_write(struct cgroup *cont, struct cftype *cft,
  128. const char *buffer)
  129. {
  130. struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
  131. unsigned long long val;
  132. int ret = 0;
  133. switch (cft->private) {
  134. case RES_LIMIT:
  135. /* see memcontrol.c */
  136. ret = res_counter_memparse_write_strategy(buffer, &val);
  137. if (ret)
  138. break;
  139. ret = tcp_update_limit(memcg, val);
  140. break;
  141. default:
  142. ret = -EINVAL;
  143. break;
  144. }
  145. return ret;
  146. }
  147. static u64 tcp_read_stat(struct mem_cgroup *memcg, int type, u64 default_val)
  148. {
  149. struct tcp_memcontrol *tcp;
  150. struct cg_proto *cg_proto;
  151. cg_proto = tcp_prot.proto_cgroup(memcg);
  152. if (!cg_proto)
  153. return default_val;
  154. tcp = tcp_from_cgproto(cg_proto);
  155. return res_counter_read_u64(&tcp->tcp_memory_allocated, type);
  156. }
  157. static u64 tcp_read_usage(struct mem_cgroup *memcg)
  158. {
  159. struct tcp_memcontrol *tcp;
  160. struct cg_proto *cg_proto;
  161. cg_proto = tcp_prot.proto_cgroup(memcg);
  162. if (!cg_proto)
  163. return atomic_long_read(&tcp_memory_allocated) << PAGE_SHIFT;
  164. tcp = tcp_from_cgproto(cg_proto);
  165. return res_counter_read_u64(&tcp->tcp_memory_allocated, RES_USAGE);
  166. }
  167. static u64 tcp_cgroup_read(struct cgroup *cont, struct cftype *cft)
  168. {
  169. struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
  170. u64 val;
  171. switch (cft->private) {
  172. case RES_LIMIT:
  173. val = tcp_read_stat(memcg, RES_LIMIT, RESOURCE_MAX);
  174. break;
  175. case RES_USAGE:
  176. val = tcp_read_usage(memcg);
  177. break;
  178. case RES_FAILCNT:
  179. case RES_MAX_USAGE:
  180. val = tcp_read_stat(memcg, cft->private, 0);
  181. break;
  182. default:
  183. BUG();
  184. }
  185. return val;
  186. }
  187. static int tcp_cgroup_reset(struct cgroup *cont, unsigned int event)
  188. {
  189. struct mem_cgroup *memcg;
  190. struct tcp_memcontrol *tcp;
  191. struct cg_proto *cg_proto;
  192. memcg = mem_cgroup_from_cont(cont);
  193. cg_proto = tcp_prot.proto_cgroup(memcg);
  194. if (!cg_proto)
  195. return 0;
  196. tcp = tcp_from_cgproto(cg_proto);
  197. switch (event) {
  198. case RES_MAX_USAGE:
  199. res_counter_reset_max(&tcp->tcp_memory_allocated);
  200. break;
  201. case RES_FAILCNT:
  202. res_counter_reset_failcnt(&tcp->tcp_memory_allocated);
  203. break;
  204. }
  205. return 0;
  206. }
  207. unsigned long long tcp_max_memory(const struct mem_cgroup *memcg)
  208. {
  209. struct tcp_memcontrol *tcp;
  210. struct cg_proto *cg_proto;
  211. cg_proto = tcp_prot.proto_cgroup((struct mem_cgroup *)memcg);
  212. if (!cg_proto)
  213. return 0;
  214. tcp = tcp_from_cgproto(cg_proto);
  215. return res_counter_read_u64(&tcp->tcp_memory_allocated, RES_LIMIT);
  216. }
  217. void tcp_prot_mem(struct mem_cgroup *memcg, long val, int idx)
  218. {
  219. struct tcp_memcontrol *tcp;
  220. struct cg_proto *cg_proto;
  221. cg_proto = tcp_prot.proto_cgroup(memcg);
  222. if (!cg_proto)
  223. return;
  224. tcp = tcp_from_cgproto(cg_proto);
  225. tcp->tcp_prot_mem[idx] = val;
  226. }