diff options
author | Glauber Costa <glommer@parallels.com> | 2011-12-11 16:47:02 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-12 19:04:10 -0500 |
commit | 180d8cd942ce336b2c869d324855c40c5db478ad (patch) | |
tree | 2424d854345d81464d6030ef8090a8e22bd414b0 /include | |
parent | e5671dfae59b165e2adfd4dfbdeab11ac8db5bda (diff) |
foundations of per-cgroup memory pressure controlling.
This patch replaces all uses of struct sock fields' memory_pressure,
memory_allocated, sockets_allocated, and sysctl_mem to acessor
macros. Those macros can either receive a socket argument, or a mem_cgroup
argument, depending on the context they live in.
Since we're only doing a macro wrapping here, no performance impact at all is
expected in the case where we don't have cgroups disabled.
Signed-off-by: Glauber Costa <glommer@parallels.com>
Reviewed-by: Hiroyouki Kamezawa <kamezawa.hiroyu@jp.fujitsu.com>
CC: David S. Miller <davem@davemloft.net>
CC: Eric W. Biederman <ebiederm@xmission.com>
CC: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/net/sock.h | 96 | ||||
-rw-r--r-- | include/net/tcp.h | 3 |
2 files changed, 97 insertions, 2 deletions
diff --git a/include/net/sock.h b/include/net/sock.h index 8ac338cb39ce..ed0dbf034539 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <linux/security.h> | 53 | #include <linux/security.h> |
54 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
55 | #include <linux/uaccess.h> | 55 | #include <linux/uaccess.h> |
56 | #include <linux/memcontrol.h> | ||
56 | 57 | ||
57 | #include <linux/filter.h> | 58 | #include <linux/filter.h> |
58 | #include <linux/rculist_nulls.h> | 59 | #include <linux/rculist_nulls.h> |
@@ -867,6 +868,99 @@ static inline void sk_refcnt_debug_release(const struct sock *sk) | |||
867 | #define sk_refcnt_debug_release(sk) do { } while (0) | 868 | #define sk_refcnt_debug_release(sk) do { } while (0) |
868 | #endif /* SOCK_REFCNT_DEBUG */ | 869 | #endif /* SOCK_REFCNT_DEBUG */ |
869 | 870 | ||
871 | static inline bool sk_has_memory_pressure(const struct sock *sk) | ||
872 | { | ||
873 | return sk->sk_prot->memory_pressure != NULL; | ||
874 | } | ||
875 | |||
876 | static inline bool sk_under_memory_pressure(const struct sock *sk) | ||
877 | { | ||
878 | if (!sk->sk_prot->memory_pressure) | ||
879 | return false; | ||
880 | return !!*sk->sk_prot->memory_pressure; | ||
881 | } | ||
882 | |||
883 | static inline void sk_leave_memory_pressure(struct sock *sk) | ||
884 | { | ||
885 | int *memory_pressure = sk->sk_prot->memory_pressure; | ||
886 | |||
887 | if (memory_pressure && *memory_pressure) | ||
888 | *memory_pressure = 0; | ||
889 | } | ||
890 | |||
891 | static inline void sk_enter_memory_pressure(struct sock *sk) | ||
892 | { | ||
893 | if (sk->sk_prot->enter_memory_pressure) | ||
894 | sk->sk_prot->enter_memory_pressure(sk); | ||
895 | } | ||
896 | |||
897 | static inline long sk_prot_mem_limits(const struct sock *sk, int index) | ||
898 | { | ||
899 | long *prot = sk->sk_prot->sysctl_mem; | ||
900 | return prot[index]; | ||
901 | } | ||
902 | |||
903 | static inline long | ||
904 | sk_memory_allocated(const struct sock *sk) | ||
905 | { | ||
906 | struct proto *prot = sk->sk_prot; | ||
907 | return atomic_long_read(prot->memory_allocated); | ||
908 | } | ||
909 | |||
910 | static inline long | ||
911 | sk_memory_allocated_add(struct sock *sk, int amt) | ||
912 | { | ||
913 | struct proto *prot = sk->sk_prot; | ||
914 | return atomic_long_add_return(amt, prot->memory_allocated); | ||
915 | } | ||
916 | |||
917 | static inline void | ||
918 | sk_memory_allocated_sub(struct sock *sk, int amt) | ||
919 | { | ||
920 | struct proto *prot = sk->sk_prot; | ||
921 | atomic_long_sub(amt, prot->memory_allocated); | ||
922 | } | ||
923 | |||
924 | static inline void sk_sockets_allocated_dec(struct sock *sk) | ||
925 | { | ||
926 | struct proto *prot = sk->sk_prot; | ||
927 | percpu_counter_dec(prot->sockets_allocated); | ||
928 | } | ||
929 | |||
930 | static inline void sk_sockets_allocated_inc(struct sock *sk) | ||
931 | { | ||
932 | struct proto *prot = sk->sk_prot; | ||
933 | percpu_counter_inc(prot->sockets_allocated); | ||
934 | } | ||
935 | |||
936 | static inline int | ||
937 | sk_sockets_allocated_read_positive(struct sock *sk) | ||
938 | { | ||
939 | struct proto *prot = sk->sk_prot; | ||
940 | |||
941 | return percpu_counter_sum_positive(prot->sockets_allocated); | ||
942 | } | ||
943 | |||
944 | static inline int | ||
945 | proto_sockets_allocated_sum_positive(struct proto *prot) | ||
946 | { | ||
947 | return percpu_counter_sum_positive(prot->sockets_allocated); | ||
948 | } | ||
949 | |||
950 | static inline long | ||
951 | proto_memory_allocated(struct proto *prot) | ||
952 | { | ||
953 | return atomic_long_read(prot->memory_allocated); | ||
954 | } | ||
955 | |||
956 | static inline bool | ||
957 | proto_memory_pressure(struct proto *prot) | ||
958 | { | ||
959 | if (!prot->memory_pressure) | ||
960 | return false; | ||
961 | return !!*prot->memory_pressure; | ||
962 | } | ||
963 | |||
870 | 964 | ||
871 | #ifdef CONFIG_PROC_FS | 965 | #ifdef CONFIG_PROC_FS |
872 | /* Called with local bh disabled */ | 966 | /* Called with local bh disabled */ |
@@ -1674,7 +1768,7 @@ static inline struct page *sk_stream_alloc_page(struct sock *sk) | |||
1674 | 1768 | ||
1675 | page = alloc_pages(sk->sk_allocation, 0); | 1769 | page = alloc_pages(sk->sk_allocation, 0); |
1676 | if (!page) { | 1770 | if (!page) { |
1677 | sk->sk_prot->enter_memory_pressure(sk); | 1771 | sk_enter_memory_pressure(sk); |
1678 | sk_stream_moderate_sndbuf(sk); | 1772 | sk_stream_moderate_sndbuf(sk); |
1679 | } | 1773 | } |
1680 | return page; | 1774 | return page; |
diff --git a/include/net/tcp.h b/include/net/tcp.h index 02f070d339ba..913473b4eda7 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <net/dst.h> | 44 | #include <net/dst.h> |
45 | 45 | ||
46 | #include <linux/seq_file.h> | 46 | #include <linux/seq_file.h> |
47 | #include <linux/memcontrol.h> | ||
47 | 48 | ||
48 | extern struct inet_hashinfo tcp_hashinfo; | 49 | extern struct inet_hashinfo tcp_hashinfo; |
49 | 50 | ||
@@ -285,7 +286,7 @@ static inline bool tcp_too_many_orphans(struct sock *sk, int shift) | |||
285 | } | 286 | } |
286 | 287 | ||
287 | if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && | 288 | if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF && |
288 | atomic_long_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]) | 289 | sk_memory_allocated(sk) > sk_prot_mem_limits(sk, 2)) |
289 | return true; | 290 | return true; |
290 | return false; | 291 | return false; |
291 | } | 292 | } |