Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge tag 'rxrpc-rewrite-20160929' of...

Merge tag 'rxrpc-rewrite-20160929' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs



David Howells says:

====================
rxrpc: Fixes and adjustments

This set of patches contains some fixes and adjustments:

 (1) Connections for exclusive calls are being reused because the check to
     work out whether to set RXRPC_CONN_DONT_REUSE is checking where the
     parameters will be copied to (but haven't yet).

 (2) Make Tx loss-injection go through the normal return, so the state gets
     set correctly for what the code thinks it has done.

     Note lost Tx packets in the tx_data trace rather than the skb
     tracepoint.

 (3) Activate channels according to the current state from within the
     channel_lock to avoid someone changing it on us.

 (4) Reduce the local endpoint's services list to a single pointer as we
     don't allow service AF_RXRPC sockets to share UDP ports with other
     AF_RXRPC sockets, so there can't be more than one element in the list.

 (5) Request more ACKs in slow-start mode to help monitor the state driving
     the window configuration.

 (6) Display the serial number of the packet being ACK'd rather than the
     ACK packet's own serial number in the congestion trace as this can be
     related to other entries in the trace.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 4e9f4b39 ed1e8679
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -258,15 +258,16 @@ TRACE_EVENT(rxrpc_rx_ack,

TRACE_EVENT(rxrpc_tx_data,
	    TP_PROTO(struct rxrpc_call *call, rxrpc_seq_t seq,
		     rxrpc_serial_t serial, u8 flags, bool lose),
		     rxrpc_serial_t serial, u8 flags, bool retrans, bool lose),

	    TP_ARGS(call, seq, serial, flags, lose),
	    TP_ARGS(call, seq, serial, flags, retrans, lose),

	    TP_STRUCT__entry(
		    __field(struct rxrpc_call *,	call		)
		    __field(rxrpc_seq_t,		seq		)
		    __field(rxrpc_serial_t,		serial		)
		    __field(u8,				flags		)
		    __field(bool,			retrans		)
		    __field(bool,			lose		)
			     ),

@@ -275,6 +276,7 @@ TRACE_EVENT(rxrpc_tx_data,
		    __entry->seq = seq;
		    __entry->serial = serial;
		    __entry->flags = flags;
		    __entry->retrans = retrans;
		    __entry->lose = lose;
			   ),

+8 −13
Original line number Diff line number Diff line
@@ -136,7 +136,8 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
	struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *)saddr;
	struct sock *sk = sock->sk;
	struct rxrpc_local *local;
	struct rxrpc_sock *rx = rxrpc_sk(sk), *prx;
	struct rxrpc_sock *rx = rxrpc_sk(sk);
	u16 service_id = srx->srx_service;
	int ret;

	_enter("%p,%p,%d", rx, saddr, len);
@@ -160,15 +161,12 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
		goto error_unlock;
	}

	if (rx->srx.srx_service) {
	if (service_id) {
		write_lock(&local->services_lock);
		hlist_for_each_entry(prx, &local->services, listen_link) {
			if (prx->srx.srx_service == rx->srx.srx_service)
		if (rcu_access_pointer(local->service))
			goto service_in_use;
		}

		rx->local = local;
		hlist_add_head_rcu(&rx->listen_link, &local->services);
		rcu_assign_pointer(local->service, rx);
		write_unlock(&local->services_lock);

		rx->sk.sk_state = RXRPC_SERVER_BOUND;
@@ -599,7 +597,6 @@ static int rxrpc_create(struct net *net, struct socket *sock, int protocol,
	rx->family = protocol;
	rx->calls = RB_ROOT;

	INIT_HLIST_NODE(&rx->listen_link);
	spin_lock_init(&rx->incoming_lock);
	INIT_LIST_HEAD(&rx->sock_calls);
	INIT_LIST_HEAD(&rx->to_be_accepted);
@@ -681,11 +678,9 @@ static int rxrpc_release_sock(struct sock *sk)
	sk->sk_state = RXRPC_CLOSE;
	spin_unlock_bh(&sk->sk_receive_queue.lock);

	ASSERTCMP(rx->listen_link.next, !=, LIST_POISON1);

	if (!hlist_unhashed(&rx->listen_link)) {
	if (rx->local && rx->local->service == rx) {
		write_lock(&rx->local->services_lock);
		hlist_del_rcu(&rx->listen_link);
		rx->local->service = NULL;
		write_unlock(&rx->local->services_lock);
	}

+2 −4
Original line number Diff line number Diff line
@@ -93,7 +93,6 @@ struct rxrpc_sock {
	rxrpc_notify_new_call_t	notify_new_call; /* Func to notify of new call */
	rxrpc_discard_new_call_t discard_new_call; /* Func to discard a new call */
	struct rxrpc_local	*local;		/* local endpoint */
	struct hlist_node	listen_link;	/* link in the local endpoint's listen list */
	struct rxrpc_backlog	*backlog;	/* Preallocation for services */
	spinlock_t		incoming_lock;	/* Incoming call vs service shutdown lock */
	struct list_head	sock_calls;	/* List of calls owned by this socket */
@@ -216,7 +215,7 @@ struct rxrpc_local {
	struct list_head	link;
	struct socket		*socket;	/* my UDP socket */
	struct work_struct	processor;
	struct hlist_head	services;	/* services listening on this endpoint */
	struct rxrpc_sock __rcu	*service;	/* Service(s) listening on this endpoint */
	struct rw_semaphore	defrag_sem;	/* control re-enablement of IP DF bit */
	struct sk_buff_head	reject_queue;	/* packets awaiting rejection */
	struct sk_buff_head	event_queue;	/* endpoint event packets awaiting processing */
@@ -603,7 +602,6 @@ enum rxrpc_skb_trace {
	rxrpc_skb_tx_cleaned,
	rxrpc_skb_tx_freed,
	rxrpc_skb_tx_got,
	rxrpc_skb_tx_lost,
	rxrpc_skb_tx_new,
	rxrpc_skb_tx_rotated,
	rxrpc_skb_tx_seen,
@@ -1073,7 +1071,7 @@ extern const s8 rxrpc_ack_priority[];
 * output.c
 */
int rxrpc_send_call_packet(struct rxrpc_call *, u8);
int rxrpc_send_data_packet(struct rxrpc_call *, struct sk_buff *);
int rxrpc_send_data_packet(struct rxrpc_call *, struct sk_buff *, bool);
void rxrpc_reject_packets(struct rxrpc_local *);

/*
+4 −4
Original line number Diff line number Diff line
@@ -331,14 +331,14 @@ struct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *local,
	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
	struct rxrpc_sock *rx;
	struct rxrpc_call *call;
	u16 service_id = sp->hdr.serviceId;

	_enter("");

	/* Get the socket providing the service */
	hlist_for_each_entry_rcu_bh(rx, &local->services, listen_link) {
		if (rx->srx.srx_service == sp->hdr.serviceId)
	rx = rcu_dereference(local->service);
	if (service_id == rx->srx.srx_service)
		goto found_service;
	}

	trace_rxrpc_abort("INV", sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
			  RX_INVALID_OPERATION, EOPNOTSUPP);
+1 −1
Original line number Diff line number Diff line
@@ -256,7 +256,7 @@ static void rxrpc_resend(struct rxrpc_call *call)
		rxrpc_get_skb(skb, rxrpc_skb_tx_got);
		spin_unlock_bh(&call->lock);

		if (rxrpc_send_data_packet(call, skb) < 0) {
		if (rxrpc_send_data_packet(call, skb, true) < 0) {
			rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
			return;
		}
Loading