diff options
author | David S. Miller <davem@davemloft.net> | 2021-04-16 17:10:40 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-04-16 17:10:40 -0700 |
commit | 474f459360399c5becfd0f189a8894e9e17ad3d3 (patch) | |
tree | 4ac2215add7c9db2a6b0ffcb02f1d63481c82b7b | |
parent | 820dd7a244fe2d990d414172110f36cf5e8a936a (diff) | |
parent | 442279154c73bc681e5346bdd1270a628dfdfdc7 (diff) |
Merge branch 'mptcp-fixes-and-tracepoints'
Mat Martineau says:
====================
mptcp: Fixes and tracepoints from the mptcp tree
Here's one more batch of changes that we've tested out in the MPTCP tree.
Patch 1 makes the MPTCP KUnit config symbol more consistent with other
subsystems.
Patch 2 fixes a couple of format specifiers in pr_debug()s
Patches 3-7 add four helpful tracepoints for MPTCP.
Patch 8 is a one-line refactor to use an available helper macro.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | include/trace/events/mptcp.h | 173 | ||||
-rw-r--r-- | net/mptcp/Kconfig | 2 | ||||
-rw-r--r-- | net/mptcp/Makefile | 2 | ||||
-rw-r--r-- | net/mptcp/crypto.c | 2 | ||||
-rw-r--r-- | net/mptcp/options.c | 6 | ||||
-rw-r--r-- | net/mptcp/protocol.c | 26 | ||||
-rw-r--r-- | net/mptcp/protocol.h | 12 | ||||
-rw-r--r-- | net/mptcp/subflow.c | 10 | ||||
-rw-r--r-- | net/mptcp/token.c | 2 |
10 files changed, 207 insertions, 29 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 795b9941c151..0f82854cc430 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12546,6 +12546,7 @@ W: https://github.com/multipath-tcp/mptcp_net-next/wiki B: https://github.com/multipath-tcp/mptcp_net-next/issues F: Documentation/networking/mptcp-sysctl.rst F: include/net/mptcp.h +F: include/trace/events/mptcp.h F: include/uapi/linux/mptcp.h F: net/mptcp/ F: tools/testing/selftests/net/mptcp/ diff --git a/include/trace/events/mptcp.h b/include/trace/events/mptcp.h new file mode 100644 index 000000000000..775a46d0b0f0 --- /dev/null +++ b/include/trace/events/mptcp.h @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mptcp + +#if !defined(_TRACE_MPTCP_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_MPTCP_H + +#include <linux/tracepoint.h> + +#define show_mapping_status(status) \ + __print_symbolic(status, \ + { 0, "MAPPING_OK" }, \ + { 1, "MAPPING_INVALID" }, \ + { 2, "MAPPING_EMPTY" }, \ + { 3, "MAPPING_DATA_FIN" }, \ + { 4, "MAPPING_DUMMY" }) + +TRACE_EVENT(mptcp_subflow_get_send, + + TP_PROTO(struct mptcp_subflow_context *subflow), + + TP_ARGS(subflow), + + TP_STRUCT__entry( + __field(bool, active) + __field(bool, free) + __field(u32, snd_wnd) + __field(u32, pace) + __field(u8, backup) + __field(u64, ratio) + ), + + TP_fast_assign( + struct sock *ssk; + + __entry->active = mptcp_subflow_active(subflow); + __entry->backup = subflow->backup; + + if (subflow->tcp_sock && sk_fullsock(subflow->tcp_sock)) + __entry->free = sk_stream_memory_free(subflow->tcp_sock); + else + __entry->free = 0; + + ssk = mptcp_subflow_tcp_sock(subflow); + if (ssk && sk_fullsock(ssk)) { + __entry->snd_wnd = tcp_sk(ssk)->snd_wnd; + __entry->pace = ssk->sk_pacing_rate; + } else { + __entry->snd_wnd = 0; + __entry->pace = 0; + } + + if (ssk && sk_fullsock(ssk) && __entry->pace) + __entry->ratio = div_u64((u64)ssk->sk_wmem_queued << 32, __entry->pace); + else + __entry->ratio = 0; + ), + + TP_printk("active=%d free=%d snd_wnd=%u pace=%u backup=%u ratio=%llu", + __entry->active, __entry->free, + __entry->snd_wnd, __entry->pace, + __entry->backup, __entry->ratio) +); + +DECLARE_EVENT_CLASS(mptcp_dump_mpext, + + TP_PROTO(struct mptcp_ext *mpext), + + TP_ARGS(mpext), + + TP_STRUCT__entry( + __field(u64, data_ack) + __field(u64, data_seq) + __field(u32, subflow_seq) + __field(u16, data_len) + __field(u8, use_map) + __field(u8, dsn64) + __field(u8, data_fin) + __field(u8, use_ack) + __field(u8, ack64) + __field(u8, mpc_map) + __field(u8, frozen) + __field(u8, reset_transient) + __field(u8, reset_reason) + ), + + TP_fast_assign( + __entry->data_ack = mpext->ack64 ? mpext->data_ack : mpext->data_ack32; + __entry->data_seq = mpext->data_seq; + __entry->subflow_seq = mpext->subflow_seq; + __entry->data_len = mpext->data_len; + __entry->use_map = mpext->use_map; + __entry->dsn64 = mpext->dsn64; + __entry->data_fin = mpext->data_fin; + __entry->use_ack = mpext->use_ack; + __entry->ack64 = mpext->ack64; + __entry->mpc_map = mpext->mpc_map; + __entry->frozen = mpext->frozen; + __entry->reset_transient = mpext->reset_transient; + __entry->reset_reason = mpext->reset_reason; + ), + + TP_printk("data_ack=%llu data_seq=%llu subflow_seq=%u data_len=%u use_map=%u dsn64=%u data_fin=%u use_ack=%u ack64=%u mpc_map=%u frozen=%u reset_transient=%u reset_reason=%u", + __entry->data_ack, __entry->data_seq, + __entry->subflow_seq, __entry->data_len, + __entry->use_map, __entry->dsn64, + __entry->data_fin, __entry->use_ack, + __entry->ack64, __entry->mpc_map, + __entry->frozen, __entry->reset_transient, + __entry->reset_reason) +); + +DEFINE_EVENT(mptcp_dump_mpext, get_mapping_status, + TP_PROTO(struct mptcp_ext *mpext), + TP_ARGS(mpext)); + +TRACE_EVENT(ack_update_msk, + + TP_PROTO(u64 data_ack, u64 old_snd_una, + u64 new_snd_una, u64 new_wnd_end, + u64 msk_wnd_end), + + TP_ARGS(data_ack, old_snd_una, + new_snd_una, new_wnd_end, + msk_wnd_end), + + TP_STRUCT__entry( + __field(u64, data_ack) + __field(u64, old_snd_una) + __field(u64, new_snd_una) + __field(u64, new_wnd_end) + __field(u64, msk_wnd_end) + ), + + TP_fast_assign( + __entry->data_ack = data_ack; + __entry->old_snd_una = old_snd_una; + __entry->new_snd_una = new_snd_una; + __entry->new_wnd_end = new_wnd_end; + __entry->msk_wnd_end = msk_wnd_end; + ), + + TP_printk("data_ack=%llu old_snd_una=%llu new_snd_una=%llu new_wnd_end=%llu msk_wnd_end=%llu", + __entry->data_ack, __entry->old_snd_una, + __entry->new_snd_una, __entry->new_wnd_end, + __entry->msk_wnd_end) +); + +TRACE_EVENT(subflow_check_data_avail, + + TP_PROTO(__u8 status, struct sk_buff *skb), + + TP_ARGS(status, skb), + + TP_STRUCT__entry( + __field(u8, status) + __field(const void *, skb) + ), + + TP_fast_assign( + __entry->status = status; + __entry->skb = skb; + ), + + TP_printk("mapping_status=%s, skb=%p", + show_mapping_status(__entry->status), + __entry->skb) +); + +#endif /* _TRACE_MPTCP_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/net/mptcp/Kconfig b/net/mptcp/Kconfig index a014149aa323..20328920f6ed 100644 --- a/net/mptcp/Kconfig +++ b/net/mptcp/Kconfig @@ -22,7 +22,7 @@ config MPTCP_IPV6 depends on IPV6=y default y -config MPTCP_KUNIT_TESTS +config MPTCP_KUNIT_TEST tristate "This builds the MPTCP KUnit tests" if !KUNIT_ALL_TESTS depends on KUNIT default KUNIT_ALL_TESTS diff --git a/net/mptcp/Makefile b/net/mptcp/Makefile index d2642c012a6a..e54daceac58b 100644 --- a/net/mptcp/Makefile +++ b/net/mptcp/Makefile @@ -9,4 +9,4 @@ obj-$(CONFIG_INET_MPTCP_DIAG) += mptcp_diag.o mptcp_crypto_test-objs := crypto_test.o mptcp_token_test-objs := token_test.o -obj-$(CONFIG_MPTCP_KUNIT_TESTS) += mptcp_crypto_test.o mptcp_token_test.o +obj-$(CONFIG_MPTCP_KUNIT_TEST) += mptcp_crypto_test.o mptcp_token_test.o diff --git a/net/mptcp/crypto.c b/net/mptcp/crypto.c index b472dc149856..a8931349933c 100644 --- a/net/mptcp/crypto.c +++ b/net/mptcp/crypto.c @@ -78,6 +78,6 @@ void mptcp_crypto_hmac_sha(u64 key1, u64 key2, u8 *msg, int len, void *hmac) sha256(input, SHA256_BLOCK_SIZE + SHA256_DIGEST_SIZE, hmac); } -#if IS_MODULE(CONFIG_MPTCP_KUNIT_TESTS) +#if IS_MODULE(CONFIG_MPTCP_KUNIT_TEST) EXPORT_SYMBOL_GPL(mptcp_crypto_hmac_sha); #endif diff --git a/net/mptcp/options.c b/net/mptcp/options.c index d51c3ad54d9a..99fc21406168 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -13,6 +13,8 @@ #include "protocol.h" #include "mib.h" +#include <trace/events/mptcp.h> + static bool mptcp_cap_flag_sha256(u8 flags) { return (flags & MPTCP_CAP_FLAG_MASK) == MPTCP_CAP_HMAC_SHA256; @@ -943,6 +945,10 @@ static void ack_update_msk(struct mptcp_sock *msk, __mptcp_data_acked(sk); } mptcp_data_unlock(sk); + + trace_ack_update_msk(mp_opt->data_ack, + old_snd_una, new_snd_una, + new_wnd_end, msk->wnd_end); } bool mptcp_update_rcv_data_fin(struct mptcp_sock *msk, u64 data_fin_seq, bool use_64bit) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 073e20078ed0..c14ac2975736 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -25,6 +25,9 @@ #include "protocol.h" #include "mib.h" +#define CREATE_TRACE_POINTS +#include <trace/events/mptcp.h> + #if IS_ENABLED(CONFIG_MPTCP_IPV6) struct mptcp6_sock { struct mptcp_sock msk; @@ -399,18 +402,6 @@ static void mptcp_set_timeout(const struct sock *sk, const struct sock *ssk) mptcp_sk(sk)->timer_ival = tout > 0 ? tout : TCP_RTO_MIN; } -static bool mptcp_subflow_active(struct mptcp_subflow_context *subflow) -{ - struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - - /* can't send if JOIN hasn't completed yet (i.e. is usable for mptcp) */ - if (subflow->request_join && !subflow->fully_established) - return false; - - /* only send if our side has not closed yet */ - return ((1 << ssk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)); -} - static bool tcp_can_send_ack(const struct sock *ssk) { return !((1 << inet_sk_state_load(ssk)) & @@ -1294,7 +1285,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk, int avail_size; size_t ret = 0; - pr_debug("msk=%p ssk=%p sending dfrag at seq=%lld len=%d already sent=%d", + pr_debug("msk=%p ssk=%p sending dfrag at seq=%llu len=%u already sent=%u", msk, ssk, dfrag->data_seq, dfrag->data_len, info->sent); /* compute send limit */ @@ -1422,6 +1413,7 @@ static struct sock *mptcp_subflow_get_send(struct mptcp_sock *msk) send_info[i].ratio = -1; } mptcp_for_each_subflow(msk, subflow) { + trace_mptcp_subflow_get_send(subflow); ssk = mptcp_subflow_tcp_sock(subflow); if (!mptcp_subflow_active(subflow)) continue; @@ -1442,10 +1434,6 @@ static struct sock *mptcp_subflow_get_send(struct mptcp_sock *msk) } } - pr_debug("msk=%p nr_active=%d ssk=%p:%lld backup=%p:%lld", - msk, nr_active, send_info[0].ssk, send_info[0].ratio, - send_info[1].ssk, send_info[1].ratio); - /* pick the best backup if no other subflow is active */ if (!nr_active) send_info[0].ssk = send_info[1].ssk; @@ -1712,7 +1700,7 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) if (!msk->first_pending) WRITE_ONCE(msk->first_pending, dfrag); } - pr_debug("msk=%p dfrag at seq=%lld len=%d sent=%d new=%d", msk, + pr_debug("msk=%p dfrag at seq=%llu len=%u sent=%u new=%d", msk, dfrag->data_seq, dfrag->data_len, dfrag->already_sent, !dfrag_collapsed); @@ -2623,7 +2611,7 @@ static void mptcp_close(struct sock *sk, long timeout) cleanup: /* orphan all the subflows */ inet_csk(sk)->icsk_mtup.probe_timestamp = tcp_jiffies32; - list_for_each_entry(subflow, &mptcp_sk(sk)->conn_list, node) { + mptcp_for_each_subflow(mptcp_sk(sk), subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); bool slow = lock_sock_fast(ssk); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index df269c26f145..edc0128730df 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -544,6 +544,18 @@ void mptcp_info2sockaddr(const struct mptcp_addr_info *info, struct sockaddr_storage *addr, unsigned short family); +static inline bool mptcp_subflow_active(struct mptcp_subflow_context *subflow) +{ + struct sock *ssk = mptcp_subflow_tcp_sock(subflow); + + /* can't send if JOIN hasn't completed yet (i.e. is usable for mptcp) */ + if (subflow->request_join && !subflow->fully_established) + return false; + + /* only send if our side has not closed yet */ + return ((1 << ssk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)); +} + static inline void mptcp_subflow_tcp_fallback(struct sock *sk, struct mptcp_subflow_context *ctx) { diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index c3da84576b3c..82e91b00ad39 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -25,6 +25,8 @@ #include "protocol.h" #include "mib.h" +#include <trace/events/mptcp.h> + static void mptcp_subflow_ops_undo_override(struct sock *ssk); static void SUBFLOW_REQ_INC_STATS(struct request_sock *req, @@ -862,9 +864,7 @@ static enum mapping_status get_mapping_status(struct sock *ssk, goto validate_seq; } - pr_debug("seq=%llu is64=%d ssn=%u data_len=%u data_fin=%d", - mpext->data_seq, mpext->dsn64, mpext->subflow_seq, - mpext->data_len, mpext->data_fin); + trace_get_mapping_status(mpext); data_len = mpext->data_len; if (data_len == 0) { @@ -1002,8 +1002,6 @@ static bool subflow_check_data_avail(struct sock *ssk) struct mptcp_sock *msk; struct sk_buff *skb; - pr_debug("msk=%p ssk=%p data_avail=%d skb=%p", subflow->conn, ssk, - subflow->data_avail, skb_peek(&ssk->sk_receive_queue)); if (!skb_peek(&ssk->sk_receive_queue)) subflow->data_avail = 0; if (subflow->data_avail) @@ -1015,7 +1013,7 @@ static bool subflow_check_data_avail(struct sock *ssk) u64 old_ack; status = get_mapping_status(ssk, msk); - pr_debug("msk=%p ssk=%p status=%d", msk, ssk, status); + trace_subflow_check_data_avail(status, skb_peek(&ssk->sk_receive_queue)); if (status == MAPPING_INVALID) { ssk->sk_err = EBADMSG; goto fatal; diff --git a/net/mptcp/token.c b/net/mptcp/token.c index feb4b9ffd462..8f0270a780ce 100644 --- a/net/mptcp/token.c +++ b/net/mptcp/token.c @@ -402,7 +402,7 @@ void __init mptcp_token_init(void) } } -#if IS_MODULE(CONFIG_MPTCP_KUNIT_TESTS) +#if IS_MODULE(CONFIG_MPTCP_KUNIT_TEST) EXPORT_SYMBOL_GPL(mptcp_token_new_request); EXPORT_SYMBOL_GPL(mptcp_token_new_connect); EXPORT_SYMBOL_GPL(mptcp_token_accept); |