Re: [PATCH 7/8] RDMA/devices: Use xarray to store the client_data

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

 



On Mon, Feb 04, 2019 at 02:17:50PM -0700, Jason Gunthorpe wrote:
> +/*
> + * xarray has this annoying behavior where it won't iterate over NULL values
> + * stored in allocated arrays.  So we need our own iterator to see all values
> + * stored in the array. This does the same thing as xa_for_each except that it
> + * also returns NULL valued entries if the array is allocating. Simplified to
> + * only work on simple xarrays.
> + */
> +static void *xan_find(struct xarray *xa, unsigned long *indexp,
> +		      unsigned long max, xa_mark_t filter)
> +{
> +	XA_STATE(xas, xa, *indexp);
> +	void *entry;
> +
> +	rcu_read_lock();
> +	do {
> +		if ((__force unsigned int)filter < XA_MAX_MARKS)
> +			entry = xas_find_marked(&xas, max, filter);
> +		else
> +			entry = xas_find(&xas, max);
> +		if (xa_is_zero(entry) && !xas_get_mark(&xas, XA_FREE_MARK))
> +			break;
> +	} while (xas_retry(&xas, entry));
> +	rcu_read_unlock();
> +
> +	if (entry) {
> +		*indexp = xas.xa_index;
> +		if (xa_is_zero(entry))
> +			return NULL;
> +		return entry;
> +	}
> +	return ERR_PTR(-ENOENT);
> +}
> +#define xan_for_each(xa, index, entry, filter)                                 \
> +	for (index = 0, entry = xan_find(xa, &(index), ULONG_MAX, filter);     \
> +	     !IS_ERR(entry);                                                   \
> +	     (index)++, entry = xan_find(xa, &(index), ULONG_MAX, filter))

We can't do this in the generic XArray code because ERR_PTR(-ENOENT) might
overlap with an XArray value entry.

Now, what you can do is iterate using xas_for_each().  That will return the
zeroed entries.

	XA_STATE(xas, &dev->client_data, 0);
...
	rcu_read_lock();
	xas_for_each_marked(&xas, client_data, ULONG_MAX,
				CLIENT_DATA_REGISTERED) {
		struct ib_client *client = xa_load(&clients, xas.xa_index);
...

I'm not familiar enough with your code to figure out where you'd want
to rcu_read_unlock() :-)



[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