mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 11:19:37 +00:00
![Kevin Kou](/assets/img/avatar_default.png)
The original patch bringed in the "SCTP ACK tracking trace event" feature was committed at Dec.20, 2017, it replaced jprobe usage with trace events, and bringed in two trace events, one is TRACE_EVENT(sctp_probe), another one is TRACE_EVENT(sctp_probe_path). The original patch intended to trigger the trace_sctp_probe_path in TRACE_EVENT(sctp_probe) as below code, +TRACE_EVENT(sctp_probe, + + TP_PROTO(const struct sctp_endpoint *ep, + const struct sctp_association *asoc, + struct sctp_chunk *chunk), + + TP_ARGS(ep, asoc, chunk), + + TP_STRUCT__entry( + __field(__u64, asoc) + __field(__u32, mark) + __field(__u16, bind_port) + __field(__u16, peer_port) + __field(__u32, pathmtu) + __field(__u32, rwnd) + __field(__u16, unack_data) + ), + + TP_fast_assign( + struct sk_buff *skb = chunk->skb; + + __entry->asoc = (unsigned long)asoc; + __entry->mark = skb->mark; + __entry->bind_port = ep->base.bind_addr.port; + __entry->peer_port = asoc->peer.port; + __entry->pathmtu = asoc->pathmtu; + __entry->rwnd = asoc->peer.rwnd; + __entry->unack_data = asoc->unack_data; + + if (trace_sctp_probe_path_enabled()) { + struct sctp_transport *sp; + + list_for_each_entry(sp, &asoc->peer.transport_addr_list, + transports) { + trace_sctp_probe_path(sp, asoc); + } + } + ), But I found it did not work when I did testing, and trace_sctp_probe_path had no output, I finally found that there is trace buffer lock operation(trace_event_buffer_reserve) in include/trace/trace_events.h: static notrace void \ trace_event_raw_event_##call(void *__data, proto) \ { \ struct trace_event_file *trace_file = __data; \ struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\ struct trace_event_buffer fbuffer; \ struct trace_event_raw_##call *entry; \ int __data_size; \ \ if (trace_trigger_soft_disabled(trace_file)) \ return; \ \ __data_size = trace_event_get_offsets_##call(&__data_offsets, args); \ \ entry = trace_event_buffer_reserve(&fbuffer, trace_file, \ sizeof(*entry) + __data_size); \ \ if (!entry) \ return; \ \ tstruct \ \ { assign; } \ \ trace_event_buffer_commit(&fbuffer); \ } The reason caused no output of trace_sctp_probe_path is that trace_sctp_probe_path written in TP_fast_assign part of TRACE_EVENT(sctp_probe), and it will be placed( { assign; } ) after the trace_event_buffer_reserve() when compiler expands Macro, entry = trace_event_buffer_reserve(&fbuffer, trace_file, \ sizeof(*entry) + __data_size); \ \ if (!entry) \ return; \ \ tstruct \ \ { assign; } \ so trace_sctp_probe_path finally can not acquire trace_event_buffer and return no output, that is to say the nest of tracepoint entry function is not allowed. The function call flow is: trace_sctp_probe() -> trace_event_raw_event_sctp_probe() -> lock buffer -> trace_sctp_probe_path() -> trace_event_raw_event_sctp_probe_path() --nested -> buffer has been locked and return no output. This patch is to remove trace_sctp_probe_path from the TP_fast_assign part of TRACE_EVENT(sctp_probe) to avoid the nest of entry function, and trigger sctp_probe_path_trace in sctp_outq_sack. After this patch, you can enable both events individually, # cd /sys/kernel/debug/tracing # echo 1 > events/sctp/sctp_probe/enable # echo 1 > events/sctp/sctp_probe_path/enable Or, you can enable all the events under sctp. # echo 1 > events/sctp/enable Signed-off-by: Kevin Kou <qdkevin.kou@gmail.com> Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
90 lines
2.4 KiB
C
90 lines
2.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#undef TRACE_SYSTEM
|
|
#define TRACE_SYSTEM sctp
|
|
|
|
#if !defined(_TRACE_SCTP_H) || defined(TRACE_HEADER_MULTI_READ)
|
|
#define _TRACE_SCTP_H
|
|
|
|
#include <net/sctp/structs.h>
|
|
#include <linux/tracepoint.h>
|
|
|
|
TRACE_EVENT(sctp_probe_path,
|
|
|
|
TP_PROTO(struct sctp_transport *sp,
|
|
const struct sctp_association *asoc),
|
|
|
|
TP_ARGS(sp, asoc),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(__u64, asoc)
|
|
__field(__u32, primary)
|
|
__array(__u8, ipaddr, sizeof(union sctp_addr))
|
|
__field(__u32, state)
|
|
__field(__u32, cwnd)
|
|
__field(__u32, ssthresh)
|
|
__field(__u32, flight_size)
|
|
__field(__u32, partial_bytes_acked)
|
|
__field(__u32, pathmtu)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->asoc = (unsigned long)asoc;
|
|
__entry->primary = (sp == asoc->peer.primary_path);
|
|
memcpy(__entry->ipaddr, &sp->ipaddr, sizeof(union sctp_addr));
|
|
__entry->state = sp->state;
|
|
__entry->cwnd = sp->cwnd;
|
|
__entry->ssthresh = sp->ssthresh;
|
|
__entry->flight_size = sp->flight_size;
|
|
__entry->partial_bytes_acked = sp->partial_bytes_acked;
|
|
__entry->pathmtu = sp->pathmtu;
|
|
),
|
|
|
|
TP_printk("asoc=%#llx%s ipaddr=%pISpc state=%u cwnd=%u ssthresh=%u "
|
|
"flight_size=%u partial_bytes_acked=%u pathmtu=%u",
|
|
__entry->asoc, __entry->primary ? "(*)" : "",
|
|
__entry->ipaddr, __entry->state, __entry->cwnd,
|
|
__entry->ssthresh, __entry->flight_size,
|
|
__entry->partial_bytes_acked, __entry->pathmtu)
|
|
);
|
|
|
|
TRACE_EVENT(sctp_probe,
|
|
|
|
TP_PROTO(const struct sctp_endpoint *ep,
|
|
const struct sctp_association *asoc,
|
|
struct sctp_chunk *chunk),
|
|
|
|
TP_ARGS(ep, asoc, chunk),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(__u64, asoc)
|
|
__field(__u32, mark)
|
|
__field(__u16, bind_port)
|
|
__field(__u16, peer_port)
|
|
__field(__u32, pathmtu)
|
|
__field(__u32, rwnd)
|
|
__field(__u16, unack_data)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
struct sk_buff *skb = chunk->skb;
|
|
|
|
__entry->asoc = (unsigned long)asoc;
|
|
__entry->mark = skb->mark;
|
|
__entry->bind_port = ep->base.bind_addr.port;
|
|
__entry->peer_port = asoc->peer.port;
|
|
__entry->pathmtu = asoc->pathmtu;
|
|
__entry->rwnd = asoc->peer.rwnd;
|
|
__entry->unack_data = asoc->unack_data;
|
|
),
|
|
|
|
TP_printk("asoc=%#llx mark=%#x bind_port=%d peer_port=%d pathmtu=%d "
|
|
"rwnd=%u unack_data=%d",
|
|
__entry->asoc, __entry->mark, __entry->bind_port,
|
|
__entry->peer_port, __entry->pathmtu, __entry->rwnd,
|
|
__entry->unack_data)
|
|
);
|
|
|
|
#endif /* _TRACE_SCTP_H */
|
|
|
|
/* This part must be outside protection */
|
|
#include <trace/define_trace.h>
|