Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/net/ceph/msgpool.c
26285 views
1
// SPDX-License-Identifier: GPL-2.0
2
#include <linux/ceph/ceph_debug.h>
3
4
#include <linux/err.h>
5
#include <linux/sched.h>
6
#include <linux/types.h>
7
#include <linux/vmalloc.h>
8
9
#include <linux/ceph/messenger.h>
10
#include <linux/ceph/msgpool.h>
11
12
static void *msgpool_alloc(gfp_t gfp_mask, void *arg)
13
{
14
struct ceph_msgpool *pool = arg;
15
struct ceph_msg *msg;
16
17
msg = ceph_msg_new2(pool->type, pool->front_len, pool->max_data_items,
18
gfp_mask, true);
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;
26
}
27
28
static void msgpool_free(void *element, void *arg)
29
{
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);
36
}
37
38
int ceph_msgpool_init(struct ceph_msgpool *pool, int type,
39
int front_len, int max_data_items, int size,
40
const char *name)
41
{
42
dout("msgpool %s init\n", name);
43
pool->type = type;
44
pool->front_len = front_len;
45
pool->max_data_items = max_data_items;
46
pool->pool = mempool_create(size, msgpool_alloc, msgpool_free, pool);
47
if (!pool->pool)
48
return -ENOMEM;
49
pool->name = name;
50
return 0;
51
}
52
53
void ceph_msgpool_destroy(struct ceph_msgpool *pool)
54
{
55
dout("msgpool %s destroy\n", pool->name);
56
mempool_destroy(pool->pool);
57
}
58
59
struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, int front_len,
60
int max_data_items)
61
{
62
struct ceph_msg *msg;
63
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);
69
WARN_ON_ONCE(1);
70
71
/* try to alloc a fresh message */
72
return ceph_msg_new2(pool->type, front_len, max_data_items,
73
GFP_NOFS, false);
74
}
75
76
msg = mempool_alloc(pool->pool, GFP_NOFS);
77
dout("msgpool_get %s %p\n", pool->name, msg);
78
return msg;
79
}
80
81
void ceph_msgpool_put(struct ceph_msgpool *pool, struct ceph_msg *msg)
82
{
83
dout("msgpool_put %s %p\n", pool->name, msg);
84
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);
88
89
msg->data_length = 0;
90
msg->num_data_items = 0;
91
92
kref_init(&msg->kref); /* retake single ref */
93
mempool_free(msg, pool->pool);
94
}
95
96