]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
scsi: hisi_sas: add memory barrier in task delivery function
[mirror_ubuntu-bionic-kernel.git] / drivers / scsi / hisi_sas / hisi_sas_v2_hw.c
index 11bb01d88cb2b32b79b68ba562c9937c82263c74..daa2dd1848e97167b80bc709500150c03dc182ff 100644 (file)
@@ -1682,23 +1682,28 @@ get_free_slot_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_dq *dq)
 static void start_delivery_v2_hw(struct hisi_sas_dq *dq)
 {
        struct hisi_hba *hisi_hba = dq->hisi_hba;
-       struct hisi_sas_slot *s, *s1;
+       struct hisi_sas_slot *s, *s1, *s2 = NULL;
        struct list_head *dq_list;
        int dlvry_queue = dq->id;
-       int wp, count = 0;
+       int wp;
 
        dq_list = &dq->list;
        list_for_each_entry_safe(s, s1, &dq->list, delivery) {
                if (!s->ready)
                        break;
-               count++;
-               wp = (s->dlvry_queue_slot + 1) % HISI_SAS_QUEUE_SLOTS;
+               s2 = s;
                list_del(&s->delivery);
        }
 
-       if (!count)
+       if (!s2)
                return;
 
+       /*
+        * Ensure that memories for slots built on other CPUs is observed.
+        */
+       smp_rmb();
+       wp = (s2->dlvry_queue_slot + 1) % HISI_SAS_QUEUE_SLOTS;
+
        hisi_sas_write32(hisi_hba, DLVRY_Q_0_WR_PTR + (dlvry_queue * 0x14), wp);
 }