Re: [PATCH rdma-rc] IB/uverbs: Don't use the address vector's port number during modify_qp

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 20 Jun 2018 12:00:37 -0600
Jason Gunthorpe <jgg@xxxxxxxxxxxx> wrote:


> 
> diff --git a/drivers/infiniband/core/uverbs_cmd.c
> b/drivers/infiniband/core/uverbs_cmd.c index
> 908ee8ab32972f..d34179d2aa6d4b 100644 ---
> a/drivers/infiniband/core/uverbs_cmd.c +++
> b/drivers/infiniband/core/uverbs_cmd.c @@ -2027,13 +2027,35 @@ static
> int modify_qp(struct ib_uverbs_file *file, attr->alt_timeout
> = cmd->base.alt_timeout; attr->rate_limit	  = cmd->rate_limit;
>  
> -	if (cmd->base.attr_mask & IB_QP_AV)
> +	if (cmd->base.attr_mask & IB_QP_AV) {
> +		unsigned int primary_port = (cmd->base.attr_mask & IB_QP_PORT) ?
> +						cmd->base.port_num :
> +						    qp->port;
Hi Jason,
You have a problem in the above line when qp != qp->real_qp (as is the case with XRC
target QPs).

The problem is that for XRC target QPs, only qp->real_qp->port is updated when
the IB_QP_PORT is specified.  Thus, for XRC TGT qps, qp->port is left at 0.

(At this point in your code, you are still dealing with the "outer" qp.
This changes under function ib_modify_qp_with_udata(), where all modifications
are done (and recorded) on qp->real_qp.  This includes updating qp->port:
In file drivers/infiniband/core/verbs.c, seee function ib_modify_qp_with_udata():
int ib_modify_qp_with_udata(struct ib_qp *ib_qp, struct ib_qp_attr *attr,
                            int attr_mask, struct ib_udata *udata)
{
        return _ib_modify_qp(ib_qp->real_qp, attr, attr_mask, udata);
}

and under function _ib_modify_qp() in the same file:
        if (attr_mask & IB_QP_PORT)
                qp->port = attr->port_num;

Thus, notice that it qp->real_qp->port which gets updated.
For all QP types except XRC_TGT, this is OK since qp->real_qp = qp.
However, for XRC_TGT, qp->real_qp != qp.

Thus:
+		unsigned int primary_port = (cmd->base.attr_mask & IB_QP_PORT) ?
+						cmd->base.port_num :
+						    qp->port;

should be:
+		unsigned int primary_port = (cmd->base.attr_mask & IB_QP_PORT) ?
+						cmd->base.port_num :
+                                             qp->real_qp->port;

-Jack

> +
> +		/*
> +		 * The Linux ABI specifies the primary port number
> both
> +		 * loosely in the struct (as IBA suggests) and also
> in the
> +		 * AV. The primary AV port number must always agree
> with the
> +		 * primary port number set by IB_QP_PORT.
> +		 */
> +		if (cmd->base.dest.port_num != primary_port) {
> +			ret = -EINVAL;
> +			goto release_qp;
> +		}
>  		copy_ah_attr_from_uverbs(qp->device, &attr->ah_attr,
>  					 &cmd->base.dest);
> +	}
> +
> +	if (cmd->base.attr_mask & IB_QP_ALT_PATH) {
> +		if (!rdma_is_port_valid(qp->device,
> +                  cmd->base.alt_dest.port_num)) {
> +			ret = -EINVAL;
> +			goto release_qp;
> +		}
>  
> -	if (cmd->base.attr_mask & IB_QP_ALT_PATH)
>  		copy_ah_attr_from_uverbs(qp->device,
> &attr->alt_ah_attr, &cmd->base.alt_dest);
> +	}
>  
>  	ret = ib_modify_qp_with_udata(qp, attr,
>  				      modify_qp_mask(qp->qp_type,
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux