Commit 626c077c authored by Sebastian Sanchez's avatar Sebastian Sanchez Committed by Doug Ledford

IB/hfi1: Prevent link down request double queuing

When link interrupts occur, multiple link down requests
could be queued up when only one is needed. This could get
the hfi1 out of sync with its link partner during LNI.

Only allow one link down request to be queued at any one time.
Reviewed-by: default avatarDean Luick <dean.luick@intel.com>
Signed-off-by: default avatarSebastian Sanchez <sebastian.sanchez@intel.com>
Signed-off-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 71d47008
...@@ -7045,6 +7045,7 @@ void handle_link_down(struct work_struct *work) ...@@ -7045,6 +7045,7 @@ void handle_link_down(struct work_struct *work)
/* Go offline first, then deal with reading/writing through 8051 */ /* Go offline first, then deal with reading/writing through 8051 */
was_up = !!(ppd->host_link_state & HLS_UP); was_up = !!(ppd->host_link_state & HLS_UP);
set_link_state(ppd, HLS_DN_OFFLINE); set_link_state(ppd, HLS_DN_OFFLINE);
xchg(&ppd->is_link_down_queued, 0);
if (was_up) { if (was_up) {
lcl_reason = 0; lcl_reason = 0;
...@@ -7805,10 +7806,11 @@ static void handle_8051_interrupt(struct hfi1_devdata *dd, u32 unused, u64 reg) ...@@ -7805,10 +7806,11 @@ static void handle_8051_interrupt(struct hfi1_devdata *dd, u32 unused, u64 reg)
*/ */
if ((ppd->host_link_state & if ((ppd->host_link_state &
(HLS_GOING_OFFLINE | HLS_LINK_COOLDOWN)) || (HLS_GOING_OFFLINE | HLS_LINK_COOLDOWN)) ||
ppd->link_enabled == 0) { ppd->link_enabled == 0 || ppd->is_link_down_queued) {
dd_dev_info(dd, "%s: not queuing link down\n", dd_dev_info(dd, "%s: not queuing link down\n",
__func__); __func__);
} else { } else {
xchg(&ppd->is_link_down_queued, 1);
queue_work(ppd->link_wq, &ppd->link_down_work); queue_work(ppd->link_wq, &ppd->link_down_work);
} }
} }
......
...@@ -644,6 +644,7 @@ struct hfi1_pportdata { ...@@ -644,6 +644,7 @@ struct hfi1_pportdata {
/* placeholders for IB MAD packet settings */ /* placeholders for IB MAD packet settings */
u8 overrun_threshold; u8 overrun_threshold;
u8 phy_error_threshold; u8 phy_error_threshold;
unsigned int is_link_down_queued;
/* Used to override LED behavior for things like maintenance beaconing*/ /* Used to override LED behavior for things like maintenance beaconing*/
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment