Skip to content

Commit

Permalink
IB/cache: Add ib_find_gid_by_filter cache API
Browse files Browse the repository at this point in the history
GID cache API users might want to search for GIDs with specific
attributes rather than just specifying GID, net device and port.
This is used in a later patch, where we find the sgid index by
L2 Ethernet attributes.

Signed-off-by: Matan Barak <matanb@mellanox.com>
Reviewed-By: Devesh Sharma <devesh.sharma@avagotech.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
  • Loading branch information
Matan Barak authored and Doug Ledford committed Oct 22, 2015
1 parent abae1b7 commit 99b27e3
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
93 changes: 93 additions & 0 deletions drivers/infiniband/core/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,81 @@ int ib_find_cached_gid_by_port(struct ib_device *ib_dev,
}
EXPORT_SYMBOL(ib_find_cached_gid_by_port);

/**
* ib_find_gid_by_filter - Returns the GID table index where a specified
* GID value occurs
* @device: The device to query.
* @gid: The GID value to search for.
* @port_num: The port number of the device where the GID value could be
* searched.
* @filter: The filter function is executed on any matching GID in the table.
* If the filter function returns true, the corresponding index is returned,
* otherwise, we continue searching the GID table. It's guaranteed that
* 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.
* @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
* of which the filter function returns true in the port's GID table.
* This function is only supported on RoCE ports.
*
*/
static int ib_cache_gid_find_by_filter(struct ib_device *ib_dev,
const union ib_gid *gid,
u8 port,
bool (*filter)(const union ib_gid *,
const struct ib_gid_attr *,
void *),
void *context,
u16 *index)
{
struct ib_gid_table **ports_table = ib_dev->cache.gid_cache;
struct ib_gid_table *table;
unsigned int i;
bool found = false;

if (!ports_table)
return -EOPNOTSUPP;

if (port < rdma_start_port(ib_dev) ||
port > rdma_end_port(ib_dev) ||
!rdma_protocol_roce(ib_dev, port))
return -EPROTONOSUPPORT;

table = ports_table[port - rdma_start_port(ib_dev)];

for (i = 0; i < table->sz; i++) {
struct ib_gid_attr attr;
unsigned long flags;

read_lock_irqsave(&table->data_vec[i].lock, flags);
if (table->data_vec[i].props & GID_TABLE_ENTRY_INVALID)
goto next;

if (memcmp(gid, &table->data_vec[i].gid, sizeof(*gid)))
goto next;

memcpy(&attr, &table->data_vec[i].attr, sizeof(attr));

if (filter(gid, &attr, context))
found = true;

next:
read_unlock_irqrestore(&table->data_vec[i].lock, flags);

if (found)
break;
}

if (!found)
return -ENOENT;

if (index)
*index = i;
return 0;
}

static struct ib_gid_table *alloc_gid_table(int sz)
{
unsigned int i;
Expand Down Expand Up @@ -670,6 +745,24 @@ int ib_find_cached_gid(struct ib_device *device,
}
EXPORT_SYMBOL(ib_find_cached_gid);

int ib_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, u16 *index)
{
/* Only RoCE GID table supports filter function */
if (!rdma_cap_roce_gid_table(device, port_num) && filter)
return -EPROTONOSUPPORT;

return ib_cache_gid_find_by_filter(device, gid,
port_num, filter,
context, index);
}
EXPORT_SYMBOL(ib_find_gid_by_filter);

int ib_get_cached_pkey(struct ib_device *device,
u8 port_num,
int index,
Expand Down
8 changes: 8 additions & 0 deletions include/rdma/ib_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ int ib_find_cached_gid_by_port(struct ib_device *device,
u8 port_num,
struct net_device *ndev,
u16 *index);

int ib_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, u16 *index);
/**
* ib_get_cached_pkey - Returns a cached PKey table entry
* @device: The device to query.
Expand Down

0 comments on commit 99b27e3

Please sign in to comment.