hinic: fix out-of-order excution in arm cpu
authorLuo bin <luobin9@huawei.com>
Fri, 20 Mar 2020 23:13:18 +0000 (23:13 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sun, 22 Mar 2020 02:43:38 +0000 (19:43 -0700)
add read barrier in driver code to keep from reading other fileds
in dma memory which is writable for hw until we have verified the
memory is valid for driver

Signed-off-by: Luo bin <luobin9@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c
drivers/net/ethernet/huawei/hinic/hinic_rx.c
drivers/net/ethernet/huawei/hinic/hinic_tx.c

index eb53c15b13f33b626108f5ed396d15032b341e33..33f93cc25193a6008d696c96b8854d5bc1e49f32 100644 (file)
@@ -623,6 +623,8 @@ static int cmdq_cmd_ceq_handler(struct hinic_cmdq *cmdq, u16 ci,
        if (!CMDQ_WQE_COMPLETED(be32_to_cpu(ctrl->ctrl_info)))
                return -EBUSY;
 
+       dma_rmb();
+
        errcode = CMDQ_WQE_ERRCODE_GET(be32_to_cpu(status->status_info), VAL);
 
        cmdq_sync_cmd_handler(cmdq, ci, errcode);
index 6a723c4757bce69b3b42b81453a345af2c6ef82e..c0b6bcb067cd478eb85a976ab947f0f2dcfd4d1c 100644 (file)
@@ -235,6 +235,8 @@ static void aeq_irq_handler(struct hinic_eq *eq)
                if (HINIC_EQ_ELEM_DESC_GET(aeqe_desc, WRAPPED) == eq->wrapped)
                        break;
 
+               dma_rmb();
+
                event = HINIC_EQ_ELEM_DESC_GET(aeqe_desc, TYPE);
                if (event >= HINIC_MAX_AEQ_EVENTS) {
                        dev_err(&pdev->dev, "Unknown AEQ Event %d\n", event);
index 2695ad69fca600c469762643ebd804f6bdfade1d..815649e37cb152f6f2cb584fabf01ef00469e4ec 100644 (file)
@@ -350,6 +350,9 @@ static int rxq_recv(struct hinic_rxq *rxq, int budget)
                if (!rq_wqe)
                        break;
 
+               /* make sure we read rx_done before packet length */
+               dma_rmb();
+
                cqe = rq->cqe[ci];
                status =  be32_to_cpu(cqe->status);
                hinic_rq_get_sge(rxq->rq, rq_wqe, ci, &sge);
index 0e13d1c7e474602b85a9bdd73190b3e7a2c9145c..375d81d03e8667f5b923395725129c7b16b8cf42 100644 (file)
@@ -622,6 +622,8 @@ static int free_tx_poll(struct napi_struct *napi, int budget)
        do {
                hw_ci = HW_CONS_IDX(sq) & wq->mask;
 
+               dma_rmb();
+
                /* Reading a WQEBB to get real WQE size and consumer index. */
                sq_wqe = hinic_sq_read_wqebb(sq, &skb, &wqe_size, &sw_ci);
                if ((!sq_wqe) ||