Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: expose sk wmem in sock_exceed_buf_limit tracepoint

Currently trace_sock_exceed_buf_limit() only show rmem info,
but wmem limit may also be hit.
So expose wmem info in this tracepoint as well.

Regarding memcg, I think it is better to introduce a new tracepoint(if
that is needed), i.e. trace_memcg_limit_hit other than show memcg info in
trace_sock_exceed_buf_limit.

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Yafang Shao and committed by
David S. Miller
d6f19938 335c997d

+29 -7
+25 -5
include/trace/events/sock.h
··· 35 35 EM(TCP_CLOSING) \ 36 36 EMe(TCP_NEW_SYN_RECV) 37 37 38 + #define skmem_kind_names \ 39 + EM(SK_MEM_SEND) \ 40 + EMe(SK_MEM_RECV) 41 + 38 42 /* enums need to be exported to user space */ 39 43 #undef EM 40 44 #undef EMe ··· 48 44 family_names 49 45 inet_protocol_names 50 46 tcp_state_names 47 + skmem_kind_names 51 48 52 49 #undef EM 53 50 #undef EMe ··· 63 58 64 59 #define show_tcp_state_name(val) \ 65 60 __print_symbolic(val, tcp_state_names) 61 + 62 + #define show_skmem_kind_names(val) \ 63 + __print_symbolic(val, skmem_kind_names) 66 64 67 65 TRACE_EVENT(sock_rcvqueue_full, 68 66 ··· 91 83 92 84 TRACE_EVENT(sock_exceed_buf_limit, 93 85 94 - TP_PROTO(struct sock *sk, struct proto *prot, long allocated), 86 + TP_PROTO(struct sock *sk, struct proto *prot, long allocated, int kind), 95 87 96 - TP_ARGS(sk, prot, allocated), 88 + TP_ARGS(sk, prot, allocated, kind), 97 89 98 90 TP_STRUCT__entry( 99 91 __array(char, name, 32) ··· 101 93 __field(long, allocated) 102 94 __field(int, sysctl_rmem) 103 95 __field(int, rmem_alloc) 96 + __field(int, sysctl_wmem) 97 + __field(int, wmem_alloc) 98 + __field(int, wmem_queued) 99 + __field(int, kind) 104 100 ), 105 101 106 102 TP_fast_assign( ··· 113 101 __entry->allocated = allocated; 114 102 __entry->sysctl_rmem = sk_get_rmem0(sk, prot); 115 103 __entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc); 104 + __entry->sysctl_wmem = sk_get_wmem0(sk, prot); 105 + __entry->wmem_alloc = refcount_read(&sk->sk_wmem_alloc); 106 + __entry->wmem_queued = sk->sk_wmem_queued; 107 + __entry->kind = kind; 116 108 ), 117 109 118 - TP_printk("proto:%s sysctl_mem=%ld,%ld,%ld allocated=%ld " 119 - "sysctl_rmem=%d rmem_alloc=%d", 110 + TP_printk("proto:%s sysctl_mem=%ld,%ld,%ld allocated=%ld sysctl_rmem=%d rmem_alloc=%d sysctl_wmem=%d wmem_alloc=%d wmem_queued=%d kind=%s", 120 111 __entry->name, 121 112 __entry->sysctl_mem[0], 122 113 __entry->sysctl_mem[1], 123 114 __entry->sysctl_mem[2], 124 115 __entry->allocated, 125 116 __entry->sysctl_rmem, 126 - __entry->rmem_alloc) 117 + __entry->rmem_alloc, 118 + __entry->sysctl_wmem, 119 + __entry->wmem_alloc, 120 + __entry->wmem_queued, 121 + show_skmem_kind_names(__entry->kind) 122 + ) 127 123 ); 128 124 129 125 TRACE_EVENT(inet_sock_set_state,
+4 -2
net/core/sock.c
··· 2401 2401 { 2402 2402 struct proto *prot = sk->sk_prot; 2403 2403 long allocated = sk_memory_allocated_add(sk, amt); 2404 + bool charged = true; 2404 2405 2405 2406 if (mem_cgroup_sockets_enabled && sk->sk_memcg && 2406 - !mem_cgroup_charge_skmem(sk->sk_memcg, amt)) 2407 + !(charged = mem_cgroup_charge_skmem(sk->sk_memcg, amt))) 2407 2408 goto suppress_allocation; 2408 2409 2409 2410 /* Under limit. */ ··· 2462 2461 return 1; 2463 2462 } 2464 2463 2465 - trace_sock_exceed_buf_limit(sk, prot, allocated); 2464 + if (kind == SK_MEM_SEND || (kind == SK_MEM_RECV && charged)) 2465 + trace_sock_exceed_buf_limit(sk, prot, allocated, kind); 2466 2466 2467 2467 sk_memory_allocated_sub(sk, amt); 2468 2468