From nobody Fri Dec 19 04:58:07 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C183F1946B3 for ; Wed, 4 Dec 2024 07:47:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733298481; cv=none; b=nlwKQlS038Xnm15JY8dNgaS5MCX13FzrY7envqoYM+DfiP1zyierVhifQuCp59HqLJ0calLiCtbw++6Kw9Y+1WJoN1Yn8eMeNSuTuhknZhbyO7lTpY2EZa3fZiqUTXGOxInezBdg6c5pC1VUmf9uUnRgA51fllTqNXBtZHQqrj8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733298481; c=relaxed/simple; bh=yZpcH3jfOZhaIMhDc90aLeHm+zbrPem84Ky8S2xB72U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oUt/8fff0cgY2aztJ07mrSmphD1NWiX1m4gEN+Ipr4mK7xoj2z/qnuaPXQqmf4I2SJyePVJvvMoGfvooFAisGTc+qx22Oci8xvss4ENDJZSgtPectUR/w8Xuk7h9veqprBDJZj1x0+1163o/hCkTQfXdKX/v7TC85LlQ06Zw7IE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=goQGfcvO; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="goQGfcvO" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1733298478; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7YbPQ3cKw3bKxL4TM3+ZS8qJ4Li9YNqJTqyKnz0s0FM=; b=goQGfcvOnbhtAIZO9qKuWrxdebZmylBF3GT403k0qq73fz0svyg936Fp3OacJfj1e3/J+M Usr7stna6QDTkPAOSkmCI6Z1dNL54UBwa0lPxErvO52MnGkNmVWel8ZP5RjeatGYCA8cop 7TEJWk52eAOh1W1C8KXTWI/Ak8kenRI= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-657-Him0VSniOuG3SqQfmI2MLw-1; Wed, 04 Dec 2024 02:47:53 -0500 X-MC-Unique: Him0VSniOuG3SqQfmI2MLw-1 X-Mimecast-MFC-AGG-ID: Him0VSniOuG3SqQfmI2MLw Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 526CA1956058; Wed, 4 Dec 2024 07:47:52 +0000 (UTC) Received: from warthog.procyon.org.uk.com (unknown [10.42.28.48]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id ABE351956048; Wed, 4 Dec 2024 07:47:49 +0000 (UTC) From: David Howells To: netdev@vger.kernel.org Cc: David Howells , Marc Dionne , Yunsheng Lin , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-afs@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 08/39] rxrpc: Use a large kvec[] in rxrpc_local rather than every rxrpc_txbuf Date: Wed, 4 Dec 2024 07:46:36 +0000 Message-ID: <20241204074710.990092-9-dhowells@redhat.com> In-Reply-To: <20241204074710.990092-1-dhowells@redhat.com> References: <20241204074710.990092-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 Content-Type: text/plain; charset="utf-8" Use a single large kvec[] in the rxrpc_local struct rather than one in every rxrpc_txbuf struct to build large packets to save on memory. Signed-off-by: David Howells cc: Marc Dionne cc: "David S. Miller" cc: Eric Dumazet cc: Jakub Kicinski cc: Paolo Abeni cc: linux-afs@lists.infradead.org cc: netdev@vger.kernel.org --- net/rxrpc/ar-internal.h | 6 ++++++ net/rxrpc/output.c | 45 ++++++++++++++++++++++++++++++----------- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index d0fd37bdcfe9..ab8e565cb20b 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h @@ -320,6 +320,12 @@ struct rxrpc_local { struct list_head new_client_calls; /* Newly created client calls need con= nection */ spinlock_t client_call_lock; /* Lock for ->new_client_calls */ struct sockaddr_rxrpc srx; /* local address */ + /* Provide a kvec table sufficiently large to manage either a DATA + * packet with a maximum set of jumbo subpackets or a PING ACK padded + * out to 64K with zeropages for PMTUD. + */ + struct kvec kvec[RXRPC_MAX_NR_JUMBO > 3 + 16 ? + RXRPC_MAX_NR_JUMBO : 3 + 16]; }; =20 /* diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c index b93a5d50be3e..f8bb5250e849 100644 --- a/net/rxrpc/output.c +++ b/net/rxrpc/output.c @@ -175,9 +175,11 @@ static void rxrpc_begin_rtt_probe(struct rxrpc_call *c= all, rxrpc_serial_t serial /* * Transmit an ACK packet. */ -static void rxrpc_send_ack_packet(struct rxrpc_call *call, struct rxrpc_tx= buf *txb) +static void rxrpc_send_ack_packet(struct rxrpc_call *call, struct rxrpc_tx= buf *txb, + int nr_kv) { - struct rxrpc_wire_header *whdr =3D txb->kvec[0].iov_base; + struct kvec *kv =3D call->local->kvec; + struct rxrpc_wire_header *whdr =3D kv[0].iov_base; struct rxrpc_connection *conn; struct rxrpc_ackpacket *ack =3D (struct rxrpc_ackpacket *)(whdr + 1); struct msghdr msg; @@ -206,8 +208,9 @@ static void rxrpc_send_ack_packet(struct rxrpc_call *ca= ll, struct rxrpc_txbuf *t =20 rxrpc_inc_stat(call->rxnet, stat_tx_ack_send); =20 - iov_iter_kvec(&msg.msg_iter, WRITE, txb->kvec, txb->nr_kvec, txb->len); + iov_iter_kvec(&msg.msg_iter, WRITE, kv, nr_kv, txb->len); rxrpc_local_dont_fragment(conn->local, false); + ret =3D do_udp_sendmsg(conn->local->socket, &msg, txb->len); call->peer->last_tx_at =3D ktime_get_seconds(); if (ret < 0) { @@ -233,6 +236,8 @@ void rxrpc_send_ACK(struct rxrpc_call *call, u8 ack_rea= son, rxrpc_serial_t serial, enum rxrpc_propose_ack_trace why) { struct rxrpc_txbuf *txb; + struct kvec *kv =3D call->local->kvec; + int nr_kv; =20 if (test_bit(RXRPC_CALL_DISCONNECTED, &call->flags)) return; @@ -248,12 +253,19 @@ void rxrpc_send_ACK(struct rxrpc_call *call, u8 ack_r= eason, txb->ack_why =3D why; =20 rxrpc_fill_out_ack(call, txb, ack_reason, serial); + + nr_kv =3D txb->nr_kvec; + kv[0] =3D txb->kvec[0]; + kv[1] =3D txb->kvec[1]; + kv[2] =3D txb->kvec[2]; + // TODO: Extend a path MTU probe ACK + call->ackr_nr_unacked =3D 0; atomic_set(&call->ackr_nr_consumed, 0); clear_bit(RXRPC_CALL_RX_IS_IDLE, &call->flags); =20 trace_rxrpc_send_ack(call, why, ack_reason, serial); - rxrpc_send_ack_packet(call, txb); + rxrpc_send_ack_packet(call, txb, nr_kv); rxrpc_put_txbuf(txb, rxrpc_txbuf_put_ack_tx); } =20 @@ -324,12 +336,15 @@ int rxrpc_send_abort_packet(struct rxrpc_call *call) /* * Prepare a (sub)packet for transmission. */ -static void rxrpc_prepare_data_subpacket(struct rxrpc_call *call, struct r= xrpc_txbuf *txb, - rxrpc_serial_t serial) +static size_t rxrpc_prepare_data_subpacket(struct rxrpc_call *call, struct= rxrpc_txbuf *txb, + rxrpc_serial_t serial, + int subpkt) { struct rxrpc_wire_header *whdr =3D txb->kvec[0].iov_base; enum rxrpc_req_ack_trace why; struct rxrpc_connection *conn =3D call->conn; + struct kvec *kv =3D &call->local->kvec[subpkt]; + size_t len =3D txb->len; bool last, more; u8 flags; =20 @@ -385,8 +400,13 @@ static void rxrpc_prepare_data_subpacket(struct rxrpc_= call *call, struct rxrpc_t whdr->flags =3D flags; whdr->serial =3D htonl(txb->serial); whdr->cksum =3D txb->cksum; + whdr->serviceId =3D htons(conn->service_id); + kv->iov_base =3D whdr; + // TODO: Convert into a jumbo header for tail subpackets =20 trace_rxrpc_tx_data(call, txb->seq, txb->serial, flags, false); + kv->iov_len =3D len; + return len; } =20 /* @@ -395,13 +415,15 @@ static void rxrpc_prepare_data_subpacket(struct rxrpc= _call *call, struct rxrpc_t static size_t rxrpc_prepare_data_packet(struct rxrpc_call *call, struct rx= rpc_txbuf *txb) { rxrpc_serial_t serial; + size_t len =3D 0; =20 /* Each transmission of a Tx packet needs a new serial number */ serial =3D rxrpc_get_next_serial(call->conn); =20 - rxrpc_prepare_data_subpacket(call, txb, serial); + len +=3D rxrpc_prepare_data_subpacket(call, txb, serial, 0); + // TODO: Loop around adding tail subpackets =20 - return txb->len; + return len; } =20 /* @@ -442,7 +464,6 @@ static void rxrpc_tstamp_data_packets(struct rxrpc_call= *call, struct rxrpc_txbu */ static int rxrpc_send_data_packet(struct rxrpc_call *call, struct rxrpc_tx= buf *txb) { - struct rxrpc_wire_header *whdr =3D txb->kvec[0].iov_base; struct rxrpc_connection *conn =3D call->conn; enum rxrpc_tx_point frag; struct msghdr msg; @@ -463,7 +484,7 @@ static int rxrpc_send_data_packet(struct rxrpc_call *ca= ll, struct rxrpc_txbuf *t } } =20 - iov_iter_kvec(&msg.msg_iter, WRITE, txb->kvec, txb->nr_kvec, len); + iov_iter_kvec(&msg.msg_iter, WRITE, call->local->kvec, 1, len); =20 msg.msg_name =3D &call->peer->srx.transport; msg.msg_namelen =3D call->peer->srx.transport_len; @@ -480,7 +501,7 @@ static int rxrpc_send_data_packet(struct rxrpc_call *ca= ll, struct rxrpc_txbuf *t =20 /* send the packet with the don't fragment bit set if we currently * think it's small enough */ - if (txb->len >=3D call->peer->maxdata) { + if (len >=3D sizeof(struct rxrpc_wire_header) + call->peer->maxdata) { rxrpc_local_dont_fragment(conn->local, false); frag =3D rxrpc_tx_point_call_data_frag; } else { @@ -503,7 +524,7 @@ static int rxrpc_send_data_packet(struct rxrpc_call *ca= ll, struct rxrpc_txbuf *t rxrpc_inc_stat(call->rxnet, stat_tx_data_send_fail); trace_rxrpc_tx_fail(call->debug_id, txb->serial, ret, frag); } else { - trace_rxrpc_tx_packet(call->debug_id, whdr, frag); + trace_rxrpc_tx_packet(call->debug_id, call->local->kvec[0].iov_base, fra= g); } =20 rxrpc_tx_backoff(call, ret);