mirror of https://gitee.com/openkylin/linux.git
sock: introduce SO_MEMINFO getsockopt
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>
This commit is contained in:
parent
c7cd4c9bf8
commit
a2d133b1d4
|
@ -99,4 +99,6 @@
|
|||
|
||||
#define SCM_TIMESTAMPING_OPT_STATS 54
|
||||
|
||||
#define SO_MEMINFO 55
|
||||
|
||||
#endif /* _UAPI_ASM_SOCKET_H */
|
||||
|
|
|
@ -92,4 +92,6 @@
|
|||
|
||||
#define SCM_TIMESTAMPING_OPT_STATS 54
|
||||
|
||||
#define SO_MEMINFO 55
|
||||
|
||||
#endif /* _UAPI__ASM_AVR32_SOCKET_H */
|
||||
|
|
|
@ -92,5 +92,7 @@
|
|||
|
||||
#define SCM_TIMESTAMPING_OPT_STATS 54
|
||||
|
||||
#define SO_MEMINFO 55
|
||||
|
||||
#endif /* _ASM_SOCKET_H */
|
||||
|
||||
|
|
|
@ -101,4 +101,6 @@
|
|||
|
||||
#define SCM_TIMESTAMPING_OPT_STATS 54
|
||||
|
||||
#define SO_MEMINFO 55
|
||||
|
||||
#endif /* _ASM_IA64_SOCKET_H */
|
||||
|
|
|
@ -92,4 +92,6 @@
|
|||
|
||||
#define SCM_TIMESTAMPING_OPT_STATS 54
|
||||
|
||||
#define SO_MEMINFO 55
|
||||
|
||||
#endif /* _ASM_M32R_SOCKET_H */
|
||||
|
|
|
@ -110,4 +110,7 @@
|
|||
|
||||
#define SCM_TIMESTAMPING_OPT_STATS 54
|
||||
|
||||
#define SO_MEMINFO 55
|
||||
|
||||
|
||||
#endif /* _UAPI_ASM_SOCKET_H */
|
||||
|
|
|
@ -92,4 +92,6 @@
|
|||
|
||||
#define SCM_TIMESTAMPING_OPT_STATS 54
|
||||
|
||||
#define SO_MEMINFO 55
|
||||
|
||||
#endif /* _ASM_SOCKET_H */
|
||||
|
|
|
@ -91,4 +91,6 @@
|
|||
|
||||
#define SCM_TIMESTAMPING_OPT_STATS 0x402F
|
||||
|
||||
#define SO_MEMINFO 0x4030
|
||||
|
||||
#endif /* _UAPI_ASM_SOCKET_H */
|
||||
|
|
|
@ -99,4 +99,6 @@
|
|||
|
||||
#define SCM_TIMESTAMPING_OPT_STATS 54
|
||||
|
||||
#define SO_MEMINFO 55
|
||||
|
||||
#endif /* _ASM_POWERPC_SOCKET_H */
|
||||
|
|
|
@ -98,4 +98,6 @@
|
|||
|
||||
#define SCM_TIMESTAMPING_OPT_STATS 54
|
||||
|
||||
#define SO_MEMINFO 55
|
||||
|
||||
#endif /* _ASM_SOCKET_H */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -103,4 +103,6 @@
|
|||
|
||||
#define SCM_TIMESTAMPING_OPT_STATS 54
|
||||
|
||||
#define SO_MEMINFO 55
|
||||
|
||||
#endif /* _XTENSA_SOCKET_H */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -94,4 +94,6 @@
|
|||
|
||||
#define SCM_TIMESTAMPING_OPT_STATS 54
|
||||
|
||||
#define SO_MEMINFO 55
|
||||
|
||||
#endif /* __ASM_GENERIC_SOCKET_H */
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue