msgpool.c 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #include "ceph_debug.h"
  2. #include <linux/err.h>
  3. #include <linux/sched.h>
  4. #include <linux/types.h>
  5. #include <linux/vmalloc.h>
  6. #include "msgpool.h"
  7. static void *alloc_fn(gfp_t gfp_mask, void *arg)
  8. {
  9. struct ceph_msgpool *pool = arg;
  10. return ceph_msg_new(0, pool->front_len);
  11. }
  12. static void free_fn(void *element, void *arg)
  13. {
  14. ceph_msg_put(element);
  15. }
  16. int ceph_msgpool_init(struct ceph_msgpool *pool,
  17. int front_len, int size, bool blocking)
  18. {
  19. pool->front_len = front_len;
  20. pool->pool = mempool_create(size, alloc_fn, free_fn, pool);
  21. if (!pool->pool)
  22. return -ENOMEM;
  23. return 0;
  24. }
  25. void ceph_msgpool_destroy(struct ceph_msgpool *pool)
  26. {
  27. mempool_destroy(pool->pool);
  28. }
  29. struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool,
  30. int front_len)
  31. {
  32. if (front_len > pool->front_len) {
  33. pr_err("msgpool_get pool %p need front %d, pool size is %d\n",
  34. pool, front_len, pool->front_len);
  35. WARN_ON(1);
  36. /* try to alloc a fresh message */
  37. return ceph_msg_new(0, front_len);
  38. }
  39. return mempool_alloc(pool->pool, GFP_NOFS);
  40. }
  41. void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg)
  42. {
  43. /* reset msg front_len; user may have changed it */
  44. msg->front.iov_len = pool->front_len;
  45. msg->hdr.front_len = cpu_to_le32(pool->front_len);
  46. kref_init(&msg->kref); /* retake single ref */
  47. }