qcacmn: Fix memory leak during REO cmd ring drain

Fix possible REO descriptor leak while draining REO
command ring by invoking command status handlers with
special error code.

Change-Id: I2fe5f60489b57a4b0a287e67e5610112f7292677
This commit is contained in:
Karunakar Dasineni
2018-02-27 23:05:08 -08:00
committed by nshrivas
parent 8bb56ebedc
commit 31b98d4cd7
3 changed files with 25 additions and 8 deletions

View File

@@ -1019,7 +1019,10 @@ static void dp_rx_tid_update_cb(struct dp_soc *soc, void *cb_ctxt,
{
struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt;
if (reo_status->queue_status.header.status) {
if ((reo_status->rx_queue_status.header.status !=
HAL_REO_CMD_SUCCESS) &&
(reo_status->rx_queue_status.header.status !=
HAL_REO_CMD_DRAIN)) {
/* Should not happen normally. Just print error for now */
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"%s: Rx tid HW desc update failed(%d): tid %d\n",
@@ -1114,7 +1117,10 @@ static void dp_reo_desc_free(struct dp_soc *soc, void *cb_ctxt,
(struct reo_desc_list_node *)cb_ctxt;
struct dp_rx_tid *rx_tid = &freedesc->rx_tid;
if (reo_status->rx_queue_status.header.status) {
if ((reo_status->fl_cache_status.header.status !=
HAL_REO_CMD_SUCCESS) &&
(reo_status->fl_cache_status.header.status !=
HAL_REO_CMD_DRAIN)) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"%s: Rx tid HW desc flush failed(%d): tid %d\n",
__func__,
@@ -1317,8 +1323,13 @@ static void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt,
uint32_t desc_size, tot_desc_size;
struct hal_reo_cmd_params params;
if (reo_status->rx_queue_status.header.status) {
if (reo_status->rx_queue_status.header.status == HAL_REO_CMD_DRAIN) {
qdf_mem_zero(reo_status, sizeof(*reo_status));
reo_status->fl_cache_status.header.status = HAL_REO_CMD_DRAIN;
dp_reo_desc_free(soc, (void *)freedesc, reo_status);
return;
} else if (reo_status->rx_queue_status.header.status !=
HAL_REO_CMD_SUCCESS) {
/* Should not happen normally. Just print error for now */
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"%s: Rx tid HW desc deletion failed(%d): tid %d\n",

View File

@@ -178,12 +178,17 @@ void dp_reo_cmdlist_destroy(struct dp_soc *soc)
{
struct dp_reo_cmd_info *reo_cmd = NULL;
struct dp_reo_cmd_info *tmp_cmd = NULL;
union hal_reo_status reo_status;
reo_status.queue_status.header.status =
HAL_REO_CMD_DRAIN;
qdf_spin_lock_bh(&soc->rx.reo_cmd_lock);
TAILQ_FOREACH_SAFE(reo_cmd, &soc->rx.reo_cmd_list,
reo_cmd_list_elem, tmp_cmd) {
reo_cmd_list_elem, tmp_cmd) {
TAILQ_REMOVE(&soc->rx.reo_cmd_list, reo_cmd,
reo_cmd_list_elem);
reo_cmd_list_elem);
reo_cmd->handler(soc, reo_cmd->data, &reo_status);
qdf_mem_free(reo_cmd);
}
qdf_spin_unlock_bh(&soc->rx.reo_cmd_lock);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -137,7 +137,8 @@ enum reo_cmd_exec_status {
HAL_REO_CMD_SUCCESS = 0,
HAL_REO_CMD_BLOCKED = 1,
HAL_REO_CMD_FAILED = 2,
HAL_REO_CMD_RESOURCE_BLOCKED = 3
HAL_REO_CMD_RESOURCE_BLOCKED = 3,
HAL_REO_CMD_DRAIN = 0xff
};
/**