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:

committed by
nshrivas

parent
8bb56ebedc
commit
31b98d4cd7
@@ -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",
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user