ib_client.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
  2. /*
  3. * Copyright (c) 2024 Oracle. All rights reserved.
  4. */
  5. /* #include <linux/module.h>
  6. #include <linux/slab.h> */
  7. #include <linux/xarray.h>
  8. #include <linux/types.h>
  9. #include <linux/kref.h>
  10. #include <linux/completion.h>
  11. #include <linux/sunrpc/svc_rdma.h>
  12. #include <linux/sunrpc/rdma_rn.h>
  13. #include "xprt_rdma.h"
  14. #include <trace/events/rpcrdma.h>
  15. /* Per-ib_device private data for rpcrdma */
  16. struct rpcrdma_device {
  17. struct kref rd_kref;
  18. unsigned long rd_flags;
  19. struct ib_device *rd_device;
  20. struct xarray rd_xa;
  21. struct completion rd_done;
  22. };
  23. #define RPCRDMA_RD_F_REMOVING (0)
  24. static struct ib_client rpcrdma_ib_client;
  25. /*
  26. * Listeners have no associated device, so we never register them.
  27. * Note that ib_get_client_data() does not check if @device is
  28. * NULL for us.
  29. */
  30. static struct rpcrdma_device *rpcrdma_get_client_data(struct ib_device *device)
  31. {
  32. if (!device)
  33. return NULL;
  34. return ib_get_client_data(device, &rpcrdma_ib_client);
  35. }
  36. /**
  37. * rpcrdma_rn_register - register to get device removal notifications
  38. * @device: device to monitor
  39. * @rn: notification object that wishes to be notified
  40. * @done: callback to notify caller of device removal
  41. *
  42. * Returns zero on success. The callback in rn_done is guaranteed
  43. * to be invoked when the device is removed, unless this notification
  44. * is unregistered first.
  45. *
  46. * On failure, a negative errno is returned.
  47. */
  48. int rpcrdma_rn_register(struct ib_device *device,
  49. struct rpcrdma_notification *rn,
  50. void (*done)(struct rpcrdma_notification *rn))
  51. {
  52. struct rpcrdma_device *rd = rpcrdma_get_client_data(device);
  53. if (!rd || test_bit(RPCRDMA_RD_F_REMOVING, &rd->rd_flags))
  54. return -ENETUNREACH;
  55. if (xa_alloc(&rd->rd_xa, &rn->rn_index, rn, xa_limit_32b, GFP_KERNEL) < 0)
  56. return -ENOMEM;
  57. kref_get(&rd->rd_kref);
  58. rn->rn_done = done;
  59. trace_rpcrdma_client_register(device, rn);
  60. return 0;
  61. }
  62. static void rpcrdma_rn_release(struct kref *kref)
  63. {
  64. struct rpcrdma_device *rd = container_of(kref, struct rpcrdma_device,
  65. rd_kref);
  66. trace_rpcrdma_client_completion(rd->rd_device);
  67. complete(&rd->rd_done);
  68. }
  69. /**
  70. * rpcrdma_rn_unregister - stop device removal notifications
  71. * @device: monitored device
  72. * @rn: notification object that no longer wishes to be notified
  73. */
  74. void rpcrdma_rn_unregister(struct ib_device *device,
  75. struct rpcrdma_notification *rn)
  76. {
  77. struct rpcrdma_device *rd = rpcrdma_get_client_data(device);
  78. if (!rd)
  79. return;
  80. trace_rpcrdma_client_unregister(device, rn);
  81. xa_erase(&rd->rd_xa, rn->rn_index);
  82. kref_put(&rd->rd_kref, rpcrdma_rn_release);
  83. }
  84. /**
  85. * rpcrdma_add_one - ib_client device insertion callback
  86. * @device: device about to be inserted
  87. *
  88. * Returns zero on success. xprtrdma private data has been allocated
  89. * for this device. On failure, a negative errno is returned.
  90. */
  91. static int rpcrdma_add_one(struct ib_device *device)
  92. {
  93. struct rpcrdma_device *rd;
  94. rd = kzalloc(sizeof(*rd), GFP_KERNEL);
  95. if (!rd)
  96. return -ENOMEM;
  97. kref_init(&rd->rd_kref);
  98. xa_init_flags(&rd->rd_xa, XA_FLAGS_ALLOC);
  99. rd->rd_device = device;
  100. init_completion(&rd->rd_done);
  101. ib_set_client_data(device, &rpcrdma_ib_client, rd);
  102. trace_rpcrdma_client_add_one(device);
  103. return 0;
  104. }
  105. /**
  106. * rpcrdma_remove_one - ib_client device removal callback
  107. * @device: device about to be removed
  108. * @client_data: this module's private per-device data
  109. *
  110. * Upon return, all transports associated with @device have divested
  111. * themselves from IB hardware resources.
  112. */
  113. static void rpcrdma_remove_one(struct ib_device *device,
  114. void *client_data)
  115. {
  116. struct rpcrdma_device *rd = client_data;
  117. struct rpcrdma_notification *rn;
  118. unsigned long index;
  119. trace_rpcrdma_client_remove_one(device);
  120. set_bit(RPCRDMA_RD_F_REMOVING, &rd->rd_flags);
  121. xa_for_each(&rd->rd_xa, index, rn)
  122. rn->rn_done(rn);
  123. /*
  124. * Wait only if there are still outstanding notification
  125. * registrants for this device.
  126. */
  127. if (!refcount_dec_and_test(&rd->rd_kref.refcount)) {
  128. trace_rpcrdma_client_wait_on(device);
  129. wait_for_completion(&rd->rd_done);
  130. }
  131. trace_rpcrdma_client_remove_one_done(device);
  132. xa_destroy(&rd->rd_xa);
  133. kfree(rd);
  134. }
  135. static struct ib_client rpcrdma_ib_client = {
  136. .name = "rpcrdma",
  137. .add = rpcrdma_add_one,
  138. .remove = rpcrdma_remove_one,
  139. };
  140. /**
  141. * rpcrdma_ib_client_unregister - unregister ib_client for xprtrdma
  142. *
  143. * cel: watch for orphaned rpcrdma_device objects on module unload
  144. */
  145. void rpcrdma_ib_client_unregister(void)
  146. {
  147. ib_unregister_client(&rpcrdma_ib_client);
  148. }
  149. /**
  150. * rpcrdma_ib_client_register - register ib_client for rpcrdma
  151. *
  152. * Returns zero on success, or a negative errno.
  153. */
  154. int rpcrdma_ib_client_register(void)
  155. {
  156. return ib_register_client(&rpcrdma_ib_client);
  157. }