mirror of https://gitee.com/openkylin/linux.git
fm10k: correctly handle LPORT_MAP error
Currently, any error responses from the switch manager after an LPORT_MAP request are silently ignored. At most the mailbox message will be reported as an error. This can result in unexpected behavior when the switch manager has configured a port with zero bandwidth. Add support for reading the fm10k_swapi_error structure from LPORT_MAP responses. If the message contains the necessary TLV and has a non-zero error code, report link down, clear the dglort_map, and delay the next get_host_state call by a reasonable delay. Also log an error message indicating that the LPORT_MAP request failed. The delay ensures preventing an interrupt storm on the switch manager, and reduces the number of mailbox messages we send in this scenario drastically. Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Tested-by: Krishneil Singh <Krishneil.k.singh@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
8998763a7b
commit
a7a7783ada
|
@ -330,6 +330,7 @@ struct fm10k_intfc {
|
|||
unsigned long last_reset;
|
||||
unsigned long link_down_event;
|
||||
bool host_ready;
|
||||
bool lport_map_failed;
|
||||
|
||||
u32 reta[FM10K_RETA_SIZE];
|
||||
u32 rssrk[FM10K_RSSRK_SIZE];
|
||||
|
|
|
@ -1263,11 +1263,40 @@ static s32 fm10k_lport_map(struct fm10k_hw *hw, u32 **results,
|
|||
u32 dglort_map = hw->mac.dglort_map;
|
||||
s32 err;
|
||||
|
||||
interface = container_of(hw, struct fm10k_intfc, hw);
|
||||
|
||||
err = fm10k_msg_err_pf(hw, results, mbx);
|
||||
if (!err && hw->swapi.status) {
|
||||
/* force link down for a reasonable delay */
|
||||
interface->link_down_event = jiffies + (2 * HZ);
|
||||
set_bit(__FM10K_LINK_DOWN, &interface->state);
|
||||
|
||||
/* reset dglort_map back to no config */
|
||||
hw->mac.dglort_map = FM10K_DGLORTMAP_NONE;
|
||||
|
||||
fm10k_service_event_schedule(interface);
|
||||
|
||||
/* prevent overloading kernel message buffer */
|
||||
if (interface->lport_map_failed)
|
||||
return 0;
|
||||
|
||||
interface->lport_map_failed = true;
|
||||
|
||||
if (hw->swapi.status == FM10K_MSG_ERR_PEP_NOT_SCHEDULED)
|
||||
dev_warn(&interface->pdev->dev,
|
||||
"cannot obtain link because the host interface is configured for a PCIe host interface bandwidth of zero\n");
|
||||
dev_warn(&interface->pdev->dev,
|
||||
"request logical port map failed: %d\n",
|
||||
hw->swapi.status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = fm10k_msg_lport_map_pf(hw, results, mbx);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
interface = container_of(hw, struct fm10k_intfc, hw);
|
||||
interface->lport_map_failed = false;
|
||||
|
||||
/* we need to reset if port count was just updated */
|
||||
if (dglort_map != hw->mac.dglort_map)
|
||||
|
|
|
@ -1620,6 +1620,8 @@ static s32 fm10k_get_host_state_pf(struct fm10k_hw *hw, bool *switch_ready)
|
|||
|
||||
/* This structure defines the attibutes to be parsed below */
|
||||
const struct fm10k_tlv_attr fm10k_lport_map_msg_attr[] = {
|
||||
FM10K_TLV_ATTR_LE_STRUCT(FM10K_PF_ATTR_ID_ERR,
|
||||
sizeof(struct fm10k_swapi_error)),
|
||||
FM10K_TLV_ATTR_U32(FM10K_PF_ATTR_ID_LPORT_MAP),
|
||||
FM10K_TLV_ATTR_LAST
|
||||
};
|
||||
|
|
|
@ -71,6 +71,8 @@ enum fm10k_pf_tlv_attr_id_v1 {
|
|||
#define FM10K_MSG_UPDATE_PVID_PVID_SHIFT 16
|
||||
#define FM10K_MSG_UPDATE_PVID_PVID_SIZE 16
|
||||
|
||||
#define FM10K_MSG_ERR_PEP_NOT_SCHEDULED 280
|
||||
|
||||
/* The following data structures are overlayed directly onto TLV mailbox
|
||||
* messages, and must not break 4 byte alignment. Ensure the structures line
|
||||
* up correctly as per their TLV definition.
|
||||
|
|
Loading…
Reference in New Issue