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

Commit 6634ac01 authored by Katish Paran's avatar Katish Paran Committed by Gerrit - the friendly Code Review server
Browse files

memshare: Release the memory only if no allocation is done



Currently, memshare relies on the system monitor only for
releasing memory for the allocated clients. It may happen that
XPU is still intact on the modem side while driver tries to
release the memory. This patch ensures that memory release only
happens if XPU is released.

Change-Id: I45716c0abe6bc08559854782ff73a332e148a7cb
Signed-off-by: default avatarKatish Paran <kparan@codeaurora.org>
parent fc52a10d
Loading
Loading
Loading
Loading
+42 −26
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ static struct qmi_handle *mem_share_svc_handle;
static void mem_share_svc_recv_msg(struct work_struct *work);
static DECLARE_DELAYED_WORK(work_recv_msg, mem_share_svc_recv_msg);
static struct workqueue_struct *mem_share_svc_workqueue;
static uint64_t bootup_request;

/* Memshare Driver Structure */
struct memshare_driver {
@@ -156,25 +157,6 @@ void free_client(int id)

}

void free_mem_clients(int proc)
{
	int i;

	pr_debug("memshare: freeing clients\n");

	for (i = 0; i < MAX_CLIENTS; i++) {
		if (memblock[i].peripheral == proc &&
				!memblock[i].guarantee && memblock[i].alloted) {
			pr_debug("Freeing memory for client id: %d\n",
					memblock[i].client_id);
			dma_free_attrs(memsh_drv->dev, memblock[i].size,
				memblock[i].virtual_addr, memblock[i].phy_addr,
				&attrs);
			free_client(i);
		}
	}
}

void fill_alloc_response(struct mem_alloc_generic_resp_msg_v01 *resp,
						int id, int *flag)
{
@@ -208,6 +190,7 @@ void initialize_client(void)
		memblock[i].peripheral = -1;
		memblock[i].sequence_id = -1;
		memblock[i].memory_type = MEMORY_CMA;
		memblock[i].free_memory = 0;
	}
	dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
}
@@ -215,13 +198,42 @@ void initialize_client(void)
static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
					void *_cmd)
{
	pr_debug("memshare: Modem notification\n");
	int i;

	switch (code) {

	case SUBSYS_BEFORE_SHUTDOWN:
		bootup_request++;
		break;

	case SUBSYS_AFTER_POWERUP:
		pr_err("memshare: Modem Restart has happened\n");
		free_mem_clients(DHMS_MEM_PROC_MPSS_V01);
		pr_debug("memshare: Modem has booted up\n");
		for (i = 0; i < MAX_CLIENTS; i++) {
			if (memblock[i].free_memory > 0 &&
					bootup_request >= 2) {
				memblock[i].free_memory -= 1;
				pr_debug("memshare: free_memory count: %d for clinet id: %d\n",
					memblock[i].free_memory,
					memblock[i].client_id);
			}

			if (memblock[i].free_memory == 0) {
				if (memblock[i].peripheral ==
					DHMS_MEM_PROC_MPSS_V01 &&
					!memblock[i].guarantee &&
					memblock[i].alloted) {
					pr_err("memshare: Freeing memory for client id: %d\n",
						memblock[i].client_id);
					dma_free_attrs(memsh_drv->dev,
						memblock[i].size,
						memblock[i].virtual_addr,
						memblock[i].phy_addr,
						&attrs);
					free_client(i);
				}
			}
		}
		bootup_request++;
		break;

	default:
@@ -287,7 +299,7 @@ static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h)
	int client_id;

	alloc_req = (struct mem_alloc_generic_req_msg_v01 *)req;
	pr_debug("alloc request client id: %d proc _id: %d\n",
	pr_debug("memshare: alloc request client id: %d proc _id: %d\n",
			alloc_req->client_id, alloc_req->proc_id);
	mutex_lock(&memsh_drv->mem_share);
	alloc_resp = kzalloc(sizeof(struct mem_alloc_generic_resp_msg_v01),
@@ -308,6 +320,10 @@ static int handle_alloc_generic_req(void *req_h, void *req, void *conn_h)
		return -EINVAL;
	}

	memblock[client_id].free_memory += 1;
	pr_debug("memshare: In %s, free memory count for client id: %d = %d",
		__func__, memblock[client_id].client_id,
			memblock[client_id].free_memory);
	if (!memblock[client_id].alloted) {
		rc = memshare_alloc(memsh_drv->dev, alloc_req->num_bytes,
					&memblock[client_id]);
@@ -384,7 +400,7 @@ static int handle_free_generic_req(void *req_h, void *req, void *conn_h)
	uint32_t client_id;

	free_req = (struct mem_free_generic_req_msg_v01 *)req;
	pr_debug("%s: Received Free Request\n", __func__);
	pr_debug("memshare: %s: Received Free Request\n", __func__);
	mutex_lock(&memsh_drv->mem_free);
	memset(&free_resp, 0, sizeof(struct mem_free_generic_resp_msg_v01));
	free_resp.resp.error = QMI_ERR_INTERNAL_V01;
@@ -448,7 +464,7 @@ static int handle_query_size_req(void *req_h, void *req, void *conn_h)
		mutex_unlock(&memsh_drv->mem_share);
		return -ENOMEM;
	}
	pr_debug("query request client id: %d proc _id: %d\n",
	pr_debug("memshare: query request client id: %d proc _id: %d\n",
		query_req->client_id, query_req->proc_id);
	client_id = check_client(query_req->client_id, query_req->proc_id,
								CHECK);
@@ -471,7 +487,7 @@ static int handle_query_size_req(void *req_h, void *req, void *conn_h)
	query_resp->resp.error = QMI_ERR_NONE_V01;
	mutex_unlock(&memsh_drv->mem_share);

	pr_debug("query_resp.size :%d, alloc_resp.mem_req_result :%lx\n",
	pr_debug("memshare: query_resp.size :%d, alloc_resp.mem_req_result :%lx\n",
			  query_resp->size,
			  (unsigned long int)query_resp->resp.result);
	rc = qmi_send_resp_from_cb(mem_share_svc_handle, conn_h, req_h,
+6 −4
Original line number Diff line number Diff line
@@ -40,13 +40,15 @@ struct mem_blocks {
	uint32_t alloted;
	/* Size required for client */
	uint32_t size;
	/* start address of the memory block reserved by server memory
	/*
	 * start address of the memory block reserved by server memory
	 * subsystem to client
	 */
	phys_addr_t phy_addr;
	/* Virtual address for the physical address allocated
	*/
	/* Virtual address for the physical address allocated */
	void *virtual_addr;
	/* Release memory only when XPU is released*/
	uint8_t free_memory;
};

int memshare_alloc(struct device *dev,