]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mlx4_ib: Fix endianness in blueflame post_send.
authorJack Morgenstein <jackm@dev.mellanox.co.il>
Thu, 10 Jul 2014 09:29:14 +0000 (12:29 +0300)
committerMukesh Kacker <mukesh.kacker@oracle.com>
Tue, 7 Jul 2015 21:45:21 +0000 (14:45 -0700)
qp object field doorbell_qpn was initialized using swab()
at qp creation.
swab() unconditionally swaps dword endianness. Thus, on
little-endian platforms the endianness of doorbell_qpn was
big endian; on big-endian platforms, doorbell_qpn is little-endian.

In post send blueflame, doorbell_qpn was taken as is (i.e., the
driver assumed that it was in big-endian format). This was OK
for little-endian hosts, but incorrect for big-endian hosts.

The fix is to use cpu_to_be32 when initializing doorbell_qpn (thus
guaranteeing that doorbell_qpn is in big-endian format on all
host types). This also requires modifying non-bf sends to
use __raw_writel (which does not do any endianness swapping)
instead of writel (which does endianness swapping on big-endian hosts).

The fix was developed by Shamir Rabinovitch of Oracle.

Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
(Ported by Mellanox OFED 2.4)

Signed-off-by: Mukesh Kacker <mukesh.kacker@oracle.com>
drivers/infiniband/hw/mlx4/mlx4_ib.h
drivers/infiniband/hw/mlx4/qp.c
drivers/net/ethernet/mellanox/mlx4_vnic/vnic_qp.c

index 86046705d2c5caa8f00a80a564e27499db0bf6b3..1d19744333eba6a9b172989d3e747fd79a3bd2b8 100644 (file)
@@ -279,7 +279,7 @@ struct mlx4_ib_qp {
        struct mlx4_db          db;
        struct mlx4_ib_wq       rq;
 
-       u32                     doorbell_qpn;
+       __be32                  doorbell_qpn;
        __be32                  sq_signal_bits;
        unsigned                sq_next_wqe;
        int                     sq_max_wqes_per_wr;
index a00000bcd1cf1f0354d99bdbbc68a608d6986509..84df3d8c935583af0db3a3a11ad0280a526aca0d 100644 (file)
@@ -861,7 +861,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
         * shifting) for send doorbell.  Precompute this value to save
         * a little bit when posting sends.
         */
-       qp->doorbell_qpn = swab32(qp->mqp.qpn << 8);
+       qp->doorbell_qpn = cpu_to_be32((u32)qp->mqp.qpn << 8);
 
        qp->mqp.event = mlx4_ib_qp_event;
        if (!*caller_qp)
@@ -3053,7 +3053,7 @@ out:
                /* We set above doorbell_qpn bits to 0 as part of vlan
                  * tag initialization, so |= should be correct.
                */
-               *(u32 *) (&ctrl->vlan_tag) |= qp->doorbell_qpn;
+               *(__be32 *)(&ctrl->vlan_tag) |= qp->doorbell_qpn;
                /*
                 * Make sure that descriptor is written to memory
                 * before writing to BlueFlame page.
@@ -3077,7 +3077,8 @@ out:
                 */
                wmb();
 
-               writel(qp->doorbell_qpn, qp->bf.uar->map + MLX4_SEND_DOORBELL);
+               __raw_writel((__force u32)qp->doorbell_qpn,
+                            qp->bf.uar->map + MLX4_SEND_DOORBELL);
 
                /*
                 * Make sure doorbells don't leak out of SQ spinlock
index b4884b8b3e47329eb65f371104b24d8dcf2a78bd..f700000477655c4862db311df4de359758264af0 100644 (file)
@@ -630,7 +630,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
         * shifting) for send doorbell.  Precompute this value to save
         * a little bit when posting sends.
         */
-       qp->doorbell_qpn = swab32(qp->mqp.qpn << 8);
+       qp->doorbell_qpn = cpu_to_be32((u32)qp->mqp.qpn << 8);
 
        qp->mqp.event = mlx4_ib_qp_event;
 
@@ -1489,7 +1489,7 @@ int vnic_ib_post_send(struct ib_qp *ibqp,
 out:
        if (nreq == 1 && inl && size > 1 && size < qp->bf.buf_size / 16) {
                ctrl->owner_opcode |= htonl((qp->sq_next_wqe & 0xffff) << 8);
-               *(u32 *) (&ctrl->vlan_tag) |= qp->doorbell_qpn;
+               *(__be32 *)(&ctrl->vlan_tag) |= qp->doorbell_qpn;
                /*
                 * Make sure that descriptor is written to memory
                 * before writing to BlueFlame page.
@@ -1513,7 +1513,8 @@ out:
                 */
                wmb();
 
-               writel(qp->doorbell_qpn, qp->bf.uar->map + MLX4_SEND_DOORBELL);
+               __raw_writel((__force u32)qp->doorbell_qpn,
+                            qp->bf.uar->map + MLX4_SEND_DOORBELL);
 
                /*
                 * Make sure doorbells don't leak out of SQ spinlock