Commit 54086c5a authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files


David Howells says:

====================
rxrpc fixes

Here are a couple of fixes that need to be applied on top of rxrpc patches
in net-next:

 (1) Fix a bug in the connection bundle changes in the net-next tree.

 (2) Fix the loss of final ACK on socket shutdown.
====================

Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 0ec78cdb ddc7834a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -831,6 +831,7 @@ void rxrpc_clean_up_local_conns(struct rxrpc_local *);
 * conn_event.c
 */
void rxrpc_process_connection(struct work_struct *);
void rxrpc_process_delayed_final_acks(struct rxrpc_connection *, bool);

/*
 * conn_object.c
+6 −2
Original line number Diff line number Diff line
@@ -901,11 +901,14 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
	struct rxrpc_bundle *bundle = conn->bundle;
	struct rxrpc_local *local = bundle->params.local;
	unsigned int bindex;
	bool need_drop = false;
	bool need_drop = false, need_put = false;
	int i;

	_enter("C=%x", conn->debug_id);

	if (conn->flags & RXRPC_CONN_FINAL_ACK_MASK)
		rxrpc_process_delayed_final_acks(conn, true);

	spin_lock(&bundle->channel_lock);
	bindex = conn->bundle_shift / RXRPC_MAXCALLS;
	if (bundle->conns[bindex] == conn) {
@@ -928,10 +931,11 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
		if (i == ARRAY_SIZE(bundle->conns) && !bundle->params.exclusive) {
			_debug("erase bundle");
			rb_erase(&bundle->local_node, &local->client_bundles);
			need_put = true;
		}

		spin_unlock(&local->client_bundles_lock);
		if (i == ARRAY_SIZE(bundle->conns))
		if (need_put)
			rxrpc_put_bundle(bundle);
	}

+3 −3
Original line number Diff line number Diff line
@@ -397,7 +397,7 @@ abort:
/*
 * Process delayed final ACKs that we haven't subsumed into a subsequent call.
 */
static void rxrpc_process_delayed_final_acks(struct rxrpc_connection *conn)
void rxrpc_process_delayed_final_acks(struct rxrpc_connection *conn, bool force)
{
	unsigned long j = jiffies, next_j;
	unsigned int channel;
@@ -416,7 +416,7 @@ again:
		smp_rmb(); /* vs rxrpc_disconnect_client_call */
		ack_at = READ_ONCE(chan->final_ack_at);

		if (time_before(j, ack_at)) {
		if (time_before(j, ack_at) && !force) {
			if (time_before(ack_at, next_j)) {
				next_j = ack_at;
				set = true;
@@ -450,7 +450,7 @@ static void rxrpc_do_process_connection(struct rxrpc_connection *conn)

	/* Process delayed ACKs whose time has come. */
	if (conn->flags & RXRPC_CONN_FINAL_ACK_MASK)
		rxrpc_process_delayed_final_acks(conn);
		rxrpc_process_delayed_final_acks(conn, false);

	/* go through the conn-level event packets, releasing the ref on this
	 * connection that each one has when we've finished with it */