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

orang tua
8bb56ebedc
melakukan
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;
|
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 */
|
/* Should not happen normally. Just print error for now */
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
"%s: Rx tid HW desc update failed(%d): tid %d\n",
|
"%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 reo_desc_list_node *)cb_ctxt;
|
||||||
struct dp_rx_tid *rx_tid = &freedesc->rx_tid;
|
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,
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
"%s: Rx tid HW desc flush failed(%d): tid %d\n",
|
"%s: Rx tid HW desc flush failed(%d): tid %d\n",
|
||||||
__func__,
|
__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;
|
uint32_t desc_size, tot_desc_size;
|
||||||
struct hal_reo_cmd_params params;
|
struct hal_reo_cmd_params params;
|
||||||
|
|
||||||
|
if (reo_status->rx_queue_status.header.status == HAL_REO_CMD_DRAIN) {
|
||||||
if (reo_status->rx_queue_status.header.status) {
|
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 */
|
/* Should not happen normally. Just print error for now */
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
"%s: Rx tid HW desc deletion failed(%d): tid %d\n",
|
"%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 *reo_cmd = NULL;
|
||||||
struct dp_reo_cmd_info *tmp_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);
|
qdf_spin_lock_bh(&soc->rx.reo_cmd_lock);
|
||||||
TAILQ_FOREACH_SAFE(reo_cmd, &soc->rx.reo_cmd_list,
|
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,
|
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_mem_free(reo_cmd);
|
||||||
}
|
}
|
||||||
qdf_spin_unlock_bh(&soc->rx.reo_cmd_lock);
|
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
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
* any purpose with or without fee is hereby granted, provided that the
|
* 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_SUCCESS = 0,
|
||||||
HAL_REO_CMD_BLOCKED = 1,
|
HAL_REO_CMD_BLOCKED = 1,
|
||||||
HAL_REO_CMD_FAILED = 2,
|
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