wc->queue[head].sl = entry->sl;
        wc->queue[head].dlid_path_bits = entry->dlid_path_bits;
        wc->queue[head].port_num = entry->port_num;
+       /* Make sure queue entry is written before the head index. */
+       smp_wmb();
        wc->head = next;
 
        if (cq->notify == IB_CQ_NEXT_COMP ||
 
                if (tail == wc->head)
                        break;
-
+               /* Make sure entry is read after head index is read. */
+               smp_rmb();
                qp = ipath_lookup_qpn(&to_idev(cq->ibcq.device)->qp_table,
                                      wc->queue[tail].qp_num);
                entry->qp = &qp->ibqp;
 
                        ret = 0;
                        goto bail;
                }
+               /* Make sure entry is read after head index is read. */
+               smp_rmb();
                wqe = get_rwqe_ptr(rq, tail);
                if (++tail >= rq->size)
                        tail = 0;
 
                wqe->num_sge = wr->num_sge;
                for (i = 0; i < wr->num_sge; i++)
                        wqe->sg_list[i] = wr->sg_list[i];
+               /* Make sure queue entry is written before the head index. */
+               smp_wmb();
                wq->head = next;
                spin_unlock_irqrestore(&srq->rq.lock, flags);
        }
 
                        dev->n_pkt_drops++;
                        goto bail_sge;
                }
+               /* Make sure entry is read after head index is read. */
+               smp_rmb();
                wqe = get_rwqe_ptr(rq, tail);
                if (++tail >= rq->size)
                        tail = 0;
 
                wqe->num_sge = wr->num_sge;
                for (i = 0; i < wr->num_sge; i++)
                        wqe->sg_list[i] = wr->sg_list[i];
+               /* Make sure queue entry is written before the head index. */
+               smp_wmb();
                wq->head = next;
                spin_unlock_irqrestore(&qp->r_rq.lock, flags);
        }