Re: [PATCH rdma-next v3 09/17] IB/mlx5: Support statistic q counter configuration

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

 



On 6/12/2019 9:44 PM, Jason Gunthorpe wrote:
> On Wed, Jun 12, 2019 at 03:12:27PM +0300, Leon Romanovsky wrote:
>> On Wed, Jun 12, 2019 at 09:08:02AM -0300, Jason Gunthorpe wrote:
>>> On Wed, Jun 12, 2019 at 12:01:23PM +0000, Mark Zhang wrote:
>>>> On 6/12/2019 1:54 AM, Jason Gunthorpe wrote:
>>>>> On Thu, Jun 06, 2019 at 01:53:37PM +0300, Leon Romanovsky wrote:
>>>>>> From: Mark Zhang <markz@xxxxxxxxxxxx>
>>>>>>
>>>>>> Add support for ib callbacks counter_bind_qp() and counter_unbind_qp().
>>>>>>
>>>>>> Signed-off-by: Mark Zhang <markz@xxxxxxxxxxxx>
>>>>>> Reviewed-by: Majd Dibbiny <majd@xxxxxxxxxxxx>
>>>>>> Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx>
>>>>>>    drivers/infiniband/hw/mlx5/main.c | 53 +++++++++++++++++++++++++++++++
>>>>>>    1 file changed, 53 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
>>>>>> index 8b7bcf8f68fb..66c94a060718 100644
>>>>>> +++ b/drivers/infiniband/hw/mlx5/main.c
>>>>>> @@ -5533,6 +5533,57 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
>>>>>>    	return num_counters;
>>>>>>    }
>>>>>>
>>>>>> +static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter,
>>>>>> +				   struct ib_qp *qp)
>>>>>> +{
>>>>>> +	struct mlx5_ib_dev *dev = to_mdev(qp->device);
>>>>>> +	u16 cnt_set_id = 0;
>>>>>> +	int err;
>>>>>> +
>>>>>> +	if (!counter->id) {
>>>>>> +		err = mlx5_cmd_alloc_q_counter(dev->mdev,
>>>>>> +					       &cnt_set_id,
>>>>>> +					       MLX5_SHARED_RESOURCE_UID);
>>>>>> +		if (err)
>>>>>> +			return err;
>>>>>> +		counter->id = cnt_set_id;
>>>>>> +	}
>>>>>> +
>>>>>> +	err = mlx5_ib_qp_set_counter(qp, counter);
>>>>>> +	if (err)
>>>>>> +		goto fail_set_counter;
>>>>>> +
>>>>>> +	return 0;
>>>>>> +
>>>>>> +fail_set_counter:
>>>>>> +	mlx5_core_dealloc_q_counter(dev->mdev, cnt_set_id);
>>>>>> +	counter->id = 0;
>>>>>> +
>>>>>> +	return err;
>>>>>> +}
>>>>>> +
>>>>>> +static int mlx5_ib_counter_unbind_qp(struct ib_qp *qp, bool force)
>>>>>> +{
>>>>>> +	struct mlx5_ib_dev *dev = to_mdev(qp->device);
>>>>>> +	struct rdma_counter *counter = qp->counter;
>>>>>> +	int err;
>>>>>> +
>>>>>> +	err = mlx5_ib_qp_set_counter(qp, NULL);
>>>>>> +	if (err && !force)
>>>>>> +		return err;
>>>>>> +
>>>>>> +	/*
>>>>>> +	 * Deallocate the counter if this is the last QP bound on it;
>>>>>> +	 * If @force is set then we still deallocate the q counter
>>>>>> +	 * no matter if there's any error in previous. used for cases
>>>>>> +	 * like qp destroy.
>>>>>> +	 */
>>>>>> +	if (atomic_read(&counter->usecnt) == 1)
>>>>>> +		return mlx5_core_dealloc_q_counter(dev->mdev, counter->id);
>>>>>
>>>>> This looks like a nonsense thing to write, what it is trying to do
>>>>> with that atomic?
>>>>>
>>>>> I still can't see why this isn't a normal kref.
>>>>>
>>>>
>>>> Hi Jason,
>>>>
>>>> Have discussed with Leon, unlike other resources, counter alloc/dealloc
>>>> isn't called explicitly. So we need a refcount to record how many QPs
>>>> are bound on this counter, when it comes to 0 then the counter can be
>>>> deallocated. Whether to use atomic or kref the code is similar, it is
>>>> not able to take advantage of kref/completion.
>>>
>>> That doesn't explain the nonsense "atomic_read(&counter->usecnt) == 1"
>>> test
>>
>> It means that all QPs "returned" this counter.
> 
> It doesn't make sense to do something like that with an atomic, either
> you know there is no possible atomic_inc/dec at this point (which begs the
> question why test it), or it is racy
> 

How about add a new parameter "last_qp", if it is true then deallocate 
the counter? So that the "atomic_read()" check can be performed in core 
layer.


> 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