Remove VRING_USED_F_NO_NOTIFY flag in VirtQueue_kick and add barriers on QNX
authorvwan@ti.com <vwan@ti.com>
Fri, 5 Dec 2014 20:10:39 +0000 (12:10 -0800)
committerRobert Tivy <rtivy@ti.com>
Tue, 9 Dec 2014 18:20:17 +0000 (10:20 -0800)
This commit removes usage of VRING_USED_F_NO_NOTIFY flag in VirtQueue_kick on
QNX. This causes an interrupt to be sent for every buffer.

Also, barriers are added where appropriate to prevent any race condition due
to the Cortex-A15 weak memory model.

This addresses SDOCM00114151.

Signed-off-by: VW <vwan@ti.com>
qnx/src/ipc3x_dev/ti/syslink/ipc/hlos/knl/transports/virtio/VirtQueue.c

index 8fc1c094dda77353c40db453f52a8358572cbe59..94f210d0205b7289e275073cdb24289383c88871 100644 (file)
@@ -138,12 +138,11 @@ Void VirtQueue_cb(Void *buf, VirtQueue_Handle vq)
  */
 Void VirtQueue_kick(VirtQueue_Handle vq)
 {
-    /* For now, simply interrupt remote processor */
-    if (vq->vring.used->flags & VRING_USED_F_NO_NOTIFY) {
-        GT_0trace(curTrace, GT_3CLASS,
-                "VirtQueue_kick: no kick because of VRING_USED_F_NO_NOTIFY");
-        return;
-    }
+    /*
+     * We need to expose available array entries before sending an
+     * interrupt.
+     */
+    asm("   DSB ST");
 
     GT_2trace(curTrace, GT_2CLASS,
             "VirtQueue_kick: Sending interrupt to proc %d with payload 0x%x",
@@ -217,6 +216,12 @@ Int VirtQueue_addAvailBuf(VirtQueue_Handle vq, Void *buf, UInt32 len, Int16 head
         vq->vring.desc[head].len = len;
         vq->vring.desc[head].flags = 0;
 
+        /*
+         * Descriptors and available array need to be set before we expose the
+         * new available array entries.
+         */
+        asm("   DMB ST");
+
         vq->vring.avail->idx++;
     }
 
@@ -238,6 +243,9 @@ Int16 VirtQueue_getUsedBuf(VirtQueue_Object *vq, Void **buf)
         return (-1);
     }
 
+    /* Only get used array entries after they have been exposed. */
+    asm("   DMB");
+
     /* No need to know be kicked about added buffers anymore */
     //vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; // disabling for now, since there seems to be a race condition where an M3->A9 message is not detected because the interrupt isn't sent.