Skip to content

Commit 0adbc1a

Browse files
ahduyckgregkh
authored andcommitted
fbnic: Actually flush_tx instead of stalling out
[ Upstream commit 0f9a959 ] The fbnic_mbx_flush_tx function had a number of issues. First, we were waiting 200ms for the firmware to process the packets. We can drop this to 20ms and in almost all cases this should be more than enough time. So by changing this we can significantly reduce shutdown time. Second, we were not making sure that the Tx path was actually shut off. As such we could still have packets added while we were flushing the mailbox. To prevent that we can now clear the ready flag for the Tx side and it should stay down since the interrupt is disabled. Third, we kept re-reading the tail due to the second issue. The tail should not move after we have started the flush so we can just read it once while we are holding the mailbox Tx lock. By doing that we are guaranteed that the value should be consistent. Fourth, we were keeping a count of descriptors cleaned due to the second and third issues called out. That count is not a valid reason to be exiting the cleanup, and with the tail only being read once we shouldn't see any cases where the tail moves after the disable so the tracking of count can be dropped. Fifth, we were using attempts * sleep time to determine how long we would wait in our polling loop to flush out the Tx. This can be very imprecise. In order to tighten up the timing we are shifting over to using a jiffies value of jiffies + 10 * HZ + 1 to determine the jiffies value we should stop polling at as this should be accurate within once sleep cycle for the total amount of time spent polling. Fixes: da3cde0 ("eth: fbnic: Add FW communication mechanism") Signed-off-by: Alexander Duyck <[email protected]> Reviewed-by: Simon Horman <[email protected]> Reviewed-by: Jacob Keller <[email protected]> Link: https://patch.msgid.link/174654719929.499179.16406653096197423749.stgit@ahduyck-xeon-server.home.arpa Reviewed-by: Jakub Kicinski <[email protected]> Signed-off-by: Paolo Abeni <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 0939543 commit 0adbc1a

File tree

1 file changed

+16
-15
lines changed

1 file changed

+16
-15
lines changed

drivers/net/ethernet/meta/fbnic/fbnic_fw.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -935,35 +935,36 @@ int fbnic_mbx_poll_tx_ready(struct fbnic_dev *fbd)
935935

936936
void fbnic_mbx_flush_tx(struct fbnic_dev *fbd)
937937
{
938+
unsigned long timeout = jiffies + 10 * HZ + 1;
938939
struct fbnic_fw_mbx *tx_mbx;
939-
int attempts = 50;
940-
u8 count = 0;
941-
942-
/* Nothing to do if there is no mailbox */
943-
if (!fbnic_fw_present(fbd))
944-
return;
940+
u8 tail;
945941

946942
/* Record current Rx stats */
947943
tx_mbx = &fbd->mbx[FBNIC_IPC_MBX_TX_IDX];
948944

949-
/* Nothing to do if mailbox never got to ready */
950-
if (!tx_mbx->ready)
951-
return;
945+
spin_lock_irq(&fbd->fw_tx_lock);
946+
947+
/* Clear ready to prevent any further attempts to transmit */
948+
tx_mbx->ready = false;
949+
950+
/* Read tail to determine the last tail state for the ring */
951+
tail = tx_mbx->tail;
952+
953+
spin_unlock_irq(&fbd->fw_tx_lock);
952954

953955
/* Give firmware time to process packet,
954-
* we will wait up to 10 seconds which is 50 waits of 200ms.
956+
* we will wait up to 10 seconds which is 500 waits of 20ms.
955957
*/
956958
do {
957959
u8 head = tx_mbx->head;
958960

959-
if (head == tx_mbx->tail)
961+
/* Tx ring is empty once head == tail */
962+
if (head == tail)
960963
break;
961964

962-
msleep(200);
965+
msleep(20);
963966
fbnic_mbx_process_tx_msgs(fbd);
964-
965-
count += (tx_mbx->head - head) % FBNIC_IPC_MBX_DESC_LEN;
966-
} while (count < FBNIC_IPC_MBX_DESC_LEN && --attempts);
967+
} while (time_is_after_jiffies(timeout));
967968
}
968969

969970
void fbnic_get_fw_ver_commit_str(struct fbnic_dev *fbd, char *fw_version,

0 commit comments

Comments
 (0)