* [PATCH] mlx4: remove limitation on LSO header size
@ 2009-09-30 9:07 Eli Cohen
2009-10-07 22:45 ` Roland Dreier
[not found] ` <4AC858E0.2010506@voltaire.com>
0 siblings, 2 replies; 5+ messages in thread
From: Eli Cohen @ 2009-09-30 9:07 UTC (permalink / raw)
To: Roland Dreier; +Cc: Linux RDMA list, general-list, ewg
Current code has a limitation as for the size of an LSO header not allowed to
cross a 64 byte boundary. This patch removes this limitation by setting the WQE
RR for large headers thus allowing LSO headers of any size. The extra buffer
reserved for MLX4_IB_QP_LSO QPs has been doubled, from 64 to 128 bytes,
assuming this is reasonable upper limit to header length.
Also, this patch will cause IB_DEVICE_UD_TSO to be set only of FW versions that
set MLX4_DEV_CAP_FLAG_BLH; e.g. FW version 2.6.000 and higher.
Signed-off-by: Eli Cohen <eli-VPRAkNaXOzVS1MOuV/RT9w@public.gmane.org>
---
drivers/infiniband/hw/mlx4/main.c | 2 +-
drivers/infiniband/hw/mlx4/qp.c | 17 +++++++----------
include/linux/mlx4/device.h | 1 +
3 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 3cb3f47..e596537 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -103,7 +103,7 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
props->device_cap_flags |= IB_DEVICE_UD_AV_PORT_ENFORCE;
if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_IPOIB_CSUM)
props->device_cap_flags |= IB_DEVICE_UD_IP_CSUM;
- if (dev->dev->caps.max_gso_sz)
+ if (dev->dev->caps.max_gso_sz && dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BLH)
props->device_cap_flags |= IB_DEVICE_UD_TSO;
if (dev->dev->caps.bmme_flags & MLX4_BMME_FLAG_RESERVED_LKEY)
props->device_cap_flags |= IB_DEVICE_LOCAL_DMA_LKEY;
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 219b103..1b356cf 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -261,7 +261,7 @@ static int send_wqe_overhead(enum ib_qp_type type, u32 flags)
case IB_QPT_UD:
return sizeof (struct mlx4_wqe_ctrl_seg) +
sizeof (struct mlx4_wqe_datagram_seg) +
- ((flags & MLX4_IB_QP_LSO) ? 64 : 0);
+ ((flags & MLX4_IB_QP_LSO) ? 128 : 0);
case IB_QPT_UC:
return sizeof (struct mlx4_wqe_ctrl_seg) +
sizeof (struct mlx4_wqe_raddr_seg);
@@ -1467,16 +1467,11 @@ static void __set_data_seg(struct mlx4_wqe_data_seg *dseg, struct ib_sge *sg)
static int build_lso_seg(struct mlx4_wqe_lso_seg *wqe, struct ib_send_wr *wr,
struct mlx4_ib_qp *qp, unsigned *lso_seg_len,
- __be32 *lso_hdr_sz)
+ __be32 *lso_hdr_sz, int *blh)
{
unsigned halign = ALIGN(sizeof *wqe + wr->wr.ud.hlen, 16);
- /*
- * This is a temporary limitation and will be removed in
- * a forthcoming FW release:
- */
- if (unlikely(halign > 64))
- return -EINVAL;
+ *blh = unlikely(halign > 64) ? 1 : 0;
if (unlikely(!(qp->flags & MLX4_IB_QP_LSO) &&
wr->num_sge > qp->sq.max_gs - (halign >> 4)))
@@ -1523,6 +1518,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
__be32 *lso_wqe;
__be32 uninitialized_var(lso_hdr_sz);
int i;
+ int blh = 0;
spin_lock_irqsave(&qp->sq.lock, flags);
@@ -1616,7 +1612,7 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
size += sizeof (struct mlx4_wqe_datagram_seg) / 16;
if (wr->opcode == IB_WR_LSO) {
- err = build_lso_seg(wqe, wr, qp, &seglen, &lso_hdr_sz);
+ err = build_lso_seg(wqe, wr, qp, &seglen, &lso_hdr_sz, &blh);
if (unlikely(err)) {
*bad_wr = wr;
goto out;
@@ -1687,7 +1683,8 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
}
ctrl->owner_opcode = mlx4_ib_opcode[wr->opcode] |
- (ind & qp->sq.wqe_cnt ? cpu_to_be32(1 << 31) : 0);
+ (ind & qp->sq.wqe_cnt ? cpu_to_be32(1 << 31) : 0) |
+ (blh ? cpu_to_be32(1 << 6) : 0);
stamp = ind + qp->sq_spare_wqes;
ind += DIV_ROUND_UP(size * 16, 1U << qp->sq.wqe_shift);
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index ce7cc6c..e92d1bf 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -61,6 +61,7 @@ enum {
MLX4_DEV_CAP_FLAG_BAD_PKEY_CNTR = 1 << 8,
MLX4_DEV_CAP_FLAG_BAD_QKEY_CNTR = 1 << 9,
MLX4_DEV_CAP_FLAG_DPDP = 1 << 12,
+ MLX4_DEV_CAP_FLAG_BLH = 1 << 15,
MLX4_DEV_CAP_FLAG_MEM_WINDOW = 1 << 16,
MLX4_DEV_CAP_FLAG_APM = 1 << 17,
MLX4_DEV_CAP_FLAG_ATOMIC = 1 << 18,
--
1.6.4.3
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] mlx4: remove limitation on LSO header size
2009-09-30 9:07 [PATCH] mlx4: remove limitation on LSO header size Eli Cohen
@ 2009-10-07 22:45 ` Roland Dreier
[not found] ` <adaocoiombn.fsf-FYB4Gu1CFyUAvxtiuMwx3w@public.gmane.org>
[not found] ` <4AC858E0.2010506@voltaire.com>
1 sibling, 1 reply; 5+ messages in thread
From: Roland Dreier @ 2009-10-07 22:45 UTC (permalink / raw)
To: Eli Cohen; +Cc: Linux RDMA list, ewg, general-list
> + *blh = unlikely(halign > 64) ? 1 : 0;
This idiom of "(boolean condition) ? 1 : 0" looks odd to me... doesn't
(halign > 64) already evaluate to 1 or 0 anyway? Does the unlikely()
actually affect code generation here?
With that said, see below...
> + int blh = 0;
I assume this initialization is to avoid a compiler warning. But the
code is actually correct without initializing blh -- so I think that we
save a tiny bit of code by doing uninitialized_var() instead?
> + (blh ? cpu_to_be32(1 << 6) : 0);
...given that the only use of blh is as a flag to decide what constant
to use here, does it generate better code to make blh be __be32 and set
the value directly in build_lso_seg, ie do:
*blh = unlikely(halign > 64) ? cpu_to_be32(1 << 6) : 0;
and then use blh without ?: in mlx4_ib_post_send...
- R.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [ewg] [PATCH] mlx4: remove limitation on LSO header size
[not found] ` <4AC858E0.2010506-smomgflXvOZWk0Htik3J/w@public.gmane.org>
@ 2009-10-11 9:47 ` Eli Cohen
0 siblings, 0 replies; 5+ messages in thread
From: Eli Cohen @ 2009-10-11 9:47 UTC (permalink / raw)
To: Or Gerlitz; +Cc: Eli Cohen, Roland Dreier, Linux RDMA list
On Sun, Oct 04, 2009 at 10:12:16AM +0200, Or Gerlitz wrote:
>> Also, this patch will cause IB_DEVICE_UD_TSO to be set only of FW versions that set MLX4_DEV_CAP_FLAG_BLH; e.g. FW version 2.6.000 and higher.
> warning to users having an older firmware installed?
I am not sure this deserves a warning - after all it's just that the
feature is not supported.
> So the driver doesn't use the actual value of the max_gso_sz capability,
> isn't this a bug? the BLH bit (any reason not the mention in the
> change-log what these three letters stand for...?) serves you to support
> large LSO headers, but isn't enough, max_gso_sz is related to the
> payload and should be used, I think.
>
According to the spec, for LSO to be supported at all, max_gso_sz must
be none zero. Moreover, for BLH to be supported (BLH stands for Big
LSO Header), the MLX4_DEV_CAP_FLAG_BLH flag must be set and hence the
condition on both of them.
>> if (dev->dev->caps.bmme_flags & MLX4_BMME_FLAG_RESERVED_LKEY)
>> props->device_cap_flags |= IB_DEVICE_LOCAL_DMA_LKEY;
>> diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
>> index 219b103..1b356cf 100644
>> --- a/drivers/infiniband/hw/mlx4/qp.c
>> +++ b/drivers/infiniband/hw/mlx4/qp.c
>> @@ -261,7 +261,7 @@ static int send_wqe_overhead(enum ib_qp_type type, u32 flags)
>> case IB_QPT_UD:
>> return sizeof (struct mlx4_wqe_ctrl_seg) +
>> sizeof (struct mlx4_wqe_datagram_seg) +
>> - ((flags & MLX4_IB_QP_LSO) ? 64 : 0);
>> + ((flags & MLX4_IB_QP_LSO) ? 128 : 0);
> 64 , 128 ... here and later in build_lso_seg , how about defining some
> human readable something?
OK, I will replace with an enum.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mlx4: remove limitation on LSO header size
[not found] ` <adaocoiombn.fsf-FYB4Gu1CFyUAvxtiuMwx3w@public.gmane.org>
@ 2009-10-11 10:00 ` Eli Cohen
2009-10-12 17:03 ` Roland Dreier
0 siblings, 1 reply; 5+ messages in thread
From: Eli Cohen @ 2009-10-11 10:00 UTC (permalink / raw)
To: Roland Dreier; +Cc: Linux RDMA list, Eli Cohen, ewg, general-list
On Wed, Oct 07, 2009 at 03:45:16PM -0700, Roland Dreier wrote:
>
> > + *blh = unlikely(halign > 64) ? 1 : 0;
>
> This idiom of "(boolean condition) ? 1 : 0" looks odd to me... doesn't
> (halign > 64) already evaluate to 1 or 0 anyway? Does the unlikely()
> actually affect code generation here?
True, (halign > 64) is the same and is cleaner. As for the unlikely()
-- well it's already been there and besides, we're never sure if it
will improve anything so the same question could be asked for other
places in the code.
>
> With that said, see below...
>
> > + int blh = 0;
>
> I assume this initialization is to avoid a compiler warning. But the
> code is actually correct without initializing blh -- so I think that we
> save a tiny bit of code by doing uninitialized_var() instead?
We must initialize blh since it is used for any send request and not
just LSO opcodes.
>
> > + (blh ? cpu_to_be32(1 << 6) : 0);
>
> ...given that the only use of blh is as a flag to decide what constant
> to use here, does it generate better code to make blh be __be32 and set
> the value directly in build_lso_seg, ie do:
>
> *blh = unlikely(halign > 64) ? cpu_to_be32(1 << 6) : 0;
>
> and then use blh without ?: in mlx4_ib_post_send...
>
So we can let build_lso_header() put the corrent value for blh and
unconditionally "or" it into owner_opcode.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mlx4: remove limitation on LSO header size
2009-10-11 10:00 ` Eli Cohen
@ 2009-10-12 17:03 ` Roland Dreier
0 siblings, 0 replies; 5+ messages in thread
From: Roland Dreier @ 2009-10-12 17:03 UTC (permalink / raw)
To: Eli Cohen; +Cc: Linux RDMA list, Eli Cohen, ewg, general-list
> > > + *blh = unlikely(halign > 64) ? 1 : 0;
> > This idiom of "(boolean condition) ? 1 : 0" looks odd to me... doesn't
> > (halign > 64) already evaluate to 1 or 0 anyway? Does the unlikely()
> > actually affect code generation here?
> True, (halign > 64) is the same and is cleaner. As for the unlikely()
> -- well it's already been there and besides, we're never sure if it
> will improve anything so the same question could be asked for other
> places in the code.
I was just wondering in this case where you are just assigning the
boolean value of the expression to a variable how unlikely affects
things. I can understand for conditional jumps how the compiler can
choose to make the likely case more efficient, but when there are no
jumps then I was just curious how the hint could help.
> > I assume this initialization is to avoid a compiler warning. But the
> > code is actually correct without initializing blh -- so I think that we
> > save a tiny bit of code by doing uninitialized_var() instead?
> We must initialize blh since it is used for any send request and not
> just LSO opcodes.
So then this patch was buggy because blh was not reinitialized as we
loop through multiple work requests? eg an LSO request followed by a
non-LSO request?
Anyway I'll look over the newer patch.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2009-10-12 17:03 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-30 9:07 [PATCH] mlx4: remove limitation on LSO header size Eli Cohen
2009-10-07 22:45 ` Roland Dreier
[not found] ` <adaocoiombn.fsf-FYB4Gu1CFyUAvxtiuMwx3w@public.gmane.org>
2009-10-11 10:00 ` Eli Cohen
2009-10-12 17:03 ` Roland Dreier
[not found] ` <4AC858E0.2010506@voltaire.com>
[not found] ` <4AC858E0.2010506-smomgflXvOZWk0Htik3J/w@public.gmane.org>
2009-10-11 9:47 ` [ewg] " Eli Cohen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox