[NET] back: fix synchronisation of access to deallocation buffer ring.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Mon, 5 Jun 2006 14:14:58 +0000 (15:14 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Mon, 5 Jun 2006 14:14:58 +0000 (15:14 +0100)
Must ensure ring is written to before producer index is incremented.
Bug diagnosed by Ky Srinivasan <ksrinivasan@novell.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/drivers/xen/netback/netback.c

index fb6b88e5e2ccaed5c529a94f7bacc28eb03ad1d1..238565f1bbc85efbb500f2777651a4583ae7d6b1 100644 (file)
@@ -458,6 +458,9 @@ inline static void net_tx_action_dealloc(void)
        dc = dealloc_cons;
        dp = dealloc_prod;
 
+       /* Ensure we see all indexes enqueued by netif_idx_release(). */
+       smp_rmb();
+
        /*
         * Free up any grants we have finished using
         */
@@ -695,7 +698,10 @@ static void netif_idx_release(u16 pending_idx)
        unsigned long flags;
 
        spin_lock_irqsave(&_lock, flags);
-       dealloc_ring[MASK_PEND_IDX(dealloc_prod++)] = pending_idx;
+       dealloc_ring[MASK_PEND_IDX(dealloc_prod)] = pending_idx;
+       /* Sync with net_tx_action_dealloc: insert idx /then/ incr producer. */
+       smp_wmb();
+       dealloc_prod++;
        spin_unlock_irqrestore(&_lock, flags);
 
        tasklet_schedule(&net_tx_tasklet);