aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChengguang Xu <cgxu519@icloud.com>2018-02-24 05:36:02 -0500
committerIlya Dryomov <idryomov@gmail.com>2018-04-02 04:12:47 -0400
commit79cd674aed7363a043222af3c8f97d0ea0a078cf (patch)
tree86fe0a19a23723b1b8ef0b0d81ebe18b04c8d4d1
parentb517c1d87faafba0c33a38ffdd551e8b399f0a31 (diff)
ceph: optimizing cap reservation
When caps_avail_count is in a low level, most newly trimmed caps will probably go into ->caps_list and caps_avail_count will be increased. Hence after trimming, should recheck caps_avail_count to effectly reuse newly trimmed caps. Also, when releasing unnecessary caps follow the same rule of ceph_put_cap. Signed-off-by: Chengguang Xu <cgxu519@icloud.com> Reviewed-by: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r--fs/ceph/caps.c88
1 files changed, 59 insertions, 29 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index b9b5c47efd06..25141b6683e9 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -184,36 +184,54 @@ int ceph_reserve_caps(struct ceph_mds_client *mdsc,
184 mdsc->caps_avail_count); 184 mdsc->caps_avail_count);
185 spin_unlock(&mdsc->caps_list_lock); 185 spin_unlock(&mdsc->caps_list_lock);
186 186
187 for (i = have; i < need; i++) { 187 for (i = have; i < need; ) {
188retry:
189 cap = kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS); 188 cap = kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS);
190 if (!cap) { 189 if (cap) {
191 if (!trimmed) { 190 list_add(&cap->caps_item, &newcaps);
192 for (j = 0; j < mdsc->max_sessions; j++) { 191 alloc++;
193 s = __ceph_lookup_mds_session(mdsc, j); 192 i++;
194 if (!s) 193 continue;
195 continue; 194 }
196 mutex_unlock(&mdsc->mutex);
197 195
198 mutex_lock(&s->s_mutex); 196 if (!trimmed) {
199 max_caps = s->s_nr_caps - (need - i); 197 for (j = 0; j < mdsc->max_sessions; j++) {
200 ceph_trim_caps(mdsc, s, max_caps); 198 s = __ceph_lookup_mds_session(mdsc, j);
201 mutex_unlock(&s->s_mutex); 199 if (!s)
200 continue;
201 mutex_unlock(&mdsc->mutex);
202 202
203 ceph_put_mds_session(s); 203 mutex_lock(&s->s_mutex);
204 mutex_lock(&mdsc->mutex); 204 max_caps = s->s_nr_caps - (need - i);
205 } 205 ceph_trim_caps(mdsc, s, max_caps);
206 trimmed = true; 206 mutex_unlock(&s->s_mutex);
207 goto retry; 207
208 } else { 208 ceph_put_mds_session(s);
209 pr_warn("reserve caps ctx=%p ENOMEM " 209 mutex_lock(&mdsc->mutex);
210 "need=%d got=%d\n",
211 ctx, need, have + alloc);
212 goto out_nomem;
213 } 210 }
211 trimmed = true;
212
213 spin_lock(&mdsc->caps_list_lock);
214 if (mdsc->caps_avail_count) {
215 int more_have;
216 if (mdsc->caps_avail_count >= need - i)
217 more_have = need - i;
218 else
219 more_have = mdsc->caps_avail_count;
220
221 i += more_have;
222 have += more_have;
223 mdsc->caps_avail_count -= more_have;
224 mdsc->caps_reserve_count += more_have;
225
226 }
227 spin_unlock(&mdsc->caps_list_lock);
228
229 continue;
214 } 230 }
215 list_add(&cap->caps_item, &newcaps); 231
216 alloc++; 232 pr_warn("reserve caps ctx=%p ENOMEM need=%d got=%d\n",
233 ctx, need, have + alloc);
234 goto out_nomem;
217 } 235 }
218 BUG_ON(have + alloc != need); 236 BUG_ON(have + alloc != need);
219 237
@@ -234,16 +252,28 @@ retry:
234 return 0; 252 return 0;
235 253
236out_nomem: 254out_nomem:
255
256 spin_lock(&mdsc->caps_list_lock);
257 mdsc->caps_avail_count += have;
258 mdsc->caps_reserve_count -= have;
259
237 while (!list_empty(&newcaps)) { 260 while (!list_empty(&newcaps)) {
238 cap = list_first_entry(&newcaps, 261 cap = list_first_entry(&newcaps,
239 struct ceph_cap, caps_item); 262 struct ceph_cap, caps_item);
240 list_del(&cap->caps_item); 263 list_del(&cap->caps_item);
241 kmem_cache_free(ceph_cap_cachep, cap); 264
265 /* Keep some preallocated caps around (ceph_min_count), to
266 * avoid lots of free/alloc churn. */
267 if (mdsc->caps_avail_count >=
268 mdsc->caps_reserve_count + mdsc->caps_min_count) {
269 kmem_cache_free(ceph_cap_cachep, cap);
270 } else {
271 mdsc->caps_avail_count++;
272 mdsc->caps_total_count++;
273 list_add(&cap->caps_item, &mdsc->caps_list);
274 }
242 } 275 }
243 276
244 spin_lock(&mdsc->caps_list_lock);
245 mdsc->caps_avail_count += have;
246 mdsc->caps_reserve_count -= have;
247 BUG_ON(mdsc->caps_total_count != mdsc->caps_use_count + 277 BUG_ON(mdsc->caps_total_count != mdsc->caps_use_count +
248 mdsc->caps_reserve_count + 278 mdsc->caps_reserve_count +
249 mdsc->caps_avail_count); 279 mdsc->caps_avail_count);