diff options
author | Sean Hefty <sean.hefty@intel.com> | 2007-02-15 20:00:17 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-02-16 17:20:02 -0500 |
commit | faec2f7b96b555055d0aa6cc6b83a537270bed52 (patch) | |
tree | 0916cb780a1a5d5fe2ac98364917c79f25d57fcf /include | |
parent | 8a2e65f87c66ab1e720f49378750cdd800f9e9cf (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 'include')
-rw-r--r-- | include/rdma/ib_addr.h | 6 | ||||
-rw-r--r-- | include/rdma/ib_sa.h | 159 |
2 files changed, 74 insertions, 91 deletions
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index c094e5012862..c36750ff6ae8 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h | |||
@@ -110,6 +110,12 @@ static inline void ib_addr_set_pkey(struct rdma_dev_addr *dev_addr, u16 pkey) | |||
110 | dev_addr->broadcast[9] = (unsigned char) pkey; | 110 | dev_addr->broadcast[9] = (unsigned char) pkey; |
111 | } | 111 | } |
112 | 112 | ||
113 | static inline void ib_addr_get_mgid(struct rdma_dev_addr *dev_addr, | ||
114 | union ib_gid *gid) | ||
115 | { | ||
116 | memcpy(gid, dev_addr->broadcast + 4, sizeof *gid); | ||
117 | } | ||
118 | |||
113 | static inline void ib_addr_get_sgid(struct rdma_dev_addr *dev_addr, | 119 | static inline void ib_addr_get_sgid(struct rdma_dev_addr *dev_addr, |
114 | union ib_gid *gid) | 120 | union ib_gid *gid) |
115 | { | 121 | { |
diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h index 97715b0c20b6..5e26b2f53f86 100644 --- a/include/rdma/ib_sa.h +++ b/include/rdma/ib_sa.h | |||
@@ -285,18 +285,6 @@ int ib_sa_path_rec_get(struct ib_sa_client *client, | |||
285 | void *context, | 285 | void *context, |
286 | struct ib_sa_query **query); | 286 | struct ib_sa_query **query); |
287 | 287 | ||
288 | int ib_sa_mcmember_rec_query(struct ib_sa_client *client, | ||
289 | struct ib_device *device, u8 port_num, | ||
290 | u8 method, | ||
291 | struct ib_sa_mcmember_rec *rec, | ||
292 | ib_sa_comp_mask comp_mask, | ||
293 | int timeout_ms, gfp_t gfp_mask, | ||
294 | void (*callback)(int status, | ||
295 | struct ib_sa_mcmember_rec *resp, | ||
296 | void *context), | ||
297 | void *context, | ||
298 | struct ib_sa_query **query); | ||
299 | |||
300 | int ib_sa_service_rec_query(struct ib_sa_client *client, | 288 | int ib_sa_service_rec_query(struct ib_sa_client *client, |
301 | struct ib_device *device, u8 port_num, | 289 | struct ib_device *device, u8 port_num, |
302 | u8 method, | 290 | u8 method, |
@@ -309,93 +297,82 @@ int ib_sa_service_rec_query(struct ib_sa_client *client, | |||
309 | void *context, | 297 | void *context, |
310 | struct ib_sa_query **sa_query); | 298 | struct ib_sa_query **sa_query); |
311 | 299 | ||
300 | struct ib_sa_multicast { | ||
301 | struct ib_sa_mcmember_rec rec; | ||
302 | ib_sa_comp_mask comp_mask; | ||
303 | int (*callback)(int status, | ||
304 | struct ib_sa_multicast *multicast); | ||
305 | void *context; | ||
306 | }; | ||
307 | |||
312 | /** | 308 | /** |
313 | * ib_sa_mcmember_rec_set - Start an MCMember set query | 309 | * ib_sa_join_multicast - Initiates a join request to the specified multicast |
314 | * @client:SA client | 310 | * group. |
315 | * @device:device to send query on | 311 | * @client: SA client |
316 | * @port_num: port number to send query on | 312 | * @device: Device associated with the multicast group. |
317 | * @rec:MCMember Record to send in query | 313 | * @port_num: Port on the specified device to associate with the multicast |
318 | * @comp_mask:component mask to send in query | 314 | * group. |
319 | * @timeout_ms:time to wait for response | 315 | * @rec: SA multicast member record specifying group attributes. |
320 | * @gfp_mask:GFP mask to use for internal allocations | 316 | * @comp_mask: Component mask indicating which group attributes of %rec are |
321 | * @callback:function called when query completes, times out or is | 317 | * valid. |
322 | * canceled | 318 | * @gfp_mask: GFP mask for memory allocations. |
323 | * @context:opaque user context passed to callback | 319 | * @callback: User callback invoked once the join operation completes. |
324 | * @sa_query:query context, used to cancel query | 320 | * @context: User specified context stored with the ib_sa_multicast structure. |
325 | * | 321 | * |
326 | * Send an MCMember Set query to the SA (eg to join a multicast | 322 | * This call initiates a multicast join request with the SA for the specified |
327 | * group). The callback function will be called when the query | 323 | * multicast group. If the join operation is started successfully, it returns |
328 | * completes (or fails); status is 0 for a successful response, -EINTR | 324 | * an ib_sa_multicast structure that is used to track the multicast operation. |
329 | * if the query is canceled, -ETIMEDOUT is the query timed out, or | 325 | * Users must free this structure by calling ib_free_multicast, even if the |
330 | * -EIO if an error occurred sending the query. The resp parameter of | 326 | * join operation later fails. (The callback status is non-zero.) |
331 | * the callback is only valid if status is 0. | ||
332 | * | 327 | * |
333 | * If the return value of ib_sa_mcmember_rec_set() is negative, it is | 328 | * If the join operation fails; status will be non-zero, with the following |
334 | * an error code. Otherwise it is a query ID that can be used to | 329 | * failures possible: |
335 | * cancel the query. | 330 | * -ETIMEDOUT: The request timed out. |
331 | * -EIO: An error occurred sending the query. | ||
332 | * -EINVAL: The MCMemberRecord values differed from the existing group's. | ||
333 | * -ENETRESET: Indicates that an fatal error has occurred on the multicast | ||
334 | * group, and the user must rejoin the group to continue using it. | ||
336 | */ | 335 | */ |
337 | static inline int | 336 | struct ib_sa_multicast *ib_sa_join_multicast(struct ib_sa_client *client, |
338 | ib_sa_mcmember_rec_set(struct ib_sa_client *client, | 337 | struct ib_device *device, u8 port_num, |
339 | struct ib_device *device, u8 port_num, | 338 | struct ib_sa_mcmember_rec *rec, |
340 | struct ib_sa_mcmember_rec *rec, | 339 | ib_sa_comp_mask comp_mask, gfp_t gfp_mask, |
341 | ib_sa_comp_mask comp_mask, | 340 | int (*callback)(int status, |
342 | int timeout_ms, gfp_t gfp_mask, | 341 | struct ib_sa_multicast |
343 | void (*callback)(int status, | 342 | *multicast), |
344 | struct ib_sa_mcmember_rec *resp, | 343 | void *context); |
345 | void *context), | ||
346 | void *context, | ||
347 | struct ib_sa_query **query) | ||
348 | { | ||
349 | return ib_sa_mcmember_rec_query(client, device, port_num, | ||
350 | IB_MGMT_METHOD_SET, | ||
351 | rec, comp_mask, | ||
352 | timeout_ms, gfp_mask, callback, | ||
353 | context, query); | ||
354 | } | ||
355 | 344 | ||
356 | /** | 345 | /** |
357 | * ib_sa_mcmember_rec_delete - Start an MCMember delete query | 346 | * ib_free_multicast - Frees the multicast tracking structure, and releases |
358 | * @client:SA client | 347 | * any reference on the multicast group. |
359 | * @device:device to send query on | 348 | * @multicast: Multicast tracking structure allocated by ib_join_multicast. |
360 | * @port_num: port number to send query on | ||
361 | * @rec:MCMember Record to send in query | ||
362 | * @comp_mask:component mask to send in query | ||
363 | * @timeout_ms:time to wait for response | ||
364 | * @gfp_mask:GFP mask to use for internal allocations | ||
365 | * @callback:function called when query completes, times out or is | ||
366 | * canceled | ||
367 | * @context:opaque user context passed to callback | ||
368 | * @sa_query:query context, used to cancel query | ||
369 | * | ||
370 | * Send an MCMember Delete query to the SA (eg to leave a multicast | ||
371 | * group). The callback function will be called when the query | ||
372 | * completes (or fails); status is 0 for a successful response, -EINTR | ||
373 | * if the query is canceled, -ETIMEDOUT is the query timed out, or | ||
374 | * -EIO if an error occurred sending the query. The resp parameter of | ||
375 | * the callback is only valid if status is 0. | ||
376 | * | 349 | * |
377 | * If the return value of ib_sa_mcmember_rec_delete() is negative, it | 350 | * This call blocks until the multicast identifier is destroyed. It may |
378 | * is an error code. Otherwise it is a query ID that can be used to | 351 | * not be called from within the multicast callback; however, returning a non- |
379 | * cancel the query. | 352 | * zero value from the callback will result in destroying the multicast |
353 | * tracking structure. | ||
354 | */ | ||
355 | void ib_sa_free_multicast(struct ib_sa_multicast *multicast); | ||
356 | |||
357 | /** | ||
358 | * ib_get_mcmember_rec - Looks up a multicast member record by its MGID and | ||
359 | * returns it if found. | ||
360 | * @device: Device associated with the multicast group. | ||
361 | * @port_num: Port on the specified device to associate with the multicast | ||
362 | * group. | ||
363 | * @mgid: MGID of multicast group. | ||
364 | * @rec: Location to copy SA multicast member record. | ||
380 | */ | 365 | */ |
381 | static inline int | 366 | int ib_sa_get_mcmember_rec(struct ib_device *device, u8 port_num, |
382 | ib_sa_mcmember_rec_delete(struct ib_sa_client *client, | 367 | union ib_gid *mgid, struct ib_sa_mcmember_rec *rec); |
383 | struct ib_device *device, u8 port_num, | 368 | |
384 | struct ib_sa_mcmember_rec *rec, | 369 | /** |
385 | ib_sa_comp_mask comp_mask, | 370 | * ib_init_ah_from_mcmember - Initialize address handle attributes based on |
386 | int timeout_ms, gfp_t gfp_mask, | 371 | * an SA multicast member record. |
387 | void (*callback)(int status, | 372 | */ |
388 | struct ib_sa_mcmember_rec *resp, | 373 | int ib_init_ah_from_mcmember(struct ib_device *device, u8 port_num, |
389 | void *context), | 374 | struct ib_sa_mcmember_rec *rec, |
390 | void *context, | 375 | struct ib_ah_attr *ah_attr); |
391 | struct ib_sa_query **query) | ||
392 | { | ||
393 | return ib_sa_mcmember_rec_query(client, device, port_num, | ||
394 | IB_SA_METHOD_DELETE, | ||
395 | rec, comp_mask, | ||
396 | timeout_ms, gfp_mask, callback, | ||
397 | context, query); | ||
398 | } | ||
399 | 376 | ||
400 | /** | 377 | /** |
401 | * ib_init_ah_from_path - Initialize address handle attributes based on an SA | 378 | * ib_init_ah_from_path - Initialize address handle attributes based on an SA |