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

Commit 705f8b50 authored by Mohammed Javid's avatar Mohammed Javid
Browse files

msm: ipa2: Added retry logic if memory allocate fails



Observing the memory allocation fails if no free emergency
pool of memory not available. Added retry logic mechanism
to allocate memory max 10 retry count with the sleep of 100ms

Change-Id: I2bd38355065dfb1a316fad98b8e07e32e1ee007c
Acked-by: default avatarAbhishek Choubey <abchoube@qti.qualcomm.com>
Signed-off-by: default avatarMohammed Javid <mjavid@codeaurora.org>
parent a9239f2d
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2018, 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
@@ -435,14 +435,14 @@ int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,
				&dma_addr);
		if (!transfer.iovec) {
			IPAERR("fail to alloc dma mem for sps xfr buff\n");
			return -EFAULT;
			return -ENOMEM;
		}
	} else {
		transfer.iovec = kmalloc(size, flag);
		if (!transfer.iovec) {
			IPAERR("fail to alloc mem for sps xfr buff ");
			IPAERR("num_desc = %d size = %d\n", num_desc, size);
			return -EFAULT;
			return -ENOMEM;
		}
		dma_addr = dma_map_single(ipa_ctx->pdev,
				transfer.iovec, size, DMA_TO_DEVICE);
@@ -459,9 +459,10 @@ int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,

	for (i = 0; i < num_desc; i++) {
		tx_pkt = kmem_cache_zalloc(ipa_ctx->tx_pkt_wrapper_cache,
					   mem_flag);
					   GFP_ATOMIC);
		if (!tx_pkt) {
			IPAERR("failed to alloc tx wrapper\n");
			ret = -ENOMEM;
			goto failure;
		}
		/*
@@ -515,6 +516,7 @@ int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,

		if (dma_mapping_error(ipa_ctx->pdev, tx_pkt->mem.phys_base)) {
			IPAERR("dma_map_single failed\n");
			ret = -EFAULT;
			goto failure_dma_map;
		}

@@ -564,6 +566,7 @@ int ipa_send(struct ipa_sys_context *sys, u32 num_desc, struct ipa_desc *desc,
	result = sps_transfer(sys->ep->ep_hdl, &transfer);
	if (result) {
		IPAERR("sps_transfer failed rc=%d\n", result);
		ret = -EFAULT;
		goto failure;
	}

@@ -605,7 +608,7 @@ failure:
		}
	}
	spin_unlock_bh(&sys->spinlock);
	return -EFAULT;
	return ret;
}

/**
+19 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2018, 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
@@ -49,6 +49,10 @@
#define UPPER_CUTOFF 50
#define LOWER_CUTOFF 10

#define MAX_RETRY_ALLOC 10
#define ALLOC_MIN_SLEEP_RX 100000
#define ALLOC_MAX_SLEEP_RX 200000

#define IPA_DEFAULT_SYS_YELLOW_WM 32

#define IPA_AGGR_BYTE_LIMIT (\
@@ -4626,6 +4630,7 @@ int ipa_tag_process(struct ipa_desc desc[],
	int res;
	struct ipa_tag_completion *comp;
	int ep_idx;
	u32 retry_cnt = 0;
	gfp_t flag = GFP_KERNEL | (ipa_ctx->use_dma_zone ? GFP_DMA : 0);

	/* Not enough room for the required descriptors for the tag process */
@@ -4742,9 +4747,22 @@ int ipa_tag_process(struct ipa_desc desc[],
	tag_desc[desc_idx].user1 = dummy_skb;
	desc_idx++;

retry_alloc:

	/* send all descriptors to IPA with single EOT */
	res = ipa_send(sys, desc_idx, tag_desc, true);
	if (res) {
		if (res == -ENOMEM) {
			if (retry_cnt < MAX_RETRY_ALLOC) {
				IPADBG(
				"Failed to alloc memory retry count %d\n",
				retry_cnt);
				retry_cnt++;
				usleep_range(ALLOC_MIN_SLEEP_RX,
					ALLOC_MAX_SLEEP_RX);
				goto retry_alloc;
			}
		}
		IPAERR("failed to send TAG packets %d\n", res);
		res = -ENOMEM;
		goto fail_send;