wifi: iwlwifi: dbg-tlv: avoid extra allocation/copy
authorJohannes Berg <johannes.berg@intel.com>
Sun, 28 Jan 2024 06:53:51 +0000 (08:53 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 2 Feb 2024 12:47:46 +0000 (13:47 +0100)
In iwl_dbg_tlv_alloc_trigger() the code makes a copy just
to modify it and pass it to another function to make a copy
again. Change the API to return the copy so the adjustment
can be done without another copy.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Reviewed-by: Gregory Greenman <gregory.greenman@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240128084842.075c8b9f7030.Id5a61e1a87a9c6932727fb4e2c9b54ed6070362a@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c

index 72075720969c06b2378d84d48305e84df467f201..7b145b41781042d8dbd6922156efcecb9589af98 100644 (file)
@@ -64,21 +64,22 @@ dbg_ver_table[IWL_DBG_TLV_TYPE_NUM] = {
        [IWL_DBG_TLV_TYPE_CONF_SET]     = {.min_ver = 1, .max_ver = 1,},
 };
 
-static int iwl_dbg_tlv_add(const struct iwl_ucode_tlv *tlv,
-                          struct list_head *list)
+/* add a new TLV node, returning it so it can be modified */
+static struct iwl_ucode_tlv *iwl_dbg_tlv_add(const struct iwl_ucode_tlv *tlv,
+                                            struct list_head *list)
 {
        u32 len = le32_to_cpu(tlv->length);
        struct iwl_dbg_tlv_node *node;
 
        node = kzalloc(sizeof(*node) + len, GFP_KERNEL);
        if (!node)
-               return -ENOMEM;
+               return NULL;
 
        memcpy(&node->tlv, tlv, sizeof(node->tlv));
        memcpy(node->tlv.data, tlv->data, len);
        list_add_tail(&node->list, list);
 
-       return 0;
+       return &node->tlv;
 }
 
 static bool iwl_dbg_tlv_ver_support(const struct iwl_ucode_tlv *tlv)
@@ -106,7 +107,9 @@ static int iwl_dbg_tlv_alloc_debug_info(struct iwl_trans *trans,
        IWL_DEBUG_FW(trans, "WRT: Loading debug cfg: %s\n",
                     debug_info->debug_cfg_name);
 
-       return iwl_dbg_tlv_add(tlv, &trans->dbg.debug_info_tlv_list);
+       if (!iwl_dbg_tlv_add(tlv, &trans->dbg.debug_info_tlv_list))
+               return -ENOMEM;
+       return 0;
 }
 
 static int iwl_dbg_tlv_alloc_buf_alloc(struct iwl_trans *trans,
@@ -175,7 +178,9 @@ static int iwl_dbg_tlv_alloc_hcmd(struct iwl_trans *trans,
                return -EINVAL;
        }
 
-       return iwl_dbg_tlv_add(tlv, &trans->dbg.time_point[tp].hcmd_list);
+       if (!iwl_dbg_tlv_add(tlv, &trans->dbg.time_point[tp].hcmd_list))
+               return -ENOMEM;
+       return 0;
 }
 
 static int iwl_dbg_tlv_alloc_region(struct iwl_trans *trans,
@@ -246,11 +251,9 @@ static int iwl_dbg_tlv_alloc_trigger(struct iwl_trans *trans,
                                     const struct iwl_ucode_tlv *tlv)
 {
        const struct iwl_fw_ini_trigger_tlv *trig = (const void *)tlv->data;
-       struct iwl_fw_ini_trigger_tlv *dup_trig;
        u32 tp = le32_to_cpu(trig->time_point);
        u32 rf = le32_to_cpu(trig->reset_fw);
-       struct iwl_ucode_tlv *dup = NULL;
-       int ret;
+       struct iwl_ucode_tlv *new_tlv;
 
        if (le32_to_cpu(tlv->length) < sizeof(*trig))
                return -EINVAL;
@@ -267,20 +270,18 @@ static int iwl_dbg_tlv_alloc_trigger(struct iwl_trans *trans,
                     "WRT: time point %u for trigger TLV with reset_fw %u\n",
                     tp, rf);
        trans->dbg.last_tp_resetfw = 0xFF;
+
+       new_tlv = iwl_dbg_tlv_add(tlv, &trans->dbg.time_point[tp].trig_list);
+       if (!new_tlv)
+               return -ENOMEM;
+
        if (!le32_to_cpu(trig->occurrences)) {
-               dup = kmemdup(tlv, sizeof(*tlv) + le32_to_cpu(tlv->length),
-                               GFP_KERNEL);
-               if (!dup)
-                       return -ENOMEM;
-               dup_trig = (void *)dup->data;
-               dup_trig->occurrences = cpu_to_le32(-1);
-               tlv = dup;
-       }
+               struct iwl_fw_ini_trigger_tlv *new_trig = (void *)new_tlv->data;
 
-       ret = iwl_dbg_tlv_add(tlv, &trans->dbg.time_point[tp].trig_list);
-       kfree(dup);
+               new_trig->occurrences = cpu_to_le32(-1);
+       }
 
-       return ret;
+       return 0;
 }
 
 static int iwl_dbg_tlv_config_set(struct iwl_trans *trans,
@@ -304,7 +305,9 @@ static int iwl_dbg_tlv_config_set(struct iwl_trans *trans,
                return -EINVAL;
        }
 
-       return iwl_dbg_tlv_add(tlv, &trans->dbg.time_point[tp].config_list);
+       if (!iwl_dbg_tlv_add(tlv, &trans->dbg.time_point[tp].config_list))
+               return -ENOMEM;
+       return 0;
 }
 
 static int (*dbg_tlv_alloc[])(struct iwl_trans *trans,
@@ -1148,7 +1151,9 @@ iwl_dbg_tlv_add_active_trigger(struct iwl_fw_runtime *fwrt,
        if (!match) {
                IWL_DEBUG_FW(fwrt, "WRT: Enabling trigger (time point %u)\n",
                             le32_to_cpu(trig->time_point));
-               return iwl_dbg_tlv_add(trig_tlv, trig_list);
+               if (!iwl_dbg_tlv_add(trig_tlv, trig_list))
+                       return -ENOMEM;
+               return 0;
        }
 
        return iwl_dbg_tlv_override_trig_node(fwrt, trig_tlv, match);