]>
Commit | Line | Data |
---|---|---|
3d14c5d2 | 1 | #include <linux/ceph/ceph_debug.h> |
8fc91fd8 SW |
2 | |
3 | #include <linux/err.h> | |
4 | #include <linux/sched.h> | |
5 | #include <linux/types.h> | |
6 | #include <linux/vmalloc.h> | |
7 | ||
3d14c5d2 | 8 | #include <linux/ceph/msgpool.h> |
8fc91fd8 | 9 | |
d52f847a SW |
10 | static void *alloc_fn(gfp_t gfp_mask, void *arg) |
11 | { | |
12 | struct ceph_msgpool *pool = arg; | |
4f48280e | 13 | void *p; |
8fc91fd8 | 14 | |
34d23762 | 15 | p = ceph_msg_new(0, pool->front_len, gfp_mask); |
4f48280e SW |
16 | if (!p) |
17 | pr_err("msgpool %s alloc failed\n", pool->name); | |
18 | return p; | |
d52f847a | 19 | } |
8fc91fd8 | 20 | |
d52f847a | 21 | static void free_fn(void *element, void *arg) |
8fc91fd8 | 22 | { |
d52f847a | 23 | ceph_msg_put(element); |
8fc91fd8 SW |
24 | } |
25 | ||
26 | int ceph_msgpool_init(struct ceph_msgpool *pool, | |
4f48280e | 27 | int front_len, int size, bool blocking, const char *name) |
8fc91fd8 | 28 | { |
8fc91fd8 | 29 | pool->front_len = front_len; |
d52f847a SW |
30 | pool->pool = mempool_create(size, alloc_fn, free_fn, pool); |
31 | if (!pool->pool) | |
32 | return -ENOMEM; | |
4f48280e | 33 | pool->name = name; |
d52f847a | 34 | return 0; |
8fc91fd8 SW |
35 | } |
36 | ||
37 | void ceph_msgpool_destroy(struct ceph_msgpool *pool) | |
38 | { | |
d52f847a | 39 | mempool_destroy(pool->pool); |
8fc91fd8 SW |
40 | } |
41 | ||
d52f847a SW |
42 | struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, |
43 | int front_len) | |
8fc91fd8 | 44 | { |
d52f847a | 45 | if (front_len > pool->front_len) { |
4f48280e SW |
46 | pr_err("msgpool_get pool %s need front %d, pool size is %d\n", |
47 | pool->name, front_len, pool->front_len); | |
8f3bc053 SW |
48 | WARN_ON(1); |
49 | ||
50 | /* try to alloc a fresh message */ | |
34d23762 | 51 | return ceph_msg_new(0, front_len, GFP_NOFS); |
8f3bc053 SW |
52 | } |
53 | ||
d52f847a | 54 | return mempool_alloc(pool->pool, GFP_NOFS); |
8fc91fd8 SW |
55 | } |
56 | ||
57 | void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg) | |
58 | { | |
d52f847a SW |
59 | /* reset msg front_len; user may have changed it */ |
60 | msg->front.iov_len = pool->front_len; | |
61 | msg->hdr.front_len = cpu_to_le32(pool->front_len); | |
3ca02ef9 | 62 | |
d52f847a | 63 | kref_init(&msg->kref); /* retake single ref */ |
8fc91fd8 | 64 | } |