diff options
author | Matan Barak <matanb@mellanox.com> | 2015-10-15 11:38:50 -0400 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2015-10-21 23:48:17 -0400 |
commit | 99b27e3b5da0871cb43980960fb14ff625adffad (patch) | |
tree | d34bd4b4fc3e5eddbf819beb67924e6338131b33 | |
parent | abae1b71dd37bab506b14a6cf6ba7148f4d57232 (diff) |
IB/cache: Add ib_find_gid_by_filter cache API
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>
-rw-r--r-- | drivers/infiniband/core/cache.c | 93 | ||||
-rw-r--r-- | include/rdma/ib_cache.h | 8 |
2 files changed, 101 insertions, 0 deletions
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index 639a7266bfaf..89bebeada38b 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c | |||
@@ -440,6 +440,81 @@ int ib_find_cached_gid_by_port(struct ib_device *ib_dev, | |||
440 | } | 440 | } |
441 | EXPORT_SYMBOL(ib_find_cached_gid_by_port); | 441 | EXPORT_SYMBOL(ib_find_cached_gid_by_port); |
442 | 442 | ||
443 | /** | ||
444 | * ib_find_gid_by_filter - Returns the GID table index where a specified | ||
445 | * GID value occurs | ||
446 | * @device: The device to query. | ||
447 | * @gid: The GID value to search for. | ||
448 | * @port_num: The port number of the device where the GID value could be | ||
449 | * searched. | ||
450 | * @filter: The filter function is executed on any matching GID in the table. | ||
451 | * If the filter function returns true, the corresponding index is returned, | ||
452 | * otherwise, we continue searching the GID table. It's guaranteed that | ||
453 | * while filter is executed, ndev field is valid and the structure won't | ||
454 | * change. filter is executed in an atomic context. filter must not be NULL. | ||
455 | * @index: The index into the cached GID table where the GID was found. This | ||
456 | * parameter may be NULL. | ||
457 | * | ||
458 | * ib_cache_gid_find_by_filter() searches for the specified GID value | ||
459 | * of which the filter function returns true in the port's GID table. | ||
460 | * This function is only supported on RoCE ports. | ||
461 | * | ||
462 | */ | ||
463 | static int ib_cache_gid_find_by_filter(struct ib_device *ib_dev, | ||
464 | const union ib_gid *gid, | ||
465 | u8 port, | ||
466 | bool (*filter)(const union ib_gid *, | ||
467 | const struct ib_gid_attr *, | ||
468 | void *), | ||
469 | void *context, | ||
470 | u16 *index) | ||
471 | { | ||
472 | struct ib_gid_table **ports_table = ib_dev->cache.gid_cache; | ||
473 | struct ib_gid_table *table; | ||
474 | unsigned int i; | ||
475 | bool found = false; | ||
476 | |||
477 | if (!ports_table) | ||
478 | return -EOPNOTSUPP; | ||
479 | |||
480 | if (port < rdma_start_port(ib_dev) || | ||
481 | port > rdma_end_port(ib_dev) || | ||
482 | !rdma_protocol_roce(ib_dev, port)) | ||
483 | return -EPROTONOSUPPORT; | ||
484 | |||
485 | table = ports_table[port - rdma_start_port(ib_dev)]; | ||
486 | |||
487 | for (i = 0; i < table->sz; i++) { | ||
488 | struct ib_gid_attr attr; | ||
489 | unsigned long flags; | ||
490 | |||
491 | read_lock_irqsave(&table->data_vec[i].lock, flags); | ||
492 | if (table->data_vec[i].props & GID_TABLE_ENTRY_INVALID) | ||
493 | goto next; | ||
494 | |||
495 | if (memcmp(gid, &table->data_vec[i].gid, sizeof(*gid))) | ||
496 | goto next; | ||
497 | |||
498 | memcpy(&attr, &table->data_vec[i].attr, sizeof(attr)); | ||
499 | |||
500 | if (filter(gid, &attr, context)) | ||
501 | found = true; | ||
502 | |||
503 | next: | ||
504 | read_unlock_irqrestore(&table->data_vec[i].lock, flags); | ||
505 | |||
506 | if (found) | ||
507 | break; | ||
508 | } | ||
509 | |||
510 | if (!found) | ||
511 | return -ENOENT; | ||
512 | |||
513 | if (index) | ||
514 | *index = i; | ||
515 | return 0; | ||
516 | } | ||
517 | |||
443 | static struct ib_gid_table *alloc_gid_table(int sz) | 518 | static struct ib_gid_table *alloc_gid_table(int sz) |
444 | { | 519 | { |
445 | unsigned int i; | 520 | unsigned int i; |
@@ -670,6 +745,24 @@ int ib_find_cached_gid(struct ib_device *device, | |||
670 | } | 745 | } |
671 | EXPORT_SYMBOL(ib_find_cached_gid); | 746 | EXPORT_SYMBOL(ib_find_cached_gid); |
672 | 747 | ||
748 | int ib_find_gid_by_filter(struct ib_device *device, | ||
749 | const union ib_gid *gid, | ||
750 | u8 port_num, | ||
751 | bool (*filter)(const union ib_gid *gid, | ||
752 | const struct ib_gid_attr *, | ||
753 | void *), | ||
754 | void *context, u16 *index) | ||
755 | { | ||
756 | /* Only RoCE GID table supports filter function */ | ||
757 | if (!rdma_cap_roce_gid_table(device, port_num) && filter) | ||
758 | return -EPROTONOSUPPORT; | ||
759 | |||
760 | return ib_cache_gid_find_by_filter(device, gid, | ||
761 | port_num, filter, | ||
762 | context, index); | ||
763 | } | ||
764 | EXPORT_SYMBOL(ib_find_gid_by_filter); | ||
765 | |||
673 | int ib_get_cached_pkey(struct ib_device *device, | 766 | int ib_get_cached_pkey(struct ib_device *device, |
674 | u8 port_num, | 767 | u8 port_num, |
675 | int index, | 768 | int index, |
diff --git a/include/rdma/ib_cache.h b/include/rdma/ib_cache.h index 679d7ca6a3ee..269a27cf0a46 100644 --- a/include/rdma/ib_cache.h +++ b/include/rdma/ib_cache.h | |||
@@ -93,6 +93,14 @@ int ib_find_cached_gid_by_port(struct ib_device *device, | |||
93 | u8 port_num, | 93 | u8 port_num, |
94 | struct net_device *ndev, | 94 | struct net_device *ndev, |
95 | u16 *index); | 95 | u16 *index); |
96 | |||
97 | int ib_find_gid_by_filter(struct ib_device *device, | ||
98 | const union ib_gid *gid, | ||
99 | u8 port_num, | ||
100 | bool (*filter)(const union ib_gid *gid, | ||
101 | const struct ib_gid_attr *, | ||
102 | void *), | ||
103 | void *context, u16 *index); | ||
96 | /** | 104 | /** |
97 | * ib_get_cached_pkey - Returns a cached PKey table entry | 105 | * ib_get_cached_pkey - Returns a cached PKey table entry |
98 | * @device: The device to query. | 106 | * @device: The device to query. |