aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
diff options
context:
space:
mode:
authorShahar S Matityahu <shahar.s.matityahu@intel.com>2018-11-20 13:29:29 +0200
committerLuca Coelho <luciano.coelho@intel.com>2019-02-04 12:28:06 +0200
commit0ec7bfb26aff91ae60ac8a893fee755287291a55 (patch)
tree415688ffbd335a84f0fe5fd58151081ec92558a0 /drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
parentiwlwifi: dvm: use %u for sscanf() into unsigned variable (diff)
downloadlinux-dev-0ec7bfb26aff91ae60ac8a893fee755287291a55.tar.xz
linux-dev-0ec7bfb26aff91ae60ac8a893fee755287291a55.zip
iwlwifi: dbg_ini: remove redundant dram buffer allocation
There are several flows in that can cause redundant allocation. In case the driver reaches the maximum amount of blocks allowed, it allocates the buffer and only then checks if it reached the maximum amount of blocks and return without freeing the buffer, causing a memory leak. Solve this by moving the check of the amount of buffers being used before the allocation. In case there was an assert, the apply points are being reused, causing that for each assert, the driver allocates a new redundant buffer. Solve this by adding a new is_alloc field to indicate if the driver already allocated memory for the requested buffer. Also, split iwl_fw_dbg_buffer_allocation function into iwl_fw_dbg_buffer_allocation and iwl_fw_dbg_buffer_apply to increase the clearity of the flow. Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com> Fixes: d47902f9f71d ("iwlwifi: dbg: add apply point logic") Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index 43d815cb3ce9..5798f434f68f 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -71,6 +71,7 @@ void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
u32 apply_point = le32_to_cpu(header->apply_point);
int copy_size = le32_to_cpu(tlv->length) + sizeof(*tlv);
+ int offset_size = copy_size;
if (WARN_ONCE(apply_point >= IWL_FW_INI_APPLY_NUM,
"Invalid apply point id %d\n", apply_point))
@@ -81,17 +82,25 @@ void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
else
data = &trans->apply_points[apply_point];
+ /* add room for is_alloc field in &iwl_fw_ini_allocation_data struct */
+ if (le32_to_cpu(tlv->type) == IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION) {
+ struct iwl_fw_ini_allocation_data *buf_alloc =
+ (void *)tlv->data;
+
+ offset_size += sizeof(buf_alloc->is_alloc);
+ }
+
/*
* Make sure we still have room to copy this TLV. Offset points to the
* location the last copy ended.
*/
- if (WARN_ONCE(data->offset + copy_size > data->size,
+ if (WARN_ONCE(data->offset + offset_size > data->size,
"Not enough memory for apply point %d\n",
apply_point))
return;
memcpy(data->data + data->offset, (void *)tlv, copy_size);
- data->offset += copy_size;
+ data->offset += offset_size;
}
void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
@@ -129,6 +138,16 @@ void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
if (WARN_ON(apply >= IWL_FW_INI_APPLY_NUM))
continue;
+ /* add room for is_alloc field in &iwl_fw_ini_allocation_data
+ * struct
+ */
+ if (tlv_type == IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION) {
+ struct iwl_fw_ini_allocation_data *buf_alloc =
+ (void *)tlv->data;
+
+ size[apply] += sizeof(buf_alloc->is_alloc);
+ }
+
size[apply] += sizeof(*tlv) + tlv_len;
}