aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/sa_query.c
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2007-02-15 20:00:17 -0500
committerRoland Dreier <rolandd@cisco.com>2007-02-16 17:20:02 -0500
commitfaec2f7b96b555055d0aa6cc6b83a537270bed52 (patch)
tree0916cb780a1a5d5fe2ac98364917c79f25d57fcf /drivers/infiniband/core/sa_query.c
parent8a2e65f87c66ab1e720f49378750cdd800f9e9cf (diff)
IB/sa: Track multicast join/leave requests
The IB SA tracks multicast join/leave requests on a per port basis and does not do any reference counting: if two users of the same port join the same group, and one leaves that group, then the SA will remove the port from the group even though there is one user who wants to stay a member left. Therefore, in order to support multiple users of the same multicast group from the same port, we need to perform reference counting locally. To do this, add an multicast submodule to ib_sa to perform reference counting of multicast join/leave operations. Modify ib_ipoib (the only in-kernel user of multicast) to use the new interface. Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/core/sa_query.c')
-rw-r--r--drivers/infiniband/core/sa_query.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index e45afba75341..d7d4a5309ba9 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -47,8 +47,8 @@
47#include <linux/workqueue.h> 47#include <linux/workqueue.h>
48 48
49#include <rdma/ib_pack.h> 49#include <rdma/ib_pack.h>
50#include <rdma/ib_sa.h>
51#include <rdma/ib_cache.h> 50#include <rdma/ib_cache.h>
51#include "sa.h"
52 52
53MODULE_AUTHOR("Roland Dreier"); 53MODULE_AUTHOR("Roland Dreier");
54MODULE_DESCRIPTION("InfiniBand subnet administration query support"); 54MODULE_DESCRIPTION("InfiniBand subnet administration query support");
@@ -425,17 +425,6 @@ void ib_sa_register_client(struct ib_sa_client *client)
425} 425}
426EXPORT_SYMBOL(ib_sa_register_client); 426EXPORT_SYMBOL(ib_sa_register_client);
427 427
428static inline void ib_sa_client_get(struct ib_sa_client *client)
429{
430 atomic_inc(&client->users);
431}
432
433static inline void ib_sa_client_put(struct ib_sa_client *client)
434{
435 if (atomic_dec_and_test(&client->users))
436 complete(&client->comp);
437}
438
439void ib_sa_unregister_client(struct ib_sa_client *client) 428void ib_sa_unregister_client(struct ib_sa_client *client)
440{ 429{
441 ib_sa_client_put(client); 430 ib_sa_client_put(client);
@@ -901,7 +890,6 @@ err1:
901 kfree(query); 890 kfree(query);
902 return ret; 891 return ret;
903} 892}
904EXPORT_SYMBOL(ib_sa_mcmember_rec_query);
905 893
906static void send_handler(struct ib_mad_agent *agent, 894static void send_handler(struct ib_mad_agent *agent,
907 struct ib_mad_send_wc *mad_send_wc) 895 struct ib_mad_send_wc *mad_send_wc)
@@ -1053,14 +1041,27 @@ static int __init ib_sa_init(void)
1053 get_random_bytes(&tid, sizeof tid); 1041 get_random_bytes(&tid, sizeof tid);
1054 1042
1055 ret = ib_register_client(&sa_client); 1043 ret = ib_register_client(&sa_client);
1056 if (ret) 1044 if (ret) {
1057 printk(KERN_ERR "Couldn't register ib_sa client\n"); 1045 printk(KERN_ERR "Couldn't register ib_sa client\n");
1046 goto err1;
1047 }
1048
1049 ret = mcast_init();
1050 if (ret) {
1051 printk(KERN_ERR "Couldn't initialize multicast handling\n");
1052 goto err2;
1053 }
1058 1054
1055 return 0;
1056err2:
1057 ib_unregister_client(&sa_client);
1058err1:
1059 return ret; 1059 return ret;
1060} 1060}
1061 1061
1062static void __exit ib_sa_cleanup(void) 1062static void __exit ib_sa_cleanup(void)
1063{ 1063{
1064 mcast_cleanup();
1064 ib_unregister_client(&sa_client); 1065 ib_unregister_client(&sa_client);
1065 idr_destroy(&query_idr); 1066 idr_destroy(&query_idr);
1066} 1067}