i40e: Minimize amount of busy-waiting during AQ send
The i40e_asq_send_command will now use a non blocking usleep_range if possible (non-atomic context), instead of busy-waiting udelay. The usleep_range function uses hrtimers to provide better performance and removes the negative impact of busy-waiting in time-critical environments. 1. Rename i40e_asq_send_command to i40e_asq_send_command_atomic and add 5th parameter to inform if called from an atomic context. Call inside usleep_range (if non-atomic) or udelay (if atomic). 2. Change i40e_asq_send_command to invoke i40e_asq_send_command_atomic(..., false). 3. Change two functions: - i40e_aq_set_vsi_uc_promisc_on_vlan - i40e_aq_set_vsi_mc_promisc_on_vlan to explicitly use i40e_asq_send_command_atomic(..., true) instead of i40e_asq_send_command, as they use spinlocks and do some work in an atomic context. All other calls to i40e_asq_send_command remain unchanged. Signed-off-by: Dawid Lukwinski <dawid.lukwinski@intel.com> Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com> Tested-by: Tony Brelinski <tony.brelinski@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
parent
cfb1d572c9
commit
ef39584ddb
|
@ -769,21 +769,22 @@ static bool i40e_asq_done(struct i40e_hw *hw)
|
|||
}
|
||||
|
||||
/**
|
||||
* i40e_asq_send_command - send command to Admin Queue
|
||||
* i40e_asq_send_command_atomic - send command to Admin Queue
|
||||
* @hw: pointer to the hw struct
|
||||
* @desc: prefilled descriptor describing the command (non DMA mem)
|
||||
* @buff: buffer to use for indirect commands
|
||||
* @buff_size: size of buffer for indirect commands
|
||||
* @cmd_details: pointer to command details structure
|
||||
* @is_atomic_context: is the function called in an atomic context?
|
||||
*
|
||||
* This is the main send command driver routine for the Admin Queue send
|
||||
* queue. It runs the queue, cleans the queue, etc
|
||||
**/
|
||||
i40e_status i40e_asq_send_command(struct i40e_hw *hw,
|
||||
struct i40e_aq_desc *desc,
|
||||
void *buff, /* can be NULL */
|
||||
u16 buff_size,
|
||||
struct i40e_asq_cmd_details *cmd_details)
|
||||
i40e_status
|
||||
i40e_asq_send_command_atomic(struct i40e_hw *hw, struct i40e_aq_desc *desc,
|
||||
void *buff, /* can be NULL */ u16 buff_size,
|
||||
struct i40e_asq_cmd_details *cmd_details,
|
||||
bool is_atomic_context)
|
||||
{
|
||||
i40e_status status = 0;
|
||||
struct i40e_dma_mem *dma_buff = NULL;
|
||||
|
@ -910,7 +911,12 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
|
|||
*/
|
||||
if (i40e_asq_done(hw))
|
||||
break;
|
||||
udelay(50);
|
||||
|
||||
if (is_atomic_context)
|
||||
udelay(50);
|
||||
else
|
||||
usleep_range(40, 60);
|
||||
|
||||
total_delay += 50;
|
||||
} while (total_delay < hw->aq.asq_cmd_timeout);
|
||||
}
|
||||
|
@ -967,6 +973,15 @@ asq_send_command_error:
|
|||
return status;
|
||||
}
|
||||
|
||||
i40e_status
|
||||
i40e_asq_send_command(struct i40e_hw *hw, struct i40e_aq_desc *desc,
|
||||
void *buff, /* can be NULL */ u16 buff_size,
|
||||
struct i40e_asq_cmd_details *cmd_details)
|
||||
{
|
||||
return i40e_asq_send_command_atomic(hw, desc, buff, buff_size,
|
||||
cmd_details, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_fill_default_direct_cmd_desc - AQ descriptor helper function
|
||||
* @desc: pointer to the temp descriptor (non DMA mem)
|
||||
|
|
|
@ -2073,7 +2073,8 @@ enum i40e_status_code i40e_aq_set_vsi_mc_promisc_on_vlan(struct i40e_hw *hw,
|
|||
cmd->seid = cpu_to_le16(seid);
|
||||
cmd->vlan_tag = cpu_to_le16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
|
||||
|
||||
status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
|
||||
status = i40e_asq_send_command_atomic(hw, &desc, NULL, 0,
|
||||
cmd_details, true);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -2114,7 +2115,8 @@ enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
|
|||
cmd->seid = cpu_to_le16(seid);
|
||||
cmd->vlan_tag = cpu_to_le16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
|
||||
|
||||
status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
|
||||
status = i40e_asq_send_command_atomic(hw, &desc, NULL, 0,
|
||||
cmd_details, true);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -22,11 +22,15 @@ void i40e_adminq_init_ring_data(struct i40e_hw *hw);
|
|||
i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
|
||||
struct i40e_arq_event_info *e,
|
||||
u16 *events_pending);
|
||||
i40e_status i40e_asq_send_command(struct i40e_hw *hw,
|
||||
struct i40e_aq_desc *desc,
|
||||
void *buff, /* can be NULL */
|
||||
u16 buff_size,
|
||||
struct i40e_asq_cmd_details *cmd_details);
|
||||
i40e_status
|
||||
i40e_asq_send_command(struct i40e_hw *hw, struct i40e_aq_desc *desc,
|
||||
void *buff, /* can be NULL */ u16 buff_size,
|
||||
struct i40e_asq_cmd_details *cmd_details);
|
||||
i40e_status
|
||||
i40e_asq_send_command_atomic(struct i40e_hw *hw, struct i40e_aq_desc *desc,
|
||||
void *buff, /* can be NULL */ u16 buff_size,
|
||||
struct i40e_asq_cmd_details *cmd_details,
|
||||
bool is_atomic_context);
|
||||
|
||||
/* debug function for adminq */
|
||||
void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask,
|
||||
|
|
Loading…
Reference in New Issue