From 9f1798282259b99011ba7a837d1555ebd05a0341 Mon Sep 17 00:00:00 2001 From: Suzanne Candanedo Date: Thu, 27 Oct 2022 14:32:12 +0100 Subject: GPUCORE-35754: Add barrier before updating GLB_DB_REQ to ring CSG DB GPUCORE-35974: Add Memory Barrier between CS_REQ/ACK and CSG_DB_REQ/ACK The access to GLB_DB_REQ/ACK needs to be ordered with respect to CSG_REQ/ACK and CSG_DB_REQ/ACK to avoid a scenario where a CSI request overlaps with a CSG request or 2 CSI requests overlap and FW ends up missing the 2nd request. Memory barrier is required, both on Host and FW side, to guarantee the ordering. Bug: 286056062 Test: SST soak test Provenance: https://code.ipdelivery.arm.com/c/GPU/mali-ddk/+/4688 Provenance: https://code.ipdelivery.arm.com/c/GPU/mali-ddk/+/5435 Change-Id: I4de23e3f37b81749c6d668952b4f8dd21c669fea --- mali_kbase/csf/mali_kbase_csf.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'mali_kbase') diff --git a/mali_kbase/csf/mali_kbase_csf.c b/mali_kbase/csf/mali_kbase_csf.c index 29542a6..fce6aaa 100644 --- a/mali_kbase/csf/mali_kbase_csf.c +++ b/mali_kbase/csf/mali_kbase_csf.c @@ -852,6 +852,15 @@ void kbase_csf_ring_csg_slots_doorbell(struct kbase_device *kbdev, if (WARN_ON(slot_bitmap > allowed_bitmap)) return; + /* The access to GLB_DB_REQ/ACK needs to be ordered with respect to CSG_REQ/ACK and + * CSG_DB_REQ/ACK to avoid a scenario where a CSI request overlaps with a CSG request + * or 2 CSI requests overlap and FW ends up missing the 2nd request. + * Memory barrier is required, both on Host and FW side, to guarantee the ordering. + * + * 'osh' is used as CPU and GPU would be in the same Outer shareable domain. + */ + dmb(osh); + value = kbase_csf_firmware_global_output(global_iface, GLB_DB_ACK); value ^= slot_bitmap; kbase_csf_firmware_global_input_mask(global_iface, GLB_DB_REQ, value, @@ -890,6 +899,14 @@ void kbase_csf_ring_cs_kernel_doorbell(struct kbase_device *kbdev, WARN_ON(csi_index >= ginfo->stream_num)) return; + /* The access to CSG_DB_REQ/ACK needs to be ordered with respect to + * CS_REQ/ACK to avoid a scenario where CSG_DB_REQ/ACK becomes visible to + * FW before CS_REQ/ACK is set. + * + * 'osh' is used as CPU and GPU would be in the same outer shareable domain. + */ + dmb(osh); + value = kbase_csf_firmware_csg_output(ginfo, CSG_DB_ACK); value ^= (1 << csi_index); kbase_csf_firmware_csg_input_mask(ginfo, CSG_DB_REQ, value, -- cgit v1.2.3 From a26b51ecfb9ac6fb8fa5b1998c7c1896ab5b1478 Mon Sep 17 00:00:00 2001 From: Michael Stokes Date: Thu, 1 Jun 2023 11:59:57 +0200 Subject: Add missing hwaccess_lock around atom_flags updates. Commit 0935897 (pa/1761483) added two additional katom flags, but updates to these new flags were not protected by hwaccess_lock, and could thus race with other updates and ultimately corrupt atom_flags. Bug: 265931966 Test: SST soak test Change-Id: I95acc5e335d8013394b11149abf5d9b793648c6f --- mali_kbase/mali_kbase_jd.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'mali_kbase') diff --git a/mali_kbase/mali_kbase_jd.c b/mali_kbase/mali_kbase_jd.c index 8667819..66064ec 100644 --- a/mali_kbase/mali_kbase_jd.c +++ b/mali_kbase/mali_kbase_jd.c @@ -762,10 +762,13 @@ static void jd_mark_simple_gfx_frame_atoms(struct kbase_jd_atom *katom) } if (dep_fence && dep_vtx) { + unsigned long flags; dev_dbg(kbdev->dev, "Simple gfx frame: {vtx=%pK, wait=%pK}->frag=%pK\n", dep_vtx, dep_fence, katom); + spin_lock_irqsave(&kbdev->hwaccess_lock, flags); katom->atom_flags |= KBASE_KATOM_FLAG_SIMPLE_FRAME_FRAGMENT; dep_vtx->atom_flags |= KBASE_KATOM_FLAG_DEFER_WHILE_POWEROFF; + spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags); } } @@ -839,14 +842,15 @@ bool kbase_jd_done_nolock(struct kbase_jd_atom *katom, bool post_immediately) dev_dbg(kctx->kbdev->dev, "Simple-frame fragment atom %pK unblocked\n", node); - node->atom_flags &= - ~KBASE_KATOM_FLAG_SIMPLE_FRAME_FRAGMENT; for (i = 0; i < 2; i++) { if (node->dep[i].atom && node->dep[i].atom->atom_flags & KBASE_KATOM_FLAG_DEFER_WHILE_POWEROFF) { + unsigned long flags; + spin_lock_irqsave(&kctx->kbdev->hwaccess_lock, flags); node->dep[i].atom->atom_flags &= ~KBASE_KATOM_FLAG_DEFER_WHILE_POWEROFF; + spin_unlock_irqrestore(&kctx->kbdev->hwaccess_lock, flags); dev_dbg(kctx->kbdev->dev, " Undeferred atom %pK\n", node->dep[i].atom); -- cgit v1.2.3