Re: [PATCH rdma-next v4 06/17] RDMA/counter: Add "auto" configuration mode support

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

 



On Tue, Jun 18, 2019 at 08:26:14PM +0300, Leon Romanovsky wrote:

> +/**
> + * rdma_counter_bind_qp_auto - Check and bind the QP to a counter base on
> + *   the auto-mode rule
> + */
> +int rdma_counter_bind_qp_auto(struct ib_qp *qp, u8 port)
> +{
> +	struct rdma_port_counter *port_counter;
> +	struct ib_device *dev = qp->device;
> +	struct rdma_counter *counter;
> +	int ret;
> +
> +	if (!rdma_is_port_valid(dev, port))
> +		return -EINVAL;
> +
> +	port_counter = &dev->port_data[port].port_counter;
> +	if (port_counter->mode.mode != RDMA_COUNTER_MODE_AUTO)
> +		return 0;
> +
> +	counter = rdma_get_counter_auto_mode(qp, port);
> +	if (counter) {
> +		ret = __rdma_counter_bind_qp(counter, qp);
> +		if (ret) {
> +			rdma_restrack_put(&counter->res);
> +			return ret;
> +		}
> +		kref_get(&counter->kref);

The counter is left in the xarray while the kref is zero, this
kref_get is wrong..

Using two kref like things at the same time is a bad idea, the
'rdma_get_counter_auto_mode' should return the kref held, not the
restrack get. The restrack_del doesn't happen as long as the kref is
positive, so we don't need the retrack thing here..

> +	} else {
> +		counter = rdma_counter_alloc(dev, port, RDMA_COUNTER_MODE_AUTO);
> +		if (!counter)
> +			return -ENOMEM;
> +
> +		auto_mode_init_counter(counter, qp, port_counter->mode.mask);
> +
> +		ret = __rdma_counter_bind_qp(counter, qp);
> +		if (ret)
> +			goto err_bind;
> +
> +		rdma_counter_res_add(counter, qp);
> +		if (!rdma_restrack_get(&counter->res)) {
> +			ret = -EINVAL;
> +			goto err_get;
> +		}

and this shouldn't be needed as the kref is inited to 1 by the
rdma_counter_alloc..

> +	}
> +
> +	return 0;
> +
> +err_get:
> +	 __rdma_counter_unbind_qp(qp);
> +	__rdma_counter_dealloc(counter);
> +err_bind:
> +	rdma_counter_free(counter);
> +	return ret;
> +}

And then all this error unwind and all the twisty __ functions should
just be a single kref_put and the release should handle everything.

Jason




[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