Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8FE4BC2BB1D for ; Wed, 24 Nov 2021 12:16:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243656AbhKXMSo (ORCPT ); Wed, 24 Nov 2021 07:18:44 -0500 Received: from mail.kernel.org ([198.145.29.99]:47684 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242954AbhKXMNM (ORCPT ); Wed, 24 Nov 2021 07:13:12 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 7B2FD610FE; Wed, 24 Nov 2021 12:07:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1637755647; bh=4Q9Za+5KmPVZ4TUcvRbgFLBBLzm6NO2EEEDWk60V+mw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ydovCjC8ehZ72jZC1qDv/F4/8Kyo1QJMQm3g0uv6viboSKM4zNur8xJRgQiEpt73J mYobz3BJoF57uwXYDB9KqVSfLwWr1EJYq0ppDTPSHlB89GumC0RiWsLwWLrOeN4pZ8 oceDECdiE5LsR9dTgf6WFOe0EeJbvHW85EjMlOlY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Greg Kroah-Hartman , Sven Eckelmann , Simon Wunderlich Subject: [PATCH 4.4 157/162] batman-adv: Reserve needed_*room for fragments Date: Wed, 24 Nov 2021 12:57:40 +0100 Message-Id: <20211124115703.355280561@linuxfoundation.org> X-Mailer: git-send-email 2.34.0 In-Reply-To: <20211124115658.328640564@linuxfoundation.org> References: <20211124115658.328640564@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Sven Eckelmann commit c5cbfc87558168ef4c3c27ce36eba6b83391db19 upstream. The batadv net_device is trying to propagate the needed_headroom and needed_tailroom from the lower devices. This is needed to avoid cost intensive reallocations using pskb_expand_head during the transmission. But the fragmentation code split the skb's without adding extra room at the end/beginning of the various fragments. This reduced the performance of transmissions over complex scenarios (batadv on vxlan on wireguard) because the lower devices had to perform the reallocations at least once. Fixes: ee75ed88879a ("batman-adv: Fragment and send skbs larger than mtu") Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich [ bp: 4.4 backported: adjust context. ] Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- net/batman-adv/fragmentation.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c @@ -394,6 +394,7 @@ out: /** * batadv_frag_create - create a fragment from skb + * @net_dev: outgoing device for fragment * @skb: skb to create fragment from * @frag_head: header to use in new fragment * @fragment_size: size of new fragment @@ -404,22 +405,25 @@ out: * * Returns the new fragment, NULL on error. */ -static struct sk_buff *batadv_frag_create(struct sk_buff *skb, +static struct sk_buff *batadv_frag_create(struct net_device *net_dev, + struct sk_buff *skb, struct batadv_frag_packet *frag_head, unsigned int fragment_size) { + unsigned int ll_reserved = LL_RESERVED_SPACE(net_dev); + unsigned int tailroom = net_dev->needed_tailroom; struct sk_buff *skb_fragment; unsigned header_size = sizeof(*frag_head); unsigned mtu = fragment_size + header_size; - skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN); + skb_fragment = dev_alloc_skb(ll_reserved + mtu + tailroom); if (!skb_fragment) goto err; skb->priority = TC_PRIO_CONTROL; /* Eat the last mtu-bytes of the skb */ - skb_reserve(skb_fragment, header_size + ETH_HLEN); + skb_reserve(skb_fragment, ll_reserved + header_size); skb_split(skb, skb_fragment, skb->len - fragment_size); /* Add the header */ @@ -442,11 +446,12 @@ bool batadv_frag_send_packet(struct sk_b struct batadv_orig_node *orig_node, struct batadv_neigh_node *neigh_node) { + struct net_device *net_dev = neigh_node->if_incoming->net_dev; struct batadv_priv *bat_priv; struct batadv_hard_iface *primary_if = NULL; struct batadv_frag_packet frag_header; struct sk_buff *skb_fragment; - unsigned mtu = neigh_node->if_incoming->net_dev->mtu; + unsigned mtu = net_dev->mtu; unsigned header_size = sizeof(frag_header); unsigned max_fragment_size, num_fragments; bool ret = false; @@ -489,7 +494,7 @@ bool batadv_frag_send_packet(struct sk_b if (frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1) goto out_err; - skb_fragment = batadv_frag_create(skb, &frag_header, + skb_fragment = batadv_frag_create(net_dev, skb, &frag_header, max_fragment_size); if (!skb_fragment) goto out_err;