Commit f3441d41 authored by David Howells's avatar David Howells
Browse files

rxrpc: Copy client call parameters into rxrpc_call earlier



Copy client call parameters into rxrpc_call earlier so that that can be
used to convey them to the connection code - which can then be offloaded to
the I/O thread.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
parent 15f661dc
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@

#define rxrpc_local_traces \
	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    ") \
@@ -61,6 +62,7 @@
	EM(rxrpc_local_processing,		"PROCESSING  ") \
	EM(rxrpc_local_put_already_queued,	"PUT alreadyq") \
	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    ") \
@@ -166,6 +168,7 @@
	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    ") \
+6 −1
Original line number Diff line number Diff line
@@ -530,6 +530,7 @@ enum rxrpc_call_flag {
	RXRPC_CALL_UPGRADE,		/* Service upgrade was requested for the call */
	RXRPC_CALL_DELAY_ACK_PENDING,	/* DELAY ACK generation is pending */
	RXRPC_CALL_IDLE_ACK_PENDING,	/* IDLE ACK generation is pending */
	RXRPC_CALL_EXCLUSIVE,		/* The call uses a once-only connection */
};

/*
@@ -592,10 +593,13 @@ struct rxrpc_call {
	struct rcu_head		rcu;
	struct rxrpc_connection	*conn;		/* connection carrying call */
	struct rxrpc_peer	*peer;		/* Peer record for remote address */
	struct rxrpc_local	*local;		/* Representation of local endpoint */
	struct rxrpc_sock __rcu	*socket;	/* socket responsible */
	struct rxrpc_net	*rxnet;		/* Network namespace to which call belongs */
	struct key		*key;		/* Security details */
	const struct rxrpc_security *security;	/* applied security module */
	struct mutex		user_mutex;	/* User access mutex */
	struct sockaddr_rxrpc	dest_srx;	/* Destination address */
	unsigned long		delay_ack_at;	/* When DELAY ACK needs to happen */
	unsigned long		ack_lost_at;	/* When ACK is figured as lost */
	unsigned long		resend_at;	/* When next resend needs to happen */
@@ -631,11 +635,11 @@ struct rxrpc_call {
	enum rxrpc_call_state	state;		/* current state of call */
	enum rxrpc_call_completion completion;	/* Call completion condition */
	refcount_t		ref;
	u16			service_id;	/* service ID */
	u8			security_ix;	/* Security type */
	enum rxrpc_interruptibility interruptibility; /* At what point call may be interrupted */
	u32			call_id;	/* call ID on connection  */
	u32			cid;		/* connection ID plus channel index */
	u32			security_level;	/* Security level selected */
	int			debug_id;	/* debug ID for printks */
	unsigned short		rx_pkt_offset;	/* Current recvmsg packet offset */
	unsigned short		rx_pkt_len;	/* Current recvmsg packet len */
@@ -1147,6 +1151,7 @@ extern const struct rxrpc_security rxkad;
int __init rxrpc_init_security(void);
const struct rxrpc_security *rxrpc_security_lookup(u8);
void rxrpc_exit_security(void);
int rxrpc_init_client_call_security(struct rxrpc_call *);
int rxrpc_init_client_conn_security(struct rxrpc_connection *);
const struct rxrpc_security *rxrpc_get_incoming_security(struct rxrpc_sock *,
							 struct sk_buff *);
+2 −0
Original line number Diff line number Diff line
@@ -318,10 +318,12 @@ static struct rxrpc_call *rxrpc_alloc_incoming_call(struct rxrpc_sock *rx,
			  (call_tail + 1) & (RXRPC_BACKLOG_MAX - 1));

	rxrpc_see_call(call, rxrpc_call_see_accept);
	call->local = rxrpc_get_local(conn->local, rxrpc_local_get_call);
	call->conn = conn;
	call->security = conn->security;
	call->security_ix = conn->security_ix;
	call->peer = rxrpc_get_peer(conn->peer, rxrpc_peer_get_accept);
	call->dest_srx = peer->srx;
	call->cong_ssthresh = call->peer->cong_ssthresh;
	call->tx_last_sent = ktime_get_real();
	return call;
+31 −19
Original line number Diff line number Diff line
@@ -47,14 +47,9 @@ static struct semaphore rxrpc_kernel_call_limiter =

void rxrpc_poke_call(struct rxrpc_call *call, enum rxrpc_call_poke_trace what)
{
	struct rxrpc_local *local;
	struct rxrpc_peer *peer = call->peer;
	struct rxrpc_local *local = call->local;
	bool busy;

	if (WARN_ON_ONCE(!peer))
		return;
	local = peer->local;

	if (call->state < RXRPC_CALL_COMPLETE) {
		spin_lock_bh(&local->lock);
		busy = !list_empty(&call->attend_link);
@@ -200,22 +195,45 @@ struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp,
 */
static struct rxrpc_call *rxrpc_alloc_client_call(struct rxrpc_sock *rx,
						  struct sockaddr_rxrpc *srx,
						  struct rxrpc_conn_parameters *cp,
						  struct rxrpc_call_params *p,
						  gfp_t gfp,
						  unsigned int debug_id)
{
	struct rxrpc_call *call;
	ktime_t now;
	int ret;

	_enter("");

	call = rxrpc_alloc_call(rx, gfp, debug_id);
	if (!call)
		return ERR_PTR(-ENOMEM);
	call->state = RXRPC_CALL_CLIENT_AWAIT_CONN;
	call->service_id = srx->srx_service;
	now = ktime_get_real();
	call->acks_latest_ts	= now;
	call->cong_tstamp	= now;
	call->state		= RXRPC_CALL_CLIENT_AWAIT_CONN;
	call->dest_srx		= *srx;
	call->interruptibility	= p->interruptibility;
	call->tx_total_len	= p->tx_total_len;
	call->key		= key_get(cp->key);
	call->local		= rxrpc_get_local(cp->local, rxrpc_local_get_call);
	if (p->kernel)
		__set_bit(RXRPC_CALL_KERNEL, &call->flags);
	if (cp->upgrade)
		__set_bit(RXRPC_CALL_UPGRADE, &call->flags);
	if (cp->exclusive)
		__set_bit(RXRPC_CALL_EXCLUSIVE, &call->flags);

	ret = rxrpc_init_client_call_security(call);
	if (ret < 0) {
		__rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, 0, ret);
		rxrpc_put_call(call, rxrpc_call_put_discard_error);
		return ERR_PTR(ret);
	}

	trace_rxrpc_call(call->debug_id, refcount_read(&call->ref),
			 p->user_call_ID, rxrpc_call_new_client);

	_leave(" = %p", call);
	return call;
@@ -295,7 +313,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
		return ERR_PTR(-ERESTARTSYS);
	}

	call = rxrpc_alloc_client_call(rx, srx, gfp, debug_id);
	call = rxrpc_alloc_client_call(rx, srx, cp, p, gfp, debug_id);
	if (IS_ERR(call)) {
		release_sock(&rx->sk);
		up(limiter);
@@ -303,13 +321,6 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
		return call;
	}

	call->interruptibility = p->interruptibility;
	call->tx_total_len = p->tx_total_len;
	trace_rxrpc_call(call->debug_id, refcount_read(&call->ref),
			 p->user_call_ID, rxrpc_call_new_client);
	if (p->kernel)
		__set_bit(RXRPC_CALL_KERNEL, &call->flags);

	/* We need to protect a partially set up call against the user as we
	 * will be acting outside the socket lock.
	 */
@@ -413,7 +424,7 @@ void rxrpc_incoming_call(struct rxrpc_sock *rx,

	rcu_assign_pointer(call->socket, rx);
	call->call_id		= sp->hdr.callNumber;
	call->service_id	= sp->hdr.serviceId;
	call->dest_srx.srx_service = sp->hdr.serviceId;
	call->cid		= sp->hdr.cid;
	call->state		= RXRPC_CALL_SERVER_SECURING;
	call->cong_tstamp	= skb->tstamp;
@@ -639,6 +650,7 @@ static void rxrpc_destroy_call(struct work_struct *work)
	rxrpc_free_skb(call->acks_soft_tbl, rxrpc_skb_put_ack);
	rxrpc_put_connection(call->conn, rxrpc_conn_put_call);
	rxrpc_put_peer(call->peer, rxrpc_peer_put_call);
	rxrpc_put_local(call->local, rxrpc_local_put_call);
	call_rcu(&call->rcu, rxrpc_rcu_free_call);
}

+1 −1
Original line number Diff line number Diff line
@@ -553,7 +553,7 @@ static void rxrpc_activate_one_channel(struct rxrpc_connection *conn,
	call->call_id	= call_id;
	call->security	= conn->security;
	call->security_ix = conn->security_ix;
	call->service_id = conn->service_id;
	call->dest_srx.srx_service = conn->service_id;

	trace_rxrpc_connect_call(call);

Loading