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

Commit 27c8b456 authored by Skylar Chang's avatar Skylar Chang
Browse files

msm: ipa3: do not use skb clones for lan clients



IPA driver uses 8k buffers for RX packets as those are aggregated.
If these packets deaggregated in IPA driver, cloned and provided
to clients, later calls to skb_copy() results in creating an 8k skb
which may lead to high memory utilization.
This change avoid the use of skb clones and allocates new skbs
for LAN clients and copy the packet content to it.

Change-Id: I0755f4f271ff0751b731fdd6c2298ddc057b0e33
CRs-Fixed: 960822
Acked by: Ady Abraham <adya@qti.qualcomm.com>
Signed-off-by: default avatarSkylar Chang <chiaweic@codeaurora.org>
parent e3bb1fd4
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -38,6 +38,8 @@
#define IPA_GENERIC_RX_BUFF_SZ (IPA_GENERIC_RX_BUFF_BASE_SZ -\
		(IPA_REAL_GENERIC_RX_BUFF_SZ - IPA_GENERIC_RX_BUFF_BASE_SZ))

#define IPA_RX_BUFF_CLIENT_HEADROOM 256

#define IPA_WLAN_RX_POOL_SZ 100
#define IPA_WLAN_RX_POOL_SZ_LOW_WM 5
#define IPA_WLAN_RX_BUFF_SZ 2048
@@ -2065,6 +2067,21 @@ static void ipa3_cleanup_rx(struct ipa3_sys_context *sys)
	}
}

static struct sk_buff *ipa3_skb_copy_for_client(struct sk_buff *skb, int len)
{
	struct sk_buff *skb2 = NULL;

	skb2 = __dev_alloc_skb(len + IPA_RX_BUFF_CLIENT_HEADROOM, GFP_KERNEL);
	if (likely(skb2)) {
		/* Set the data pointer */
		skb_reserve(skb2, IPA_RX_BUFF_CLIENT_HEADROOM);
		memcpy(skb2->data, skb->data, len);
		skb2->len = len;
		skb_set_tail_pointer(skb2, len);
	}

	return skb2;
}

static int ipa3_lan_rx_pyld_hdlr(struct sk_buff *skb,
		struct ipa3_sys_context *sys)
@@ -2259,7 +2276,8 @@ begin:
				continue;
			}

			skb2 = skb_clone(skb, GFP_KERNEL);
			skb2 = ipa3_skb_copy_for_client(skb,
				status->pkt_len + IPA_PKT_STATUS_SIZE);
			if (likely(skb2)) {
				if (skb->len < len + IPA_PKT_STATUS_SIZE) {
					IPADBG("SPL skb len %d len %d\n",
@@ -2291,7 +2309,7 @@ begin:
						IPA_PKT_STATUS_SIZE);
				}
			} else {
				IPAERR("fail to clone\n");
				IPAERR("fail to alloc skb\n");
				if (skb->len < len) {
					sys->prev_skb = NULL;
					sys->len_rem = len - skb->len +