1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /****************************************************************************** |
3 | ******************************************************************************* |
4 | ** |
5 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
6 | ** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. |
7 | ** |
8 | ** |
9 | ******************************************************************************* |
10 | ******************************************************************************/ |
11 | |
12 | #include "dlm_internal.h" |
13 | #include "midcomms.h" |
14 | #include "lowcomms.h" |
15 | #include "config.h" |
16 | #include "memory.h" |
17 | #include "ast.h" |
18 | |
19 | static struct kmem_cache *writequeue_cache; |
20 | static struct kmem_cache *mhandle_cache; |
21 | static struct kmem_cache *msg_cache; |
22 | static struct kmem_cache *lkb_cache; |
23 | static struct kmem_cache *rsb_cache; |
24 | static struct kmem_cache *cb_cache; |
25 | |
26 | |
27 | int __init dlm_memory_init(void) |
28 | { |
29 | writequeue_cache = dlm_lowcomms_writequeue_cache_create(); |
30 | if (!writequeue_cache) |
31 | goto out; |
32 | |
33 | mhandle_cache = dlm_midcomms_cache_create(); |
34 | if (!mhandle_cache) |
35 | goto mhandle; |
36 | |
37 | lkb_cache = kmem_cache_create(name: "dlm_lkb" , size: sizeof(struct dlm_lkb), |
38 | align: __alignof__(struct dlm_lkb), flags: 0, NULL); |
39 | if (!lkb_cache) |
40 | goto lkb; |
41 | |
42 | msg_cache = dlm_lowcomms_msg_cache_create(); |
43 | if (!msg_cache) |
44 | goto msg; |
45 | |
46 | rsb_cache = kmem_cache_create(name: "dlm_rsb" , size: sizeof(struct dlm_rsb), |
47 | align: __alignof__(struct dlm_rsb), flags: 0, NULL); |
48 | if (!rsb_cache) |
49 | goto rsb; |
50 | |
51 | cb_cache = kmem_cache_create(name: "dlm_cb" , size: sizeof(struct dlm_callback), |
52 | align: __alignof__(struct dlm_callback), flags: 0, |
53 | NULL); |
54 | if (!cb_cache) |
55 | goto cb; |
56 | |
57 | return 0; |
58 | |
59 | cb: |
60 | kmem_cache_destroy(s: rsb_cache); |
61 | rsb: |
62 | kmem_cache_destroy(s: msg_cache); |
63 | msg: |
64 | kmem_cache_destroy(s: lkb_cache); |
65 | lkb: |
66 | kmem_cache_destroy(s: mhandle_cache); |
67 | mhandle: |
68 | kmem_cache_destroy(s: writequeue_cache); |
69 | out: |
70 | return -ENOMEM; |
71 | } |
72 | |
73 | void dlm_memory_exit(void) |
74 | { |
75 | kmem_cache_destroy(s: writequeue_cache); |
76 | kmem_cache_destroy(s: mhandle_cache); |
77 | kmem_cache_destroy(s: msg_cache); |
78 | kmem_cache_destroy(s: lkb_cache); |
79 | kmem_cache_destroy(s: rsb_cache); |
80 | kmem_cache_destroy(s: cb_cache); |
81 | } |
82 | |
83 | char *dlm_allocate_lvb(struct dlm_ls *ls) |
84 | { |
85 | char *p; |
86 | |
87 | p = kzalloc(size: ls->ls_lvblen, GFP_NOFS); |
88 | return p; |
89 | } |
90 | |
91 | void dlm_free_lvb(char *p) |
92 | { |
93 | kfree(objp: p); |
94 | } |
95 | |
96 | struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls) |
97 | { |
98 | struct dlm_rsb *r; |
99 | |
100 | r = kmem_cache_zalloc(k: rsb_cache, GFP_NOFS); |
101 | return r; |
102 | } |
103 | |
104 | void dlm_free_rsb(struct dlm_rsb *r) |
105 | { |
106 | if (r->res_lvbptr) |
107 | dlm_free_lvb(p: r->res_lvbptr); |
108 | kmem_cache_free(s: rsb_cache, objp: r); |
109 | } |
110 | |
111 | struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls) |
112 | { |
113 | struct dlm_lkb *lkb; |
114 | |
115 | lkb = kmem_cache_zalloc(k: lkb_cache, GFP_NOFS); |
116 | return lkb; |
117 | } |
118 | |
119 | void dlm_free_lkb(struct dlm_lkb *lkb) |
120 | { |
121 | if (test_bit(DLM_DFL_USER_BIT, &lkb->lkb_dflags)) { |
122 | struct dlm_user_args *ua; |
123 | ua = lkb->lkb_ua; |
124 | if (ua) { |
125 | kfree(objp: ua->lksb.sb_lvbptr); |
126 | kfree(objp: ua); |
127 | } |
128 | } |
129 | |
130 | /* drop references if they are set */ |
131 | dlm_callback_set_last_ptr(from: &lkb->lkb_last_cast, NULL); |
132 | dlm_callback_set_last_ptr(from: &lkb->lkb_last_cb, NULL); |
133 | |
134 | kmem_cache_free(s: lkb_cache, objp: lkb); |
135 | } |
136 | |
137 | struct dlm_mhandle *dlm_allocate_mhandle(gfp_t allocation) |
138 | { |
139 | return kmem_cache_alloc(cachep: mhandle_cache, flags: allocation); |
140 | } |
141 | |
142 | void dlm_free_mhandle(struct dlm_mhandle *mhandle) |
143 | { |
144 | kmem_cache_free(s: mhandle_cache, objp: mhandle); |
145 | } |
146 | |
147 | struct writequeue_entry *dlm_allocate_writequeue(void) |
148 | { |
149 | return kmem_cache_alloc(cachep: writequeue_cache, GFP_ATOMIC); |
150 | } |
151 | |
152 | void dlm_free_writequeue(struct writequeue_entry *writequeue) |
153 | { |
154 | kmem_cache_free(s: writequeue_cache, objp: writequeue); |
155 | } |
156 | |
157 | struct dlm_msg *dlm_allocate_msg(gfp_t allocation) |
158 | { |
159 | return kmem_cache_alloc(cachep: msg_cache, flags: allocation); |
160 | } |
161 | |
162 | void dlm_free_msg(struct dlm_msg *msg) |
163 | { |
164 | kmem_cache_free(s: msg_cache, objp: msg); |
165 | } |
166 | |
167 | struct dlm_callback *dlm_allocate_cb(void) |
168 | { |
169 | return kmem_cache_alloc(cachep: cb_cache, GFP_ATOMIC); |
170 | } |
171 | |
172 | void dlm_free_cb(struct dlm_callback *cb) |
173 | { |
174 | kmem_cache_free(s: cb_cache, objp: cb); |
175 | } |
176 | |