sock: introduce SO_MEMINFO getsockopt
authorJosh Hunt <johunt@akamai.com>
Mon, 20 Mar 2017 19:22:03 +0000 (15:22 -0400)
committerDavid S. Miller <davem@davemloft.net>
Wed, 22 Mar 2017 18:18:58 +0000 (11:18 -0700)
Allows reading of SK_MEMINFO_VARS via socket option. This way an
application can get all meminfo related information in single socket
option call instead of multiple calls.

Adds helper function, sk_get_meminfo(), and uses that for both
getsockopt and sock_diag_put_meminfo().

Suggested by Eric Dumazet.

Signed-off-by: Josh Hunt <johunt@akamai.com>
Reviewed-by: Jason Baron <jbaron@akamai.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
16 files changed:
arch/alpha/include/uapi/asm/socket.h
arch/avr32/include/uapi/asm/socket.h
arch/frv/include/uapi/asm/socket.h
arch/ia64/include/uapi/asm/socket.h
arch/m32r/include/uapi/asm/socket.h
arch/mips/include/uapi/asm/socket.h
arch/mn10300/include/uapi/asm/socket.h
arch/parisc/include/uapi/asm/socket.h
arch/powerpc/include/uapi/asm/socket.h
arch/s390/include/uapi/asm/socket.h
arch/sparc/include/uapi/asm/socket.h
arch/xtensa/include/uapi/asm/socket.h
include/net/sock.h
include/uapi/asm-generic/socket.h
net/core/sock.c
net/core/sock_diag.c

index afc901b7a6f6e68c819aec1ab9199806f24fc1c1..089db42c1b40275e4ebbaf295e82ede323a74da5 100644 (file)
@@ -99,4 +99,6 @@
 
 #define SCM_TIMESTAMPING_OPT_STATS     54
 
+#define SO_MEMINFO             55
+
 #endif /* _UAPI_ASM_SOCKET_H */
index 5a650426f35703e82db1149a4049b8575b21d85f..6eabcbd2f82a3a410835a2653a81a071b4d395a5 100644 (file)
@@ -92,4 +92,6 @@
 
 #define SCM_TIMESTAMPING_OPT_STATS     54
 
+#define SO_MEMINFO             55
+
 #endif /* _UAPI__ASM_AVR32_SOCKET_H */
index 81e03530ed39ee7e3b25b7442361f64aa883c179..bd497f8356b98d1656142bef775bec69c64d446a 100644 (file)
@@ -92,5 +92,7 @@
 
 #define SCM_TIMESTAMPING_OPT_STATS     54
 
+#define SO_MEMINFO             55
+
 #endif /* _ASM_SOCKET_H */
 
index 57feb0c1f7d707dd51ce20ffba0a418f5b5687ff..f1bb546861687fd8947738e16dfd7b02d189082b 100644 (file)
 
 #define SCM_TIMESTAMPING_OPT_STATS     54
 
+#define SO_MEMINFO             55
+
 #endif /* _ASM_IA64_SOCKET_H */
index 5853f8e92c20cda02450346d839b3f0b466359ee..459c46076f6f8b8f30b1cccd916e63c29c62bc6f 100644 (file)
@@ -92,4 +92,6 @@
 
 #define SCM_TIMESTAMPING_OPT_STATS     54
 
+#define SO_MEMINFO             55
+
 #endif /* _ASM_M32R_SOCKET_H */
index 566ecdcb5b4bcb2cd4d5888a1ce787b8fcbd0b97..688c18dd62ef69b382e7b78ed28cbfe2b2d06160 100644 (file)
 
 #define SCM_TIMESTAMPING_OPT_STATS     54
 
+#define SO_MEMINFO             55
+
+
 #endif /* _UAPI_ASM_SOCKET_H */
index 0e12527c4b0e6de154efaa91fe197eb995a1535c..312d2c457a047b69b27f3a2e245f1f17bb5f94ef 100644 (file)
@@ -92,4 +92,6 @@
 
 #define SCM_TIMESTAMPING_OPT_STATS     54
 
+#define SO_MEMINFO             55
+
 #endif /* _ASM_SOCKET_H */
index 7a109b73ddf7e814f9c29ffa1ec9b99977ead5d1..b98ec38f208331f6c117df77f5b24e94fdcf200e 100644 (file)
@@ -91,4 +91,6 @@
 
 #define SCM_TIMESTAMPING_OPT_STATS     0x402F
 
+#define SO_MEMINFO             0x4030
+
 #endif /* _UAPI_ASM_SOCKET_H */
index 44583a52f882540986928cc48a63971251226a0f..099a889240f6706ba41f504b7faf899e2fa53f39 100644 (file)
@@ -99,4 +99,6 @@
 
 #define SCM_TIMESTAMPING_OPT_STATS     54
 
+#define SO_MEMINFO             55
+
 #endif /* _ASM_POWERPC_SOCKET_H */
index b24a64cbfeb10a91274a59117f2e76ea3c583e00..6199bb34f7fa67ced2068f1c3730612162a80e20 100644 (file)
@@ -98,4 +98,6 @@
 
 #define SCM_TIMESTAMPING_OPT_STATS     54
 
+#define        SO_MEMINFO              55
+
 #endif /* _ASM_SOCKET_H */
index a25dc32f5d6a163c1b0e7b7ae775f43898ba4d58..12cd8c2ec42282a0ed4b01dfa00c31126f680ac6 100644 (file)
@@ -88,6 +88,8 @@
 
 #define SCM_TIMESTAMPING_OPT_STATS     0x0038
 
+#define SO_MEMINFO             0x0039
+
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION             0x5001
 #define SO_SECURITY_ENCRYPTION_TRANSPORT       0x5002
index 9fdbe1fe0473802caaf04782f9a5c05ca813f013..d0b85f6c14840f5749f46b8991ed8b3e72f2e76d 100644 (file)
 
 #define SCM_TIMESTAMPING_OPT_STATS     54
 
+#define SO_MEMINFO             55
+
 #endif /* _XTENSA_SOCKET_H */
index 08142be8938e4a758a13887e7a4cc3a3cc2da56c..cb241a0e8434ca951b57c8f4aa253d80121c19d7 100644 (file)
@@ -2362,6 +2362,8 @@ bool sk_ns_capable(const struct sock *sk,
 bool sk_capable(const struct sock *sk, int cap);
 bool sk_net_capable(const struct sock *sk, int cap);
 
+void sk_get_meminfo(const struct sock *sk, u32 *meminfo);
+
 extern __u32 sysctl_wmem_max;
 extern __u32 sysctl_rmem_max;
 
index 2c748ddad5f875711ed66f91eae9bc69b9a41fe0..8313702c1eae5c684251c3105e3170a5a3a6a6d2 100644 (file)
@@ -94,4 +94,6 @@
 
 #define SCM_TIMESTAMPING_OPT_STATS     54
 
+#define SO_MEMINFO             55
+
 #endif /* __ASM_GENERIC_SOCKET_H */
index a83731c367619d55c8aa883c5583830c18533676..f8c0373a3a740a88eea8d3eab5441fcc4855f289 100644 (file)
@@ -1313,6 +1313,21 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                v.val = sk->sk_incoming_cpu;
                break;
 
+       case SO_MEMINFO:
+       {
+               u32 meminfo[SK_MEMINFO_VARS];
+
+               if (get_user(len, optlen))
+                       return -EFAULT;
+
+               sk_get_meminfo(sk, meminfo);
+
+               len = min_t(unsigned int, len, sizeof(meminfo));
+               if (copy_to_user(optval, &meminfo, len))
+                       return -EFAULT;
+
+               goto lenout;
+       }
        default:
                /* We implement the SO_SNDLOWAT etc to not be settable
                 * (1003.1g 7).
@@ -2861,6 +2876,21 @@ void sk_common_release(struct sock *sk)
 }
 EXPORT_SYMBOL(sk_common_release);
 
+void sk_get_meminfo(const struct sock *sk, u32 *mem)
+{
+       memset(mem, 0, sizeof(*mem) * SK_MEMINFO_VARS);
+
+       mem[SK_MEMINFO_RMEM_ALLOC] = sk_rmem_alloc_get(sk);
+       mem[SK_MEMINFO_RCVBUF] = sk->sk_rcvbuf;
+       mem[SK_MEMINFO_WMEM_ALLOC] = sk_wmem_alloc_get(sk);
+       mem[SK_MEMINFO_SNDBUF] = sk->sk_sndbuf;
+       mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc;
+       mem[SK_MEMINFO_WMEM_QUEUED] = sk->sk_wmem_queued;
+       mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc);
+       mem[SK_MEMINFO_BACKLOG] = sk->sk_backlog.len;
+       mem[SK_MEMINFO_DROPS] = atomic_read(&sk->sk_drops);
+}
+
 #ifdef CONFIG_PROC_FS
 #define PROTO_INUSE_NR 64      /* should be enough for the first time */
 struct prot_inuse {
index 6b10573cc9faa790fe261b452b85f3b774c3ec21..8d11ee75a100c9e38d1ae5119a5cad000aabd5df 100644 (file)
@@ -59,15 +59,7 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype)
 {
        u32 mem[SK_MEMINFO_VARS];
 
-       mem[SK_MEMINFO_RMEM_ALLOC] = sk_rmem_alloc_get(sk);
-       mem[SK_MEMINFO_RCVBUF] = sk->sk_rcvbuf;
-       mem[SK_MEMINFO_WMEM_ALLOC] = sk_wmem_alloc_get(sk);
-       mem[SK_MEMINFO_SNDBUF] = sk->sk_sndbuf;
-       mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc;
-       mem[SK_MEMINFO_WMEM_QUEUED] = sk->sk_wmem_queued;
-       mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc);
-       mem[SK_MEMINFO_BACKLOG] = sk->sk_backlog.len;
-       mem[SK_MEMINFO_DROPS] = atomic_read(&sk->sk_drops);
+       sk_get_meminfo(sk, mem);
 
        return nla_put(skb, attrtype, sizeof(mem), &mem);
 }