IB/core: Provide rdma_ versions of the gid cache API
These versions are functionally similar but all return gid_attrs and related information via reference instead of via copy. The old API is preserved, implemented as wrappers around the new, until all callers can be converted. Signed-off-by: Parav Pandit <parav@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
parent
ddb457c699
commit
c3d71b69a7
|
@ -649,80 +649,37 @@ static int __ib_cache_gid_get(struct ib_device *ib_dev, u8 port, int index,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _ib_cache_gid_table_find(struct ib_device *ib_dev,
|
|
||||||
const union ib_gid *gid,
|
|
||||||
const struct ib_gid_attr *val,
|
|
||||||
unsigned long mask,
|
|
||||||
u8 *port, u16 *index)
|
|
||||||
{
|
|
||||||
struct ib_gid_table *table;
|
|
||||||
u8 p;
|
|
||||||
int local_index;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
for (p = 0; p < ib_dev->phys_port_cnt; p++) {
|
|
||||||
table = ib_dev->cache.ports[p].gid;
|
|
||||||
read_lock_irqsave(&table->rwlock, flags);
|
|
||||||
local_index = find_gid(table, gid, val, false, mask, NULL);
|
|
||||||
if (local_index >= 0) {
|
|
||||||
if (index)
|
|
||||||
*index = local_index;
|
|
||||||
if (port)
|
|
||||||
*port = p + rdma_start_port(ib_dev);
|
|
||||||
read_unlock_irqrestore(&table->rwlock, flags);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
read_unlock_irqrestore(&table->rwlock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ib_cache_gid_find(struct ib_device *ib_dev,
|
|
||||||
const union ib_gid *gid,
|
|
||||||
enum ib_gid_type gid_type,
|
|
||||||
struct net_device *ndev, u8 *port,
|
|
||||||
u16 *index)
|
|
||||||
{
|
|
||||||
unsigned long mask = GID_ATTR_FIND_MASK_GID |
|
|
||||||
GID_ATTR_FIND_MASK_GID_TYPE;
|
|
||||||
struct ib_gid_attr gid_attr_val = {.ndev = ndev, .gid_type = gid_type};
|
|
||||||
|
|
||||||
if (ndev)
|
|
||||||
mask |= GID_ATTR_FIND_MASK_NETDEV;
|
|
||||||
|
|
||||||
return _ib_cache_gid_table_find(ib_dev, gid, &gid_attr_val,
|
|
||||||
mask, port, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ib_find_cached_gid_by_port - Returns the GID table index where a specified
|
* rdma_find_gid_by_port - Returns the GID entry attributes when it finds
|
||||||
* GID value occurs. It searches for the specified GID value in the local
|
* a valid GID entry for given search parameters. It searches for the specified
|
||||||
* software cache.
|
* GID value in the local software cache.
|
||||||
* @device: The device to query.
|
* @device: The device to query.
|
||||||
* @gid: The GID value to search for.
|
* @gid: The GID value to search for.
|
||||||
* @gid_type: The GID type to search for.
|
* @gid_type: The GID type to search for.
|
||||||
* @port_num: The port number of the device where the GID value should be
|
* @port_num: The port number of the device where the GID value should be
|
||||||
* searched.
|
* searched.
|
||||||
* @ndev: In RoCE, the net device of the device. Null means ignore.
|
* @ndev: In RoCE, the net device of the device. NULL means ignore.
|
||||||
* @index: The index into the cached GID table where the GID was found. This
|
*
|
||||||
* parameter may be NULL.
|
* Returns sgid attributes if the GID is found with valid reference or
|
||||||
|
* returns ERR_PTR for the error.
|
||||||
|
* The caller must invoke rdma_put_gid_attr() to release the reference.
|
||||||
*/
|
*/
|
||||||
int ib_find_cached_gid_by_port(struct ib_device *ib_dev,
|
const struct ib_gid_attr *
|
||||||
const union ib_gid *gid,
|
rdma_find_gid_by_port(struct ib_device *ib_dev,
|
||||||
enum ib_gid_type gid_type,
|
const union ib_gid *gid,
|
||||||
u8 port, struct net_device *ndev,
|
enum ib_gid_type gid_type,
|
||||||
u16 *index)
|
u8 port, struct net_device *ndev)
|
||||||
{
|
{
|
||||||
int local_index;
|
int local_index;
|
||||||
struct ib_gid_table *table;
|
struct ib_gid_table *table;
|
||||||
unsigned long mask = GID_ATTR_FIND_MASK_GID |
|
unsigned long mask = GID_ATTR_FIND_MASK_GID |
|
||||||
GID_ATTR_FIND_MASK_GID_TYPE;
|
GID_ATTR_FIND_MASK_GID_TYPE;
|
||||||
struct ib_gid_attr val = {.ndev = ndev, .gid_type = gid_type};
|
struct ib_gid_attr val = {.ndev = ndev, .gid_type = gid_type};
|
||||||
|
const struct ib_gid_attr *attr;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (!rdma_is_port_valid(ib_dev, port))
|
if (!rdma_is_port_valid(ib_dev, port))
|
||||||
return -ENOENT;
|
return ERR_PTR(-ENOENT);
|
||||||
|
|
||||||
table = rdma_gid_table(ib_dev, port);
|
table = rdma_gid_table(ib_dev, port);
|
||||||
|
|
||||||
|
@ -732,55 +689,49 @@ int ib_find_cached_gid_by_port(struct ib_device *ib_dev,
|
||||||
read_lock_irqsave(&table->rwlock, flags);
|
read_lock_irqsave(&table->rwlock, flags);
|
||||||
local_index = find_gid(table, gid, &val, false, mask, NULL);
|
local_index = find_gid(table, gid, &val, false, mask, NULL);
|
||||||
if (local_index >= 0) {
|
if (local_index >= 0) {
|
||||||
if (index)
|
get_gid_entry(table->data_vec[local_index]);
|
||||||
*index = local_index;
|
attr = &table->data_vec[local_index]->attr;
|
||||||
read_unlock_irqrestore(&table->rwlock, flags);
|
read_unlock_irqrestore(&table->rwlock, flags);
|
||||||
return 0;
|
return attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_unlock_irqrestore(&table->rwlock, flags);
|
read_unlock_irqrestore(&table->rwlock, flags);
|
||||||
return -ENOENT;
|
return ERR_PTR(-ENOENT);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ib_find_cached_gid_by_port);
|
EXPORT_SYMBOL(rdma_find_gid_by_port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ib_cache_gid_find_by_filter - Returns the GID table index where a specified
|
* rdma_find_gid_by_filter - Returns the GID table attribute where a
|
||||||
* GID value occurs
|
* specified GID value occurs
|
||||||
* @device: The device to query.
|
* @device: The device to query.
|
||||||
* @gid: The GID value to search for.
|
* @gid: The GID value to search for.
|
||||||
* @port_num: The port number of the device where the GID value could be
|
* @port: The port number of the device where the GID value could be
|
||||||
* searched.
|
* searched.
|
||||||
* @filter: The filter function is executed on any matching GID in the table.
|
* @filter: The filter function is executed on any matching GID in the table.
|
||||||
* If the filter function returns true, the corresponding index is returned,
|
* If the filter function returns true, the corresponding index is returned,
|
||||||
* otherwise, we continue searching the GID table. It's guaranteed that
|
* otherwise, we continue searching the GID table. It's guaranteed that
|
||||||
* while filter is executed, ndev field is valid and the structure won't
|
* while filter is executed, ndev field is valid and the structure won't
|
||||||
* change. filter is executed in an atomic context. filter must not be NULL.
|
* change. filter is executed in an atomic context. filter must not be NULL.
|
||||||
* @index: The index into the cached GID table where the GID was found. This
|
|
||||||
* parameter may be NULL.
|
|
||||||
*
|
*
|
||||||
* ib_cache_gid_find_by_filter() searches for the specified GID value
|
* rdma_find_gid_by_filter() searches for the specified GID value
|
||||||
* of which the filter function returns true in the port's GID table.
|
* of which the filter function returns true in the port's GID table.
|
||||||
* This function is only supported on RoCE ports.
|
* This function is only supported on RoCE ports.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int ib_cache_gid_find_by_filter(struct ib_device *ib_dev,
|
const struct ib_gid_attr *rdma_find_gid_by_filter(
|
||||||
const union ib_gid *gid,
|
struct ib_device *ib_dev, const union ib_gid *gid, u8 port,
|
||||||
u8 port,
|
bool (*filter)(const union ib_gid *gid, const struct ib_gid_attr *,
|
||||||
bool (*filter)(const union ib_gid *,
|
void *),
|
||||||
const struct ib_gid_attr *,
|
void *context)
|
||||||
void *),
|
|
||||||
void *context,
|
|
||||||
u16 *index)
|
|
||||||
{
|
{
|
||||||
|
const struct ib_gid_attr *res = ERR_PTR(-ENOENT);
|
||||||
struct ib_gid_table *table;
|
struct ib_gid_table *table;
|
||||||
unsigned int i;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
bool found = false;
|
unsigned int i;
|
||||||
|
|
||||||
|
|
||||||
if (!rdma_is_port_valid(ib_dev, port) ||
|
if (!rdma_is_port_valid(ib_dev, port) ||
|
||||||
!rdma_protocol_roce(ib_dev, port))
|
!rdma_protocol_roce(ib_dev, port))
|
||||||
return -EPROTONOSUPPORT;
|
return ERR_PTR(-EPROTONOSUPPORT);
|
||||||
|
|
||||||
table = rdma_gid_table(ib_dev, port);
|
table = rdma_gid_table(ib_dev, port);
|
||||||
|
|
||||||
|
@ -798,19 +749,35 @@ static int ib_cache_gid_find_by_filter(struct ib_device *ib_dev,
|
||||||
memcpy(&attr, &table->data_vec[i]->attr, sizeof(attr));
|
memcpy(&attr, &table->data_vec[i]->attr, sizeof(attr));
|
||||||
|
|
||||||
if (filter(gid, &attr, context)) {
|
if (filter(gid, &attr, context)) {
|
||||||
found = true;
|
get_gid_entry(table->data_vec[i]);
|
||||||
if (index)
|
res = &table->data_vec[i]->attr;
|
||||||
*index = i;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
read_unlock_irqrestore(&table->rwlock, flags);
|
read_unlock_irqrestore(&table->rwlock, flags);
|
||||||
|
return res;
|
||||||
if (!found)
|
|
||||||
return -ENOENT;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ib_find_cached_gid_by_port(struct ib_device *ib_dev,
|
||||||
|
const union ib_gid *gid,
|
||||||
|
enum ib_gid_type gid_type,
|
||||||
|
u8 port, struct net_device *ndev,
|
||||||
|
u16 *index)
|
||||||
|
{
|
||||||
|
const struct ib_gid_attr *res;
|
||||||
|
|
||||||
|
res = rdma_find_gid_by_port(ib_dev, gid, gid_type, port, ndev);
|
||||||
|
if (IS_ERR(res))
|
||||||
|
return PTR_ERR(res);
|
||||||
|
|
||||||
|
if (index)
|
||||||
|
*index = res->index;
|
||||||
|
rdma_put_gid_attr(res);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(ib_find_cached_gid_by_port);
|
||||||
|
|
||||||
static struct ib_gid_table *alloc_gid_table(int sz)
|
static struct ib_gid_table *alloc_gid_table(int sz)
|
||||||
{
|
{
|
||||||
struct ib_gid_table *table = kzalloc(sizeof(*table), GFP_KERNEL);
|
struct ib_gid_table *table = kzalloc(sizeof(*table), GFP_KERNEL);
|
||||||
|
@ -1016,27 +983,109 @@ int ib_get_cached_gid(struct ib_device *device,
|
||||||
EXPORT_SYMBOL(ib_get_cached_gid);
|
EXPORT_SYMBOL(ib_get_cached_gid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ib_find_cached_gid - Returns the port number and GID table index where
|
* rdma_query_gid - Read the GID content from the GID software cache
|
||||||
* a specified GID value occurs.
|
* @device: Device to query the GID
|
||||||
|
* @port_num: Port number of the device
|
||||||
|
* @index: Index of the GID table entry to read
|
||||||
|
* @gid: Pointer to GID where to store the entry's GID
|
||||||
|
*
|
||||||
|
* rdma_query_gid() only reads the GID entry content for requested device,
|
||||||
|
* port and index. It reads for IB, RoCE and iWarp link layers. It doesn't
|
||||||
|
* hold any reference to the GID table entry in the HCA or software cache.
|
||||||
|
*
|
||||||
|
* Returns 0 on success or appropriate error code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int rdma_query_gid(struct ib_device *device, u8 port_num,
|
||||||
|
int index, union ib_gid *gid)
|
||||||
|
{
|
||||||
|
struct ib_gid_table *table;
|
||||||
|
unsigned long flags;
|
||||||
|
int res = -EINVAL;
|
||||||
|
|
||||||
|
if (!rdma_is_port_valid(device, port_num))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
table = rdma_gid_table(device, port_num);
|
||||||
|
read_lock_irqsave(&table->rwlock, flags);
|
||||||
|
|
||||||
|
if (index < 0 || index >= table->sz ||
|
||||||
|
!is_gid_entry_valid(table->data_vec[index]))
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
memcpy(gid, &table->data_vec[index]->attr.gid, sizeof(*gid));
|
||||||
|
res = 0;
|
||||||
|
|
||||||
|
done:
|
||||||
|
read_unlock_irqrestore(&table->rwlock, flags);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rdma_query_gid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rdma_find_gid - Returns SGID attributes if the matching GID is found.
|
||||||
* @device: The device to query.
|
* @device: The device to query.
|
||||||
* @gid: The GID value to search for.
|
* @gid: The GID value to search for.
|
||||||
* @gid_type: The GID type to search for.
|
* @gid_type: The GID type to search for.
|
||||||
* @ndev: In RoCE, the net device of the device. NULL means ignore.
|
* @ndev: In RoCE, the net device of the device. NULL means ignore.
|
||||||
* @port_num: The port number of the device where the GID value was found.
|
|
||||||
* @index: The index into the cached GID table where the GID was found. This
|
|
||||||
* parameter may be NULL.
|
|
||||||
*
|
*
|
||||||
* ib_find_cached_gid() searches for the specified GID value in
|
* rdma_find_gid() searches for the specified GID value in the software cache.
|
||||||
* the local software cache.
|
*
|
||||||
|
* Returns GID attributes if a valid GID is found or returns ERR_PTR for the
|
||||||
|
* error. The caller must invoke rdma_put_gid_attr() to release the reference.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
int ib_find_cached_gid(struct ib_device *device,
|
const struct ib_gid_attr *rdma_find_gid(struct ib_device *device,
|
||||||
const union ib_gid *gid,
|
const union ib_gid *gid,
|
||||||
enum ib_gid_type gid_type,
|
enum ib_gid_type gid_type,
|
||||||
struct net_device *ndev,
|
struct net_device *ndev)
|
||||||
u8 *port_num,
|
|
||||||
u16 *index)
|
|
||||||
{
|
{
|
||||||
return ib_cache_gid_find(device, gid, gid_type, ndev, port_num, index);
|
unsigned long mask = GID_ATTR_FIND_MASK_GID |
|
||||||
|
GID_ATTR_FIND_MASK_GID_TYPE;
|
||||||
|
struct ib_gid_attr gid_attr_val = {.ndev = ndev, .gid_type = gid_type};
|
||||||
|
u8 p;
|
||||||
|
|
||||||
|
if (ndev)
|
||||||
|
mask |= GID_ATTR_FIND_MASK_NETDEV;
|
||||||
|
|
||||||
|
for (p = 0; p < device->phys_port_cnt; p++) {
|
||||||
|
struct ib_gid_table *table;
|
||||||
|
unsigned long flags;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
table = device->cache.ports[p].gid;
|
||||||
|
read_lock_irqsave(&table->rwlock, flags);
|
||||||
|
index = find_gid(table, gid, &gid_attr_val, false, mask, NULL);
|
||||||
|
if (index >= 0) {
|
||||||
|
const struct ib_gid_attr *attr;
|
||||||
|
|
||||||
|
get_gid_entry(table->data_vec[index]);
|
||||||
|
attr = &table->data_vec[index]->attr;
|
||||||
|
read_unlock_irqrestore(&table->rwlock, flags);
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
read_unlock_irqrestore(&table->rwlock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_PTR(-ENOENT);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rdma_find_gid);
|
||||||
|
|
||||||
|
int ib_find_cached_gid(struct ib_device *device, const union ib_gid *gid,
|
||||||
|
enum ib_gid_type gid_type, struct net_device *ndev,
|
||||||
|
u8 *port_num, u16 *index)
|
||||||
|
{
|
||||||
|
const struct ib_gid_attr *res;
|
||||||
|
|
||||||
|
res = rdma_find_gid(device, gid, gid_type, ndev);
|
||||||
|
if (IS_ERR(res))
|
||||||
|
return PTR_ERR(res);
|
||||||
|
if (port_num)
|
||||||
|
*port_num = res->port_num;
|
||||||
|
if (index)
|
||||||
|
*index = res->index;
|
||||||
|
rdma_put_gid_attr(res);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ib_find_cached_gid);
|
EXPORT_SYMBOL(ib_find_cached_gid);
|
||||||
|
|
||||||
|
@ -1048,13 +1097,22 @@ int ib_find_gid_by_filter(struct ib_device *device,
|
||||||
void *),
|
void *),
|
||||||
void *context, u16 *index)
|
void *context, u16 *index)
|
||||||
{
|
{
|
||||||
|
const struct ib_gid_attr *res;
|
||||||
|
|
||||||
/* Only RoCE GID table supports filter function */
|
/* Only RoCE GID table supports filter function */
|
||||||
if (!rdma_protocol_roce(device, port_num) && filter)
|
if (!rdma_protocol_roce(device, port_num) && filter)
|
||||||
return -EPROTONOSUPPORT;
|
return -EPROTONOSUPPORT;
|
||||||
|
|
||||||
return ib_cache_gid_find_by_filter(device, gid,
|
res = rdma_find_gid_by_filter(device, gid, port_num, filter,
|
||||||
port_num, filter,
|
context);
|
||||||
context, index);
|
if (IS_ERR(res))
|
||||||
|
return PTR_ERR(res);
|
||||||
|
|
||||||
|
if (index)
|
||||||
|
*index = res->index;
|
||||||
|
|
||||||
|
rdma_put_gid_attr(res);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ib_get_cached_pkey(struct ib_device *device,
|
int ib_get_cached_pkey(struct ib_device *device,
|
||||||
|
|
|
@ -54,6 +54,8 @@ int ib_get_cached_gid(struct ib_device *device,
|
||||||
int index,
|
int index,
|
||||||
union ib_gid *gid,
|
union ib_gid *gid,
|
||||||
struct ib_gid_attr *attr);
|
struct ib_gid_attr *attr);
|
||||||
|
int rdma_query_gid(struct ib_device *device, u8 port_num, int index,
|
||||||
|
union ib_gid *gid);
|
||||||
|
|
||||||
int ib_find_cached_gid(struct ib_device *device,
|
int ib_find_cached_gid(struct ib_device *device,
|
||||||
const union ib_gid *gid,
|
const union ib_gid *gid,
|
||||||
|
@ -61,6 +63,10 @@ int ib_find_cached_gid(struct ib_device *device,
|
||||||
struct net_device *ndev,
|
struct net_device *ndev,
|
||||||
u8 *port_num,
|
u8 *port_num,
|
||||||
u16 *index);
|
u16 *index);
|
||||||
|
const struct ib_gid_attr *rdma_find_gid(struct ib_device *device,
|
||||||
|
const union ib_gid *gid,
|
||||||
|
enum ib_gid_type gid_type,
|
||||||
|
struct net_device *ndev);
|
||||||
|
|
||||||
int ib_find_cached_gid_by_port(struct ib_device *device,
|
int ib_find_cached_gid_by_port(struct ib_device *device,
|
||||||
const union ib_gid *gid,
|
const union ib_gid *gid,
|
||||||
|
@ -68,6 +74,11 @@ int ib_find_cached_gid_by_port(struct ib_device *device,
|
||||||
u8 port_num,
|
u8 port_num,
|
||||||
struct net_device *ndev,
|
struct net_device *ndev,
|
||||||
u16 *index);
|
u16 *index);
|
||||||
|
const struct ib_gid_attr *rdma_find_gid_by_port(struct ib_device *ib_dev,
|
||||||
|
const union ib_gid *gid,
|
||||||
|
enum ib_gid_type gid_type,
|
||||||
|
u8 port,
|
||||||
|
struct net_device *ndev);
|
||||||
|
|
||||||
int ib_find_gid_by_filter(struct ib_device *device,
|
int ib_find_gid_by_filter(struct ib_device *device,
|
||||||
const union ib_gid *gid,
|
const union ib_gid *gid,
|
||||||
|
@ -76,6 +87,12 @@ int ib_find_gid_by_filter(struct ib_device *device,
|
||||||
const struct ib_gid_attr *,
|
const struct ib_gid_attr *,
|
||||||
void *),
|
void *),
|
||||||
void *context, u16 *index);
|
void *context, u16 *index);
|
||||||
|
const struct ib_gid_attr *rdma_find_gid_by_filter(
|
||||||
|
struct ib_device *device, const union ib_gid *gid, u8 port_num,
|
||||||
|
bool (*filter)(const union ib_gid *gid, const struct ib_gid_attr *,
|
||||||
|
void *),
|
||||||
|
void *context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ib_get_cached_pkey - Returns a cached PKey table entry
|
* ib_get_cached_pkey - Returns a cached PKey table entry
|
||||||
* @device: The device to query.
|
* @device: The device to query.
|
||||||
|
|
Loading…
Reference in New Issue