msgpool.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/ceph/ceph_debug.h>
  3. #include <linux/err.h>
  4. #include <linux/sched.h>
  5. #include <linux/types.h>
  6. #include <linux/vmalloc.h>
  7. #include <linux/ceph/messenger.h>
  8. #include <linux/ceph/msgpool.h>
  9. static void *msgpool_alloc(gfp_t gfp_mask, void *arg)
  10. {
  11. struct ceph_msgpool *pool = arg;
  12. struct ceph_msg *msg;
  13. msg = ceph_msg_new2(pool->type, pool->front_len, pool->max_data_items,
  14. gfp_mask, true);
  15. if (!msg) {
  16. dout("msgpool_alloc %s failed\n", pool->name);
  17. } else {
  18. dout("msgpool_alloc %s %p\n", pool->name, msg);
  19. msg->pool = pool;
  20. }
  21. return msg;
  22. }
  23. static void msgpool_free(void *element, void *arg)
  24. {
  25. struct ceph_msgpool *pool = arg;
  26. struct ceph_msg *msg = element;
  27. dout("msgpool_release %s %p\n", pool->name, msg);
  28. msg->pool = NULL;
  29. ceph_msg_put(msg);
  30. }
  31. int ceph_msgpool_init(struct ceph_msgpool *pool, int type,
  32. int front_len, int max_data_items, int size,
  33. const char *name)
  34. {
  35. dout("msgpool %s init\n", name);
  36. pool->type = type;
  37. pool->front_len = front_len;
  38. pool->max_data_items = max_data_items;
  39. pool->pool = mempool_create(size, msgpool_alloc, msgpool_free, pool);
  40. if (!pool->pool)
  41. return -ENOMEM;
  42. pool->name = name;
  43. return 0;
  44. }
  45. void ceph_msgpool_destroy(struct ceph_msgpool *pool)
  46. {
  47. dout("msgpool %s destroy\n", pool->name);
  48. mempool_destroy(pool->pool);
  49. }
  50. struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, int front_len,
  51. int max_data_items)
  52. {
  53. struct ceph_msg *msg;
  54. if (front_len > pool->front_len ||
  55. max_data_items > pool->max_data_items) {
  56. pr_warn_ratelimited("%s need %d/%d, pool %s has %d/%d\n",
  57. __func__, front_len, max_data_items, pool->name,
  58. pool->front_len, pool->max_data_items);
  59. WARN_ON_ONCE(1);
  60. /* try to alloc a fresh message */
  61. return ceph_msg_new2(pool->type, front_len, max_data_items,
  62. GFP_NOFS, false);
  63. }
  64. msg = mempool_alloc(pool->pool, GFP_NOFS);
  65. dout("msgpool_get %s %p\n", pool->name, msg);
  66. return msg;
  67. }
  68. void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg)
  69. {
  70. dout("msgpool_put %s %p\n", pool->name, msg);
  71. /* reset msg front_len; user may have changed it */
  72. msg->front.iov_len = pool->front_len;
  73. msg->hdr.front_len = cpu_to_le32(pool->front_len);
  74. msg->data_length = 0;
  75. msg->num_data_items = 0;
  76. kref_init(&msg->kref); /* retake single ref */
  77. mempool_free(msg, pool->pool);
  78. }