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