Overloading the 'msg_size' field in the 'arq_event_info' struct
is a bad idea. It leads to bugs when the structure is used in a
loop, since the input value (buffer size) is overwritten by the
output value (actual message length). The fix introduces one
more field of 'buf_len' for the buffer size, and renames the
field of 'msg_size' to 'msg_len' for the real message size.

Signed-off-by: Helin Zhang <helin.zhang at intel.com>
Reviewed-by: Chen Jing <jing.d.chen at intel.com>
---
 lib/librte_pmd_i40e/i40e/i40e_adminq.c    | 33 ++++++++++++++++---------------
 lib/librte_pmd_i40e/i40e/i40e_adminq.h    |  3 ++-
 lib/librte_pmd_i40e/i40e/i40e_common.c    |  8 ++++++--
 lib/librte_pmd_i40e/i40e/i40e_prototype.h |  6 ++----
 4 files changed, 27 insertions(+), 23 deletions(-)

diff --git a/lib/librte_pmd_i40e/i40e/i40e_adminq.c 
b/lib/librte_pmd_i40e/i40e/i40e_adminq.c
index 80da710..e098ed6 100644
--- a/lib/librte_pmd_i40e/i40e/i40e_adminq.c
+++ b/lib/librte_pmd_i40e/i40e/i40e_adminq.c
@@ -867,7 +867,8 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw 
*hw,

        /* bump the tail */
        i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: desc and buffer:\n");
-       i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring, buff);
+       i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring,
+                     buff, buff_size);
        (hw->aq.asq.next_to_use)++;
        if (hw->aq.asq.next_to_use == hw->aq.asq.count)
                hw->aq.asq.next_to_use = 0;
@@ -917,11 +918,9 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw 
*hw,
                hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval;
        }

-       if (LE16_TO_CPU(desc->datalen) == buff_size) {
-               i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
-                          "AQTX: desc and buffer writeback:\n");
-               i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff);
-       }
+       i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
+                  "AQTX: desc and buffer writeback:\n");
+       i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff, buff_size);

        /* update the error if time out occurred */
        if ((!cmd_completed) &&
@@ -1000,6 +999,7 @@ enum i40e_status_code i40e_clean_arq_element(struct 
i40e_hw *hw,
        /* now clean the next descriptor */
        desc = I40E_ADMINQ_DESC(hw->aq.arq, ntc);
        desc_idx = ntc;
+
        flags = LE16_TO_CPU(desc->flags);
        if (flags & I40E_AQ_FLAG_ERR) {
                ret_code = I40E_ERR_ADMIN_QUEUE_ERROR;
@@ -1009,19 +1009,20 @@ enum i40e_status_code i40e_clean_arq_element(struct 
i40e_hw *hw,
                           I40E_DEBUG_AQ_MESSAGE,
                           "AQRX: Event received with error 0x%X.\n",
                           hw->aq.arq_last_status);
-       } else {
-               i40e_memcpy(&e->desc, desc, sizeof(struct i40e_aq_desc),
-                           I40E_DMA_TO_NONDMA);
-               datalen = LE16_TO_CPU(desc->datalen);
-               e->msg_size = min(datalen, e->msg_size);
-               if (e->msg_buf != NULL && (e->msg_size != 0))
-                       i40e_memcpy(e->msg_buf,
-                                   hw->aq.arq.r.arq_bi[desc_idx].va,
-                                   e->msg_size, I40E_DMA_TO_NONDMA);
        }

+       i40e_memcpy(&e->desc, desc, sizeof(struct i40e_aq_desc),
+                   I40E_DMA_TO_NONDMA);
+       datalen = LE16_TO_CPU(desc->datalen);
+       e->msg_len = min(datalen, e->buf_len);
+       if (e->msg_buf != NULL && (e->msg_len != 0))
+               i40e_memcpy(e->msg_buf,
+                           hw->aq.arq.r.arq_bi[desc_idx].va,
+                           e->msg_len, I40E_DMA_TO_NONDMA);
+
        i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n");
-       i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf);
+       i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf,
+                     hw->aq.arq_buf_size);

        /* Restore the original datalen and buffer address in the desc,
         * FW updates datalen to indicate the event message
diff --git a/lib/librte_pmd_i40e/i40e/i40e_adminq.h 
b/lib/librte_pmd_i40e/i40e/i40e_adminq.h
index 27f2843..ea611bd 100644
--- a/lib/librte_pmd_i40e/i40e/i40e_adminq.h
+++ b/lib/librte_pmd_i40e/i40e/i40e_adminq.h
@@ -83,7 +83,8 @@ struct i40e_asq_cmd_details {
 /* ARQ event information */
 struct i40e_arq_event_info {
        struct i40e_aq_desc desc;
-       u16 msg_size;
+       u16 msg_len;
+       u16 buf_len;
        u8 *msg_buf;
 };

diff --git a/lib/librte_pmd_i40e/i40e/i40e_common.c 
b/lib/librte_pmd_i40e/i40e/i40e_common.c
index ffd68a5..ffaa777 100644
--- a/lib/librte_pmd_i40e/i40e/i40e_common.c
+++ b/lib/librte_pmd_i40e/i40e/i40e_common.c
@@ -89,13 +89,15 @@ STATIC enum i40e_status_code i40e_set_mac_type(struct 
i40e_hw *hw)
  * @mask: debug mask
  * @desc: pointer to admin queue descriptor
  * @buffer: pointer to command buffer
+ * @buf_len: max length of buffer
  *
  * Dumps debug log about adminq command with descriptor contents.
  **/
 void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
-                  void *buffer)
+                  void *buffer, u16 buf_len)
 {
        struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
+       u16 len = LE16_TO_CPU(aq_desc->datalen);
        u8 *aq_buffer = (u8 *)buffer;
        u32 data[4];
        u32 i = 0;
@@ -119,7 +121,9 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask 
mask, void *desc,
        if ((buffer != NULL) && (aq_desc->datalen != 0)) {
                i40e_memset(data, 0, sizeof(data), I40E_NONDMA_MEM);
                i40e_debug(hw, mask, "AQ CMD Buffer:\n");
-               for (i = 0; i < LE16_TO_CPU(aq_desc->datalen); i++) {
+               if (buf_len < len)
+                       len = buf_len;
+               for (i = 0; i < len; i++) {
                        data[((i % 16) / 4)] |=
                                ((u32)aq_buffer[i]) << (8 * (i % 4));
                        if ((i % 16) == 15) {
diff --git a/lib/librte_pmd_i40e/i40e/i40e_prototype.h 
b/lib/librte_pmd_i40e/i40e/i40e_prototype.h
index f819f9a..f3215cf 100644
--- a/lib/librte_pmd_i40e/i40e/i40e_prototype.h
+++ b/lib/librte_pmd_i40e/i40e/i40e_prototype.h
@@ -69,10 +69,8 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw 
*hw,
 bool i40e_asq_done(struct i40e_hw *hw);

 /* debug function for adminq */
-void i40e_debug_aq(struct i40e_hw *hw,
-                  enum i40e_debug_mask mask,
-                  void *desc,
-                  void *buffer);
+void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask,
+                  void *desc, void *buffer, u16 buf_len);

 void i40e_idle_aq(struct i40e_hw *hw);
 void i40e_resume_aq(struct i40e_hw *hw);
-- 
1.8.1.4

Reply via email to