Commit 27e521c5 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'rxrpc-next-20221201-b' of...

Merge tag 'rxrpc-next-20221201-b' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs



David Howells says:

====================
rxrpc: Increasing SACK size and moving away from softirq, parts 2 & 3

Here are the second and third parts of patches in the process of moving
rxrpc from doing a lot of its stuff in softirq context to doing it in an
I/O thread in process context and thereby making it easier to support a
larger SACK table.

The full description is in the description for the first part[1] which is
already in net-next.

The second part includes some cleanups, adds some testing and overhauls
some tracing:

 (1) Remove declaration of rxrpc_kernel_call_is_complete() as the
     definition is no longer present.

 (2) Remove the knet() and kproto() macros in favour of using tracepoints.

 (3) Remove handling of duplicate packets from recvmsg.  The input side
     isn't now going to insert overlapping/duplicate packets into the
     recvmsg queue.

 (4) Don't use the rxrpc_conn_parameters struct in the rxrpc_connection or
     rxrpc_bundle structs - rather put the members in directly.

 (5) Extract the abort code from a received abort packet right up front
     rather than doing it in multiple places later.

 (6) Use enums and symbol lists rather than __builtin_return_address() to
     indicate where a tracepoint was triggered for local, peer, conn, call
     and skbuff tracing.

 (7) Add a refcount tracepoint for the rxrpc_bundle struct.

 (8) Implement an in-kernel server for the AFS rxperf testing program to
     talk to (enabled by a Kconfig option).

This is tagged as rxrpc-next-20221201-a.

The third part introduces the I/O thread and switches various bits over to
running there:

 (1) Fix call timers and call and connection workqueues to not hold refs on
     the rxrpc_call and rxrpc_connection structs to thereby avoid messy
     cleanup when the last ref is put in softirq mode.

 (2) Split input.c so that the call packet processing bits are separate
     from the received packet distribution bits.  Call packet processing
     gets bumped over to the call event handler.

 (3) Create a per-local endpoint I/O thread.  Barring some tiny bits that
     still get done in softirq context, all packet reception, processing
     and transmission is done in this thread.  That will allow a load of
     locking to be removed.

 (4) Perform packet processing and error processing from the I/O thread.

 (5) Provide a mechanism to process call event notifications in the I/O
     thread rather than queuing a work item for that call.

 (6) Move data and ACK transmission into the I/O thread.  ACKs can then be
     transmitted at the point they're generated rather than getting
     delegated from softirq context to some process context somewhere.

 (7) Move call and local processor event handling into the I/O thread.

 (8) Move cwnd degradation to after packets have been transmitted so that
     they don't shorten the window too quickly.

A bunch of simplifications can then be done:

 (1) The input_lock is no longer necessary as exclusion is achieved by
     running the code in the I/O thread only.

 (2) Don't need to use sk->sk_receive_queue.lock to guard socket state
     changes as the socket mutex should suffice.

 (3) Don't take spinlocks in RCU callback functions as they get run in
     softirq context and thus need _bh annotations.

 (4) RCU is then no longer needed for the peer's error_targets list.

 (5) Simplify the skbuff handling in the receive path by dropping the ref
     in the basic I/O thread loop and getting an extra ref as and when we
     need to queue the packet for recvmsg or another context.

 (6) Get the peer address earlier in the input process and pass it to the
     users so that we only do it once.

This is tagged as rxrpc-next-20221201-b.

Changes:
========
ver #2)
 - Added a patch to change four assertions into warnings in rxrpc_read()
   and fixed a checker warning from a __user annotation that should have
   been removed..
 - Change a min() to min_t() in rxperf as PAGE_SIZE doesn't seem to match
   type size_t on i386.
 - Three error handling issues in rxrpc_new_incoming_call():
   - If not DATA or not seq #1, should drop the packet, not abort.
   - Fix a goto that went to the wrong place, dropping a non-held lock.
   - Fix an rcu_read_lock that should've been an unlock.

Tested-by: default avatarMarc Dionne <marc.dionne@auristor.com>
Tested-by: default avatar <kafs-testing+fedora36_64checkkafs-build-144@auristor.com>
Link: https://lore.kernel.org/r/166794587113.2389296.16484814996876530222.stgit@warthog.procyon.org.uk/ [1]
Link: https://lore.kernel.org/r/166982725699.621383.2358362793992993374.stgit@warthog.procyon.org.uk/

 # v1
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d8ca1137 b0346843
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -66,10 +66,10 @@ int rxrpc_kernel_charge_accept(struct socket *, rxrpc_notify_rx_t,
void rxrpc_kernel_set_tx_length(struct socket *, struct rxrpc_call *, s64);
bool rxrpc_kernel_check_life(const struct socket *, const struct rxrpc_call *);
u32 rxrpc_kernel_get_epoch(struct socket *, struct rxrpc_call *);
bool rxrpc_kernel_call_is_complete(struct rxrpc_call *);
void rxrpc_kernel_set_max_life(struct socket *, struct rxrpc_call *,
			       unsigned long);

int rxrpc_sock_set_min_security_level(struct sock *sk, unsigned int val);
int rxrpc_sock_set_security_keyring(struct sock *, struct key *);

#endif /* _NET_RXRPC_H */
+370 −116
Original line number Diff line number Diff line
@@ -16,44 +16,121 @@
/*
 * Declare tracing information enums and their string mappings for display.
 */
#define rxrpc_call_poke_traces \
	EM(rxrpc_call_poke_error,		"Error")	\
	EM(rxrpc_call_poke_idle,		"Idle")		\
	EM(rxrpc_call_poke_start,		"Start")	\
	EM(rxrpc_call_poke_timer,		"Timer")	\
	E_(rxrpc_call_poke_timer_now,		"Timer-now")

#define rxrpc_skb_traces \
	EM(rxrpc_skb_ack,			"ACK") \
	EM(rxrpc_skb_cleaned,			"CLN") \
	EM(rxrpc_skb_cloned_jumbo,		"CLJ") \
	EM(rxrpc_skb_freed,			"FRE") \
	EM(rxrpc_skb_got,			"GOT") \
	EM(rxrpc_skb_lost,			"*L*") \
	EM(rxrpc_skb_new,			"NEW") \
	EM(rxrpc_skb_purged,			"PUR") \
	EM(rxrpc_skb_received,			"RCV") \
	EM(rxrpc_skb_rotated,			"ROT") \
	EM(rxrpc_skb_seen,			"SEE") \
	EM(rxrpc_skb_unshared,			"UNS") \
	E_(rxrpc_skb_unshared_nomem,		"US0")
	EM(rxrpc_skb_eaten_by_unshare,		"ETN unshare  ") \
	EM(rxrpc_skb_eaten_by_unshare_nomem,	"ETN unshar-nm") \
	EM(rxrpc_skb_get_conn_work,		"GET conn-work") \
	EM(rxrpc_skb_get_local_work,		"GET locl-work") \
	EM(rxrpc_skb_get_reject_work,		"GET rej-work ") \
	EM(rxrpc_skb_get_to_recvmsg,		"GET to-recv  ") \
	EM(rxrpc_skb_get_to_recvmsg_oos,	"GET to-recv-o") \
	EM(rxrpc_skb_new_encap_rcv,		"NEW encap-rcv") \
	EM(rxrpc_skb_new_error_report,		"NEW error-rpt") \
	EM(rxrpc_skb_new_jumbo_subpacket,	"NEW jumbo-sub") \
	EM(rxrpc_skb_new_unshared,		"NEW unshared ") \
	EM(rxrpc_skb_put_conn_work,		"PUT conn-work") \
	EM(rxrpc_skb_put_error_report,		"PUT error-rep") \
	EM(rxrpc_skb_put_input,			"PUT input    ") \
	EM(rxrpc_skb_put_jumbo_subpacket,	"PUT jumbo-sub") \
	EM(rxrpc_skb_put_purge,			"PUT purge    ") \
	EM(rxrpc_skb_put_rotate,		"PUT rotate   ") \
	EM(rxrpc_skb_put_unknown,		"PUT unknown  ") \
	EM(rxrpc_skb_see_conn_work,		"SEE conn-work") \
	EM(rxrpc_skb_see_recvmsg,		"SEE recvmsg  ") \
	EM(rxrpc_skb_see_reject,		"SEE reject   ") \
	EM(rxrpc_skb_see_rotate,		"SEE rotate   ") \
	E_(rxrpc_skb_see_version,		"SEE version  ")

#define rxrpc_local_traces \
	EM(rxrpc_local_got,			"GOT") \
	EM(rxrpc_local_free,			"FREE        ") \
	EM(rxrpc_local_get_call,		"GET call    ") \
	EM(rxrpc_local_get_client_conn,		"GET conn-cln") \
	EM(rxrpc_local_get_for_use,		"GET for-use ") \
	EM(rxrpc_local_get_peer,		"GET peer    ") \
	EM(rxrpc_local_get_prealloc_conn,	"GET conn-pre") \
	EM(rxrpc_local_new,			"NEW         ") \
	EM(rxrpc_local_processing,		"PRO") \
	EM(rxrpc_local_put,			"PUT") \
	EM(rxrpc_local_queued,			"QUE") \
	E_(rxrpc_local_tx_ack,			"TAK")
	EM(rxrpc_local_put_bind,		"PUT bind    ") \
	EM(rxrpc_local_put_call,		"PUT call    ") \
	EM(rxrpc_local_put_for_use,		"PUT for-use ") \
	EM(rxrpc_local_put_kill_conn,		"PUT conn-kil") \
	EM(rxrpc_local_put_peer,		"PUT peer    ") \
	EM(rxrpc_local_put_prealloc_conn,	"PUT conn-pre") \
	EM(rxrpc_local_put_release_sock,	"PUT rel-sock") \
	EM(rxrpc_local_stop,			"STOP        ") \
	EM(rxrpc_local_stopped,			"STOPPED     ") \
	EM(rxrpc_local_unuse_bind,		"UNU bind    ") \
	EM(rxrpc_local_unuse_conn_work,		"UNU conn-wrk") \
	EM(rxrpc_local_unuse_peer_keepalive,	"UNU peer-kpa") \
	EM(rxrpc_local_unuse_release_sock,	"UNU rel-sock") \
	EM(rxrpc_local_use_conn_work,		"USE conn-wrk") \
	EM(rxrpc_local_use_lookup,		"USE lookup  ") \
	E_(rxrpc_local_use_peer_keepalive,	"USE peer-kpa")

#define rxrpc_peer_traces \
	EM(rxrpc_peer_got,			"GOT") \
	EM(rxrpc_peer_new,			"NEW") \
	EM(rxrpc_peer_processing,		"PRO") \
	E_(rxrpc_peer_put,			"PUT")
	EM(rxrpc_peer_free,			"FREE        ") \
	EM(rxrpc_peer_get_accept,		"GET accept  ") \
	EM(rxrpc_peer_get_activate_call,	"GET act-call") \
	EM(rxrpc_peer_get_bundle,		"GET bundle  ") \
	EM(rxrpc_peer_get_client_conn,		"GET cln-conn") \
	EM(rxrpc_peer_get_input,		"GET input   ") \
	EM(rxrpc_peer_get_input_error,		"GET inpt-err") \
	EM(rxrpc_peer_get_keepalive,		"GET keepaliv") \
	EM(rxrpc_peer_get_lookup_client,	"GET look-cln") \
	EM(rxrpc_peer_get_service_conn,		"GET srv-conn") \
	EM(rxrpc_peer_new_client,		"NEW client  ") \
	EM(rxrpc_peer_new_prealloc,		"NEW prealloc") \
	EM(rxrpc_peer_put_bundle,		"PUT bundle  ") \
	EM(rxrpc_peer_put_call,			"PUT call    ") \
	EM(rxrpc_peer_put_conn,			"PUT conn    ") \
	EM(rxrpc_peer_put_discard_tmp,		"PUT disc-tmp") \
	EM(rxrpc_peer_put_input,		"PUT input   ") \
	EM(rxrpc_peer_put_input_error,		"PUT inpt-err") \
	E_(rxrpc_peer_put_keepalive,		"PUT keepaliv")

#define rxrpc_bundle_traces \
	EM(rxrpc_bundle_free,			"FREE        ") \
	EM(rxrpc_bundle_get_client_call,	"GET clt-call") \
	EM(rxrpc_bundle_get_client_conn,	"GET clt-conn") \
	EM(rxrpc_bundle_get_service_conn,	"GET svc-conn") \
	EM(rxrpc_bundle_put_conn,		"PUT conn    ") \
	EM(rxrpc_bundle_put_discard,		"PUT discard ") \
	E_(rxrpc_bundle_new,			"NEW         ")

#define rxrpc_conn_traces \
	EM(rxrpc_conn_got,			"GOT") \
	EM(rxrpc_conn_new_client,		"NWc") \
	EM(rxrpc_conn_new_service,		"NWs") \
	EM(rxrpc_conn_put_client,		"PTc") \
	EM(rxrpc_conn_put_service,		"PTs") \
	EM(rxrpc_conn_queued,			"QUE") \
	EM(rxrpc_conn_reap_service,		"RPs") \
	E_(rxrpc_conn_seen,			"SEE")
	EM(rxrpc_conn_free,			"FREE        ") \
	EM(rxrpc_conn_get_activate_call,	"GET act-call") \
	EM(rxrpc_conn_get_call_input,		"GET inp-call") \
	EM(rxrpc_conn_get_conn_input,		"GET inp-conn") \
	EM(rxrpc_conn_get_idle,			"GET idle    ") \
	EM(rxrpc_conn_get_poke,			"GET poke    ") \
	EM(rxrpc_conn_get_service_conn,		"GET svc-conn") \
	EM(rxrpc_conn_new_client,		"NEW client  ") \
	EM(rxrpc_conn_new_service,		"NEW service ") \
	EM(rxrpc_conn_put_call,			"PUT call    ") \
	EM(rxrpc_conn_put_call_input,		"PUT inp-call") \
	EM(rxrpc_conn_put_conn_input,		"PUT inp-conn") \
	EM(rxrpc_conn_put_discard,		"PUT discard ") \
	EM(rxrpc_conn_put_discard_idle,		"PUT disc-idl") \
	EM(rxrpc_conn_put_local_dead,		"PUT loc-dead") \
	EM(rxrpc_conn_put_noreuse,		"PUT noreuse ") \
	EM(rxrpc_conn_put_poke,			"PUT poke    ") \
	EM(rxrpc_conn_put_service_reaped,	"PUT svc-reap") \
	EM(rxrpc_conn_put_unbundle,		"PUT unbundle") \
	EM(rxrpc_conn_put_unidle,		"PUT unidle  ") \
	EM(rxrpc_conn_queue_challenge,		"QUE chall   ") \
	EM(rxrpc_conn_queue_retry_work,		"QUE retry-wk") \
	EM(rxrpc_conn_queue_rx_work,		"QUE rx-work ") \
	EM(rxrpc_conn_queue_timer,		"QUE timer   ") \
	EM(rxrpc_conn_see_new_service_conn,	"SEE new-svc ") \
	EM(rxrpc_conn_see_reap_service,		"SEE reap-svc") \
	E_(rxrpc_conn_see_work,			"SEE work    ")

#define rxrpc_client_traces \
	EM(rxrpc_client_activate_chans,		"Activa") \
@@ -71,26 +148,36 @@
	E_(rxrpc_client_to_idle,		"->Idle")

#define rxrpc_call_traces \
	EM(rxrpc_call_connected,		"CON") \
	EM(rxrpc_call_error,			"*E*") \
	EM(rxrpc_call_got,			"GOT") \
	EM(rxrpc_call_got_kernel,		"Gke") \
	EM(rxrpc_call_got_timer,		"GTM") \
	EM(rxrpc_call_got_tx,			"Gtx") \
	EM(rxrpc_call_got_userid,		"Gus") \
	EM(rxrpc_call_new_client,		"NWc") \
	EM(rxrpc_call_new_service,		"NWs") \
	EM(rxrpc_call_put,			"PUT") \
	EM(rxrpc_call_put_kernel,		"Pke") \
	EM(rxrpc_call_put_noqueue,		"PnQ") \
	EM(rxrpc_call_put_notimer,		"PnT") \
	EM(rxrpc_call_put_timer,		"PTM") \
	EM(rxrpc_call_put_tx,			"Ptx") \
	EM(rxrpc_call_put_userid,		"Pus") \
	EM(rxrpc_call_queued,			"QUE") \
	EM(rxrpc_call_queued_ref,		"QUR") \
	EM(rxrpc_call_release,			"RLS") \
	E_(rxrpc_call_seen,			"SEE")
	EM(rxrpc_call_get_input,		"GET input   ") \
	EM(rxrpc_call_get_kernel_service,	"GET krnl-srv") \
	EM(rxrpc_call_get_notify_socket,	"GET notify  ") \
	EM(rxrpc_call_get_poke,			"GET poke    ") \
	EM(rxrpc_call_get_recvmsg,		"GET recvmsg ") \
	EM(rxrpc_call_get_release_sock,		"GET rel-sock") \
	EM(rxrpc_call_get_sendmsg,		"GET sendmsg ") \
	EM(rxrpc_call_get_userid,		"GET user-id ") \
	EM(rxrpc_call_new_client,		"NEW client  ") \
	EM(rxrpc_call_new_prealloc_service,	"NEW prealloc") \
	EM(rxrpc_call_put_discard_prealloc,	"PUT disc-pre") \
	EM(rxrpc_call_put_discard_error,	"PUT disc-err") \
	EM(rxrpc_call_put_input,		"PUT input   ") \
	EM(rxrpc_call_put_kernel,		"PUT kernel  ") \
	EM(rxrpc_call_put_poke,			"PUT poke    ") \
	EM(rxrpc_call_put_recvmsg,		"PUT recvmsg ") \
	EM(rxrpc_call_put_release_sock,		"PUT rls-sock") \
	EM(rxrpc_call_put_release_sock_tba,	"PUT rls-sk-a") \
	EM(rxrpc_call_put_sendmsg,		"PUT sendmsg ") \
	EM(rxrpc_call_put_unnotify,		"PUT unnotify") \
	EM(rxrpc_call_put_userid_exists,	"PUT u-exists") \
	EM(rxrpc_call_see_accept,		"SEE accept  ") \
	EM(rxrpc_call_see_activate_client,	"SEE act-clnt") \
	EM(rxrpc_call_see_connect_failed,	"SEE con-fail") \
	EM(rxrpc_call_see_connected,		"SEE connect ") \
	EM(rxrpc_call_see_distribute_error,	"SEE dist-err") \
	EM(rxrpc_call_see_input,		"SEE input   ") \
	EM(rxrpc_call_see_release,		"SEE release ") \
	EM(rxrpc_call_see_userid_exists,	"SEE u-exists") \
	E_(rxrpc_call_see_zap,			"SEE zap     ")

#define rxrpc_txqueue_traces \
	EM(rxrpc_txqueue_await_reply,		"AWR") \
@@ -179,6 +266,7 @@
	EM(rxrpc_propose_ack_respond_to_ping,	"Rsp2Png") \
	EM(rxrpc_propose_ack_retry_tx,		"RetryTx") \
	EM(rxrpc_propose_ack_rotate_rx,		"RxAck  ") \
	EM(rxrpc_propose_ack_rx_idle,		"RxIdle ") \
	E_(rxrpc_propose_ack_terminal_ack,	"ClTerm ")

#define rxrpc_congest_modes \
@@ -273,6 +361,7 @@
	EM(rxrpc_txbuf_put_rotated,		"PUT ROTATED")	\
	EM(rxrpc_txbuf_put_send_aborted,	"PUT SEND-X ")	\
	EM(rxrpc_txbuf_put_trans,		"PUT TRANS  ")	\
	EM(rxrpc_txbuf_see_out_of_step,		"OUT-OF-STEP")	\
	EM(rxrpc_txbuf_see_send_more,		"SEE SEND+  ")	\
	E_(rxrpc_txbuf_see_unacked,		"SEE UNACKED")

@@ -287,6 +376,8 @@
#define EM(a, b) a,
#define E_(a, b) a

enum rxrpc_bundle_trace		{ rxrpc_bundle_traces } __mode(byte);
enum rxrpc_call_poke_trace	{ rxrpc_call_poke_traces } __mode(byte);
enum rxrpc_call_trace		{ rxrpc_call_traces } __mode(byte);
enum rxrpc_client_trace		{ rxrpc_client_traces } __mode(byte);
enum rxrpc_congest_change	{ rxrpc_congest_changes } __mode(byte);
@@ -316,6 +407,8 @@ enum rxrpc_txqueue_trace { rxrpc_txqueue_traces } __mode(byte);
#define EM(a, b) TRACE_DEFINE_ENUM(a);
#define E_(a, b) TRACE_DEFINE_ENUM(a);

rxrpc_bundle_traces;
rxrpc_call_poke_traces;
rxrpc_call_traces;
rxrpc_client_traces;
rxrpc_congest_changes;
@@ -345,83 +438,98 @@ rxrpc_txqueue_traces;

TRACE_EVENT(rxrpc_local,
	    TP_PROTO(unsigned int local_debug_id, enum rxrpc_local_trace op,
		     int usage, const void *where),
		     int ref, int usage),

	    TP_ARGS(local_debug_id, op, usage, where),
	    TP_ARGS(local_debug_id, op, ref, usage),

	    TP_STRUCT__entry(
		    __field(unsigned int,	local		)
		    __field(int,		op		)
		    __field(int,		ref		)
		    __field(int,		usage		)
		    __field(const void *,	where		)
			     ),

	    TP_fast_assign(
		    __entry->local = local_debug_id;
		    __entry->op = op;
		    __entry->ref = ref;
		    __entry->usage = usage;
		    __entry->where = where;
			   ),

	    TP_printk("L=%08x %s u=%d sp=%pSR",
	    TP_printk("L=%08x %s r=%d u=%d",
		      __entry->local,
		      __print_symbolic(__entry->op, rxrpc_local_traces),
		      __entry->usage,
		      __entry->where)
		      __entry->ref,
		      __entry->usage)
	    );

TRACE_EVENT(rxrpc_peer,
	    TP_PROTO(unsigned int peer_debug_id, enum rxrpc_peer_trace op,
		     int usage, const void *where),
	    TP_PROTO(unsigned int peer_debug_id, int ref, enum rxrpc_peer_trace why),

	    TP_ARGS(peer_debug_id, op, usage, where),
	    TP_ARGS(peer_debug_id, ref, why),

	    TP_STRUCT__entry(
		    __field(unsigned int,	peer		)
		    __field(int,		op		)
		    __field(int,		usage		)
		    __field(const void *,	where		)
		    __field(int,		ref		)
		    __field(int,		why		)
			     ),

	    TP_fast_assign(
		    __entry->peer = peer_debug_id;
		    __entry->op = op;
		    __entry->usage = usage;
		    __entry->where = where;
		    __entry->ref = ref;
		    __entry->why = why;
			   ),

	    TP_printk("P=%08x %s u=%d sp=%pSR",
	    TP_printk("P=%08x %s r=%d",
		      __entry->peer,
		      __print_symbolic(__entry->op, rxrpc_peer_traces),
		      __entry->usage,
		      __entry->where)
		      __print_symbolic(__entry->why, rxrpc_peer_traces),
		      __entry->ref)
	    );

TRACE_EVENT(rxrpc_bundle,
	    TP_PROTO(unsigned int bundle_debug_id, int ref, enum rxrpc_bundle_trace why),

	    TP_ARGS(bundle_debug_id, ref, why),

	    TP_STRUCT__entry(
		    __field(unsigned int,	bundle		)
		    __field(int,		ref		)
		    __field(int,		why		)
			     ),

	    TP_fast_assign(
		    __entry->bundle = bundle_debug_id;
		    __entry->ref = ref;
		    __entry->why = why;
			   ),

	    TP_printk("CB=%08x %s r=%d",
		      __entry->bundle,
		      __print_symbolic(__entry->why, rxrpc_bundle_traces),
		      __entry->ref)
	    );

TRACE_EVENT(rxrpc_conn,
	    TP_PROTO(unsigned int conn_debug_id, enum rxrpc_conn_trace op,
		     int usage, const void *where),
	    TP_PROTO(unsigned int conn_debug_id, int ref, enum rxrpc_conn_trace why),

	    TP_ARGS(conn_debug_id, op, usage, where),
	    TP_ARGS(conn_debug_id, ref, why),

	    TP_STRUCT__entry(
		    __field(unsigned int,	conn		)
		    __field(int,		op		)
		    __field(int,		usage		)
		    __field(const void *,	where		)
		    __field(int,		ref		)
		    __field(int,		why		)
			     ),

	    TP_fast_assign(
		    __entry->conn = conn_debug_id;
		    __entry->op = op;
		    __entry->usage = usage;
		    __entry->where = where;
		    __entry->ref = ref;
		    __entry->why = why;
			   ),

	    TP_printk("C=%08x %s u=%d sp=%pSR",
	    TP_printk("C=%08x %s r=%d",
		      __entry->conn,
		      __print_symbolic(__entry->op, rxrpc_conn_traces),
		      __entry->usage,
		      __entry->where)
		      __print_symbolic(__entry->why, rxrpc_conn_traces),
		      __entry->ref)
	    );

TRACE_EVENT(rxrpc_client,
@@ -455,63 +563,57 @@ TRACE_EVENT(rxrpc_client,
	    );

TRACE_EVENT(rxrpc_call,
	    TP_PROTO(unsigned int call_debug_id, enum rxrpc_call_trace op,
		     int usage, const void *where, const void *aux),
	    TP_PROTO(unsigned int call_debug_id, int ref, unsigned long aux,
		     enum rxrpc_call_trace why),

	    TP_ARGS(call_debug_id, op, usage, where, aux),
	    TP_ARGS(call_debug_id, ref, aux, why),

	    TP_STRUCT__entry(
		    __field(unsigned int,		call		)
		    __field(int,			op		)
		    __field(int,			usage		)
		    __field(const void *,		where		)
		    __field(const void *,		aux		)
		    __field(int,			ref		)
		    __field(int,			why		)
		    __field(unsigned long,		aux		)
			     ),

	    TP_fast_assign(
		    __entry->call = call_debug_id;
		    __entry->op = op;
		    __entry->usage = usage;
		    __entry->where = where;
		    __entry->ref = ref;
		    __entry->why = why;
		    __entry->aux = aux;
			   ),

	    TP_printk("c=%08x %s u=%d sp=%pSR a=%p",
	    TP_printk("c=%08x %s r=%d a=%lx",
		      __entry->call,
		      __print_symbolic(__entry->op, rxrpc_call_traces),
		      __entry->usage,
		      __entry->where,
		      __print_symbolic(__entry->why, rxrpc_call_traces),
		      __entry->ref,
		      __entry->aux)
	    );

TRACE_EVENT(rxrpc_skb,
	    TP_PROTO(struct sk_buff *skb, enum rxrpc_skb_trace op,
		     int usage, int mod_count, const void *where),
	    TP_PROTO(struct sk_buff *skb, int usage, int mod_count,
		     enum rxrpc_skb_trace why),

	    TP_ARGS(skb, op, usage, mod_count, where),
	    TP_ARGS(skb, usage, mod_count, why),

	    TP_STRUCT__entry(
		    __field(struct sk_buff *,		skb		)
		    __field(enum rxrpc_skb_trace,	op		)
		    __field(int,			usage		)
		    __field(int,			mod_count	)
		    __field(const void *,		where		)
		    __field(enum rxrpc_skb_trace,	why		)
			     ),

	    TP_fast_assign(
		    __entry->skb = skb;
		    __entry->op = op;
		    __entry->usage = usage;
		    __entry->mod_count = mod_count;
		    __entry->where = where;
		    __entry->why = why;
			   ),

	    TP_printk("s=%p Rx %s u=%d m=%d p=%pSR",
	    TP_printk("s=%p Rx %s u=%d m=%d",
		      __entry->skb,
		      __print_symbolic(__entry->op, rxrpc_skb_traces),
		      __print_symbolic(__entry->why, rxrpc_skb_traces),
		      __entry->usage,
		      __entry->mod_count,
		      __entry->where)
		      __entry->mod_count)
	    );

TRACE_EVENT(rxrpc_rx_packet,
@@ -623,6 +725,7 @@ TRACE_EVENT(rxrpc_txqueue,
		    __field(rxrpc_seq_t,		acks_hard_ack	)
		    __field(rxrpc_seq_t,		tx_bottom	)
		    __field(rxrpc_seq_t,		tx_top		)
		    __field(rxrpc_seq_t,		tx_prepared	)
		    __field(int,			tx_winsize	)
			     ),

@@ -632,16 +735,18 @@ TRACE_EVENT(rxrpc_txqueue,
		    __entry->acks_hard_ack = call->acks_hard_ack;
		    __entry->tx_bottom = call->tx_bottom;
		    __entry->tx_top = call->tx_top;
		    __entry->tx_prepared = call->tx_prepared;
		    __entry->tx_winsize = call->tx_winsize;
			   ),

	    TP_printk("c=%08x %s f=%08x h=%08x n=%u/%u/%u",
	    TP_printk("c=%08x %s f=%08x h=%08x n=%u/%u/%u/%u",
		      __entry->call,
		      __print_symbolic(__entry->why, rxrpc_txqueue_traces),
		      __entry->tx_bottom,
		      __entry->acks_hard_ack,
		      __entry->tx_top - __entry->tx_bottom,
		      __entry->tx_top - __entry->acks_hard_ack,
		      __entry->tx_prepared - __entry->tx_bottom,
		      __entry->tx_winsize)
	    );

@@ -733,6 +838,66 @@ TRACE_EVENT(rxrpc_rx_abort,
		      __entry->abort_code)
	    );

TRACE_EVENT(rxrpc_rx_challenge,
	    TP_PROTO(struct rxrpc_connection *conn, rxrpc_serial_t serial,
		     u32 version, u32 nonce, u32 min_level),

	    TP_ARGS(conn, serial, version, nonce, min_level),

	    TP_STRUCT__entry(
		    __field(unsigned int,		conn		)
		    __field(rxrpc_serial_t,		serial		)
		    __field(u32,			version		)
		    __field(u32,			nonce		)
		    __field(u32,			min_level	)
			     ),

	    TP_fast_assign(
		    __entry->conn = conn->debug_id;
		    __entry->serial = serial;
		    __entry->version = version;
		    __entry->nonce = nonce;
		    __entry->min_level = min_level;
			   ),

	    TP_printk("C=%08x CHALLENGE %08x v=%x n=%x ml=%x",
		      __entry->conn,
		      __entry->serial,
		      __entry->version,
		      __entry->nonce,
		      __entry->min_level)
	    );

TRACE_EVENT(rxrpc_rx_response,
	    TP_PROTO(struct rxrpc_connection *conn, rxrpc_serial_t serial,
		     u32 version, u32 kvno, u32 ticket_len),

	    TP_ARGS(conn, serial, version, kvno, ticket_len),

	    TP_STRUCT__entry(
		    __field(unsigned int,		conn		)
		    __field(rxrpc_serial_t,		serial		)
		    __field(u32,			version		)
		    __field(u32,			kvno		)
		    __field(u32,			ticket_len	)
			     ),

	    TP_fast_assign(
		    __entry->conn = conn->debug_id;
		    __entry->serial = serial;
		    __entry->version = version;
		    __entry->kvno = kvno;
		    __entry->ticket_len = ticket_len;
			   ),

	    TP_printk("C=%08x RESPONSE %08x v=%x kvno=%x tl=%x",
		      __entry->conn,
		      __entry->serial,
		      __entry->version,
		      __entry->kvno,
		      __entry->ticket_len)
	    );

TRACE_EVENT(rxrpc_rx_rwind_change,
	    TP_PROTO(struct rxrpc_call *call, rxrpc_serial_t serial,
		     u32 rwind, bool wake),
@@ -1278,6 +1443,44 @@ TRACE_EVENT(rxrpc_congest,
		      __entry->sum.retrans_timeo ? " rTxTo" : "")
	    );

TRACE_EVENT(rxrpc_reset_cwnd,
	    TP_PROTO(struct rxrpc_call *call, ktime_t now),

	    TP_ARGS(call, now),

	    TP_STRUCT__entry(
		    __field(unsigned int,			call		)
		    __field(enum rxrpc_congest_mode,		mode		)
		    __field(unsigned short,			cwnd		)
		    __field(unsigned short,			extra		)
		    __field(rxrpc_seq_t,			hard_ack	)
		    __field(rxrpc_seq_t,			prepared	)
		    __field(ktime_t,				since_last_tx	)
		    __field(bool,				has_data	)
			     ),

	    TP_fast_assign(
		    __entry->call	= call->debug_id;
		    __entry->mode	= call->cong_mode;
		    __entry->cwnd	= call->cong_cwnd;
		    __entry->extra	= call->cong_extra;
		    __entry->hard_ack	= call->acks_hard_ack;
		    __entry->prepared	= call->tx_prepared - call->tx_bottom;
		    __entry->since_last_tx = ktime_sub(now, call->tx_last_sent);
		    __entry->has_data	= !list_empty(&call->tx_sendmsg);
			   ),

	    TP_printk("c=%08x q=%08x %s cw=%u+%u pr=%u tm=%llu d=%u",
		      __entry->call,
		      __entry->hard_ack,
		      __print_symbolic(__entry->mode, rxrpc_congest_modes),
		      __entry->cwnd,
		      __entry->extra,
		      __entry->prepared,
		      ktime_to_ns(__entry->since_last_tx),
		      __entry->has_data)
	    );

TRACE_EVENT(rxrpc_disconnect_call,
	    TP_PROTO(struct rxrpc_call *call),

@@ -1352,6 +1555,7 @@ TRACE_EVENT(rxrpc_connect_call,
		    __field(unsigned long,		user_call_ID	)
		    __field(u32,			cid		)
		    __field(u32,			call_id		)
		    __field_struct(struct sockaddr_rxrpc, srx		)
			     ),

	    TP_fast_assign(
@@ -1359,33 +1563,42 @@ TRACE_EVENT(rxrpc_connect_call,
		    __entry->user_call_ID = call->user_call_ID;
		    __entry->cid = call->cid;
		    __entry->call_id = call->call_id;
		    __entry->srx = call->dest_srx;
			   ),

	    TP_printk("c=%08x u=%p %08x:%08x",
	    TP_printk("c=%08x u=%p %08x:%08x dst=%pISp",
		      __entry->call,
		      (void *)__entry->user_call_ID,
		      __entry->cid,
		      __entry->call_id)
		      __entry->call_id,
		      &__entry->srx.transport)
	    );

TRACE_EVENT(rxrpc_resend,
	    TP_PROTO(struct rxrpc_call *call),
	    TP_PROTO(struct rxrpc_call *call, struct sk_buff *ack),

	    TP_ARGS(call),
	    TP_ARGS(call, ack),

	    TP_STRUCT__entry(
		    __field(unsigned int,		call		)
		    __field(rxrpc_seq_t,		seq		)
		    __field(rxrpc_seq_t,		transmitted	)
		    __field(rxrpc_serial_t,		ack_serial	)
			     ),

	    TP_fast_assign(
		    struct rxrpc_skb_priv *sp = ack ? rxrpc_skb(ack) : NULL;
		    __entry->call = call->debug_id;
		    __entry->seq = call->acks_hard_ack;
		    __entry->transmitted = call->tx_transmitted;
		    __entry->ack_serial = sp ? sp->hdr.serial : 0;
			   ),

	    TP_printk("c=%08x q=%x",
	    TP_printk("c=%08x r=%x q=%x tq=%x",
		      __entry->call,
		      __entry->seq)
		      __entry->ack_serial,
		      __entry->seq,
		      __entry->transmitted)
	    );

TRACE_EVENT(rxrpc_rx_icmp,
@@ -1586,6 +1799,47 @@ TRACE_EVENT(rxrpc_txbuf,
		      __entry->ref)
	    );

TRACE_EVENT(rxrpc_poke_call,
	    TP_PROTO(struct rxrpc_call *call, bool busy,
		     enum rxrpc_call_poke_trace what),

	    TP_ARGS(call, busy, what),

	    TP_STRUCT__entry(
		    __field(unsigned int,		call_debug_id	)
		    __field(bool,			busy		)
		    __field(enum rxrpc_call_poke_trace,	what		)
			     ),

	    TP_fast_assign(
		    __entry->call_debug_id = call->debug_id;
		    __entry->busy = busy;
		    __entry->what = what;
			   ),

	    TP_printk("c=%08x %s%s",
		      __entry->call_debug_id,
		      __print_symbolic(__entry->what, rxrpc_call_poke_traces),
		      __entry->busy ? "!" : "")
	    );

TRACE_EVENT(rxrpc_call_poked,
	    TP_PROTO(struct rxrpc_call *call),

	    TP_ARGS(call),

	    TP_STRUCT__entry(
		    __field(unsigned int,		call_debug_id	)
			     ),

	    TP_fast_assign(
		    __entry->call_debug_id = call->debug_id;
			   ),

	    TP_printk("c=%08x",
		      __entry->call_debug_id)
	    );

#undef EM
#undef E_
#endif /* _TRACE_RXRPC_H */
+7 −0
Original line number Diff line number Diff line
@@ -58,4 +58,11 @@ config RXKAD

	  See Documentation/networking/rxrpc.rst.

config RXPERF
	tristate "RxRPC test service"
	help
	  Provide an rxperf service tester.  This listens on UDP port 7009 for
	  incoming calls from the rxperf program (an example of which can be
	  found in OpenAFS).

endif
+4 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ rxrpc-y := \
	conn_service.o \
	input.o \
	insecure.o \
	io_thread.o \
	key.o \
	local_event.o \
	local_object.o \
@@ -36,3 +37,6 @@ rxrpc-y := \
rxrpc-$(CONFIG_PROC_FS) += proc.o
rxrpc-$(CONFIG_RXKAD) += rxkad.o
rxrpc-$(CONFIG_SYSCTL) += sysctl.o


obj-$(CONFIG_RXPERF) += rxperf.o
+7 −11
Original line number Diff line number Diff line
@@ -194,8 +194,8 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)

service_in_use:
	write_unlock(&local->services_lock);
	rxrpc_unuse_local(local);
	rxrpc_put_local(local);
	rxrpc_unuse_local(local, rxrpc_local_unuse_bind);
	rxrpc_put_local(local, rxrpc_local_put_bind);
	ret = -EADDRINUSE;
error_unlock:
	release_sock(&rx->sk);
@@ -328,7 +328,7 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
		mutex_unlock(&call->user_mutex);
	}

	rxrpc_put_peer(cp.peer);
	rxrpc_put_peer(cp.peer, rxrpc_peer_put_discard_tmp);
	_leave(" = %p", call);
	return call;
}
@@ -359,9 +359,9 @@ void rxrpc_kernel_end_call(struct socket *sock, struct rxrpc_call *call)

	/* Make sure we're not going to call back into a kernel service */
	if (call->notify_rx) {
		spin_lock_bh(&call->notify_lock);
		spin_lock(&call->notify_lock);
		call->notify_rx = rxrpc_dummy_notify_rx;
		spin_unlock_bh(&call->notify_lock);
		spin_unlock(&call->notify_lock);
	}

	mutex_unlock(&call->user_mutex);
@@ -812,14 +812,12 @@ static int rxrpc_shutdown(struct socket *sock, int flags)

	lock_sock(sk);

	spin_lock_bh(&sk->sk_receive_queue.lock);
	if (sk->sk_state < RXRPC_CLOSE) {
		sk->sk_state = RXRPC_CLOSE;
		sk->sk_shutdown = SHUTDOWN_MASK;
	} else {
		ret = -ESHUTDOWN;
	}
	spin_unlock_bh(&sk->sk_receive_queue.lock);

	rxrpc_discard_prealloc(rx);

@@ -872,9 +870,7 @@ static int rxrpc_release_sock(struct sock *sk)
		break;
	}

	spin_lock_bh(&sk->sk_receive_queue.lock);
	sk->sk_state = RXRPC_CLOSE;
	spin_unlock_bh(&sk->sk_receive_queue.lock);

	if (rx->local && rcu_access_pointer(rx->local->service) == rx) {
		write_lock(&rx->local->services_lock);
@@ -888,8 +884,8 @@ static int rxrpc_release_sock(struct sock *sk)
	flush_workqueue(rxrpc_workqueue);
	rxrpc_purge_queue(&sk->sk_receive_queue);

	rxrpc_unuse_local(rx->local);
	rxrpc_put_local(rx->local);
	rxrpc_unuse_local(rx->local, rxrpc_local_unuse_release_sock);
	rxrpc_put_local(rx->local, rxrpc_local_put_release_sock);
	rx->local = NULL;
	key_put(rx->key);
	rx->key = NULL;
Loading