Add dma_rmb() barriers after both req_id completion checks in ena_com_phc_get_timestamp(). On weakly-ordered architectures, payload fields may be read before req_id is observed as updated. Fixes: e0ea34158ee8 ("net: ena: Add PHC support in the ENA driver") Closes: https://sashiko.dev/#/patchset/20260430032507.11586-1-akiyano%40amazon.com Signed-off-by: Arthur Kiyanovski --- drivers/net/ethernet/amazon/ena/ena_com.c | 43 +++++++++++++++-------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c index 8c86789d867a..79cfcd87d4bf 100644 --- a/drivers/net/ethernet/amazon/ena/ena_com.c +++ b/drivers/net/ethernet/amazon/ena/ena_com.c @@ -1822,23 +1822,31 @@ int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp) "PHC get time request 0x%x failed (device error)\n", phc->req_id); phc->stats.phc_err_dv++; - } else if (resp->error_flags & ENA_PHC_ERROR_FLAGS) { - /* Device updated req_id during blocking time but got - * a PHC error, this occurs if device: - * - exceeded the get time request limit - * - received an invalid timestamp - */ - netdev_err(ena_dev->net_device, - "PHC get time request 0x%x failed (error 0x%x)\n", - phc->req_id, - resp->error_flags); - phc->stats.phc_err_ts += !!(resp->error_flags & - ENA_ADMIN_PHC_ERROR_FLAG_TIMESTAMP); } else { - /* Device updated req_id during blocking time - * with valid timestamp + /* Ensure PHC payload is read after req_id update + * is observed */ - phc->stats.phc_exp++; + dma_rmb(); + + if (resp->error_flags & ENA_PHC_ERROR_FLAGS) { + /* Device updated req_id during blocking + * time but got a PHC error, this occurs + * if device: + * - exceeded the get time request limit + * - received an invalid timestamp + */ + netdev_err(ena_dev->net_device, + "PHC get time request 0x%x failed (error 0x%x)\n", + phc->req_id, + resp->error_flags); + phc->stats.phc_err_ts += !!(resp->error_flags & + ENA_ADMIN_PHC_ERROR_FLAG_TIMESTAMP); + } else { + /* Device updated req_id during blocking + * time with valid timestamp + */ + phc->stats.phc_exp++; + } } } @@ -1880,6 +1888,11 @@ int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp) continue; } + /* Ensure PHC payload (timestamp, error_flags) is read + * after req_id update is observed + */ + dma_rmb(); + /* req_id was updated by the device which indicates that * PHC timestamp and error_flags are updated too, * checking errors before retrieving timestamp -- 2.47.3