Skip to content

Commit

Permalink
vchiq_util: Fix race condition in push/pop
Browse files Browse the repository at this point in the history
The lack of memory barriers could (very rarely) result in
vchiu_queue_pop reading the next value before it had been written
(getting either NULL, or a value that had been popped once already).
  • Loading branch information
Philip Taylor authored and popcornmix committed Aug 1, 2013
1 parent 52c5734 commit c3bc1d4
Showing 1 changed file with 31 additions and 0 deletions.
31 changes: 31 additions & 0 deletions drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,20 @@ void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header)
}
}

/*
* Write to queue->storage must be visible after read from
* queue->read
*/
smp_mb();

queue->storage[queue->write & (queue->size - 1)] = header;

/*
* Write to queue->storage must be visible before write to
* queue->write
*/
smp_wmb();

queue->write++;

up(&queue->push);
Expand All @@ -97,6 +109,13 @@ VCHIQ_HEADER_T *vchiu_queue_peek(VCHIU_QUEUE_T *queue)
}

up(&queue->push); // We haven't removed anything from the queue.

/*
* Read from queue->storage must be visible after read from
* queue->write
*/
smp_rmb();

return queue->storage[queue->read & (queue->size - 1)];
}

Expand All @@ -110,8 +129,20 @@ VCHIQ_HEADER_T *vchiu_queue_pop(VCHIU_QUEUE_T *queue)
}
}

/*
* Read from queue->storage must be visible after read from
* queue->write
*/
smp_rmb();

header = queue->storage[queue->read & (queue->size - 1)];

/*
* Read from queue->storage must be visible before write to
* queue->read
*/
smp_mb();

queue->read++;

up(&queue->pop);
Expand Down

0 comments on commit c3bc1d4

Please sign in to comment.