aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/sa_query.c
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2007-02-15 17:00:17 -0800
committerRoland Dreier <rolandd@cisco.com>2007-02-16 14:20:02 -0800
commitfaec2f7b96b555055d0aa6cc6b83a537270bed52 (patch)
tree0916cb780a1a5d5fe2ac98364917c79f25d57fcf /drivers/infiniband/core/sa_query.c
parentIPoIB: CM error handling thinko fix (diff)
downloadlinux-dev-faec2f7b96b555055d0aa6cc6b83a537270bed52.tar.xz
linux-dev-faec2f7b96b555055d0aa6cc6b83a537270bed52.zip
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 @@
#include <linux/workqueue.h>
#include <rdma/ib_pack.h>
-#include <rdma/ib_sa.h>
#include <rdma/ib_cache.h>
+#include "sa.h"
MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("InfiniBand subnet administration query support");
@@ -425,17 +425,6 @@ void ib_sa_register_client(struct ib_sa_client *client)
}
EXPORT_SYMBOL(ib_sa_register_client);
-static inline void ib_sa_client_get(struct ib_sa_client *client)
-{
- atomic_inc(&client->users);
-}
-
-static inline void ib_sa_client_put(struct ib_sa_client *client)
-{
- if (atomic_dec_and_test(&client->users))
- complete(&client->comp);
-}
-
void ib_sa_unregister_client(struct ib_sa_client *client)
{
ib_sa_client_put(client);
@@ -901,7 +890,6 @@ err1:
kfree(query);
return ret;
}
-EXPORT_SYMBOL(ib_sa_mcmember_rec_query);
static void send_handler(struct ib_mad_agent *agent,
struct ib_mad_send_wc *mad_send_wc)
@@ -1053,14 +1041,27 @@ static int __init ib_sa_init(void)
get_random_bytes(&tid, sizeof tid);
ret = ib_register_client(&sa_client);
- if (ret)
+ if (ret) {
printk(KERN_ERR "Couldn't register ib_sa client\n");
+ goto err1;
+ }
+
+ ret = mcast_init();
+ if (ret) {
+ printk(KERN_ERR "Couldn't initialize multicast handling\n");
+ goto err2;
+ }
+ return 0;
+err2:
+ ib_unregister_client(&sa_client);
+err1:
return ret;
}
static void __exit ib_sa_cleanup(void)
{
+ mcast_cleanup();
ib_unregister_client(&sa_client);
idr_destroy(&query_idr);
}