aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2012-05-15 17:07:49 -0400
committerDavid Teigland <teigland@redhat.com>2012-07-16 15:17:52 -0400
commit1d7c484eeb167fc374294e38ae402de4097c8611 (patch)
tree82ed8a279b8f399205a15951c50c22aea67d7323 /fs
parentc04fecb4d9f7753e0cbff7edd03ec68f8721cdce (diff)
dlm: use idr instead of list for recovered rsbs
When a large number of resources are being recovered, a linear search of the recover_list takes a long time. Use an idr in place of a list. Signed-off-by: David Teigland <teigland@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/dlm/dlm_internal.h3
-rw-r--r--fs/dlm/lockspace.c3
-rw-r--r--fs/dlm/rcom.c2
-rw-r--r--fs/dlm/recover.c116
4 files changed, 101 insertions, 23 deletions
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
index 3093207a7684..a5f82d5b3946 100644
--- a/fs/dlm/dlm_internal.h
+++ b/fs/dlm/dlm_internal.h
@@ -288,6 +288,7 @@ struct dlm_rsb {
288 int res_nodeid; 288 int res_nodeid;
289 int res_master_nodeid; 289 int res_master_nodeid;
290 int res_dir_nodeid; 290 int res_dir_nodeid;
291 int res_id; /* for ls_recover_idr */
291 uint32_t res_lvbseq; 292 uint32_t res_lvbseq;
292 uint32_t res_hash; 293 uint32_t res_hash;
293 uint32_t res_bucket; /* rsbtbl */ 294 uint32_t res_bucket; /* rsbtbl */
@@ -587,6 +588,8 @@ struct dlm_ls {
587 struct list_head ls_recover_list; 588 struct list_head ls_recover_list;
588 spinlock_t ls_recover_list_lock; 589 spinlock_t ls_recover_list_lock;
589 int ls_recover_list_count; 590 int ls_recover_list_count;
591 struct idr ls_recover_idr;
592 spinlock_t ls_recover_idr_lock;
590 wait_queue_head_t ls_wait_general; 593 wait_queue_head_t ls_wait_general;
591 struct mutex ls_clear_proc_locks; 594 struct mutex ls_clear_proc_locks;
592 595
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index 065bb75ed609..d4d3b3165c6c 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -565,6 +565,8 @@ static int new_lockspace(const char *name, const char *cluster,
565 565
566 INIT_LIST_HEAD(&ls->ls_recover_list); 566 INIT_LIST_HEAD(&ls->ls_recover_list);
567 spin_lock_init(&ls->ls_recover_list_lock); 567 spin_lock_init(&ls->ls_recover_list_lock);
568 idr_init(&ls->ls_recover_idr);
569 spin_lock_init(&ls->ls_recover_idr_lock);
568 ls->ls_recover_list_count = 0; 570 ls->ls_recover_list_count = 0;
569 ls->ls_local_handle = ls; 571 ls->ls_local_handle = ls;
570 init_waitqueue_head(&ls->ls_wait_general); 572 init_waitqueue_head(&ls->ls_wait_general);
@@ -636,6 +638,7 @@ static int new_lockspace(const char *name, const char *cluster,
636 spin_lock(&lslist_lock); 638 spin_lock(&lslist_lock);
637 list_del(&ls->ls_list); 639 list_del(&ls->ls_list);
638 spin_unlock(&lslist_lock); 640 spin_unlock(&lslist_lock);
641 idr_destroy(&ls->ls_recover_idr);
639 kfree(ls->ls_recover_buf); 642 kfree(ls->ls_recover_buf);
640 out_lkbfree: 643 out_lkbfree:
641 idr_destroy(&ls->ls_lkbidr); 644 idr_destroy(&ls->ls_lkbidr);
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c
index c8c298d81463..87f1a56eab32 100644
--- a/fs/dlm/rcom.c
+++ b/fs/dlm/rcom.c
@@ -325,7 +325,7 @@ int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid)
325 if (error) 325 if (error)
326 goto out; 326 goto out;
327 memcpy(rc->rc_buf, r->res_name, r->res_length); 327 memcpy(rc->rc_buf, r->res_name, r->res_length);
328 rc->rc_id = (unsigned long) r; 328 rc->rc_id = (unsigned long) r->res_id;
329 329
330 send_rcom(ls, mh, rc); 330 send_rcom(ls, mh, rc);
331 out: 331 out:
diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c
index 3c025fe49ad3..ff6f27629a0c 100644
--- a/fs/dlm/recover.c
+++ b/fs/dlm/recover.c
@@ -277,22 +277,6 @@ static void recover_list_del(struct dlm_rsb *r)
277 dlm_put_rsb(r); 277 dlm_put_rsb(r);
278} 278}
279 279
280static struct dlm_rsb *recover_list_find(struct dlm_ls *ls, uint64_t id)
281{
282 struct dlm_rsb *r = NULL;
283
284 spin_lock(&ls->ls_recover_list_lock);
285
286 list_for_each_entry(r, &ls->ls_recover_list, res_recover_list) {
287 if (id == (unsigned long) r)
288 goto out;
289 }
290 r = NULL;
291 out:
292 spin_unlock(&ls->ls_recover_list_lock);
293 return r;
294}
295
296static void recover_list_clear(struct dlm_ls *ls) 280static void recover_list_clear(struct dlm_ls *ls)
297{ 281{
298 struct dlm_rsb *r, *s; 282 struct dlm_rsb *r, *s;
@@ -313,6 +297,94 @@ static void recover_list_clear(struct dlm_ls *ls)
313 spin_unlock(&ls->ls_recover_list_lock); 297 spin_unlock(&ls->ls_recover_list_lock);
314} 298}
315 299
300static int recover_idr_empty(struct dlm_ls *ls)
301{
302 int empty = 1;
303
304 spin_lock(&ls->ls_recover_idr_lock);
305 if (ls->ls_recover_list_count)
306 empty = 0;
307 spin_unlock(&ls->ls_recover_idr_lock);
308
309 return empty;
310}
311
312static int recover_idr_add(struct dlm_rsb *r)
313{
314 struct dlm_ls *ls = r->res_ls;
315 int rv, id;
316
317 rv = idr_pre_get(&ls->ls_recover_idr, GFP_NOFS);
318 if (!rv)
319 return -ENOMEM;
320
321 spin_lock(&ls->ls_recover_idr_lock);
322 if (r->res_id) {
323 spin_unlock(&ls->ls_recover_idr_lock);
324 return -1;
325 }
326 rv = idr_get_new_above(&ls->ls_recover_idr, r, 1, &id);
327 if (rv) {
328 spin_unlock(&ls->ls_recover_idr_lock);
329 return rv;
330 }
331 r->res_id = id;
332 ls->ls_recover_list_count++;
333 dlm_hold_rsb(r);
334 spin_unlock(&ls->ls_recover_idr_lock);
335 return 0;
336}
337
338static void recover_idr_del(struct dlm_rsb *r)
339{
340 struct dlm_ls *ls = r->res_ls;
341
342 spin_lock(&ls->ls_recover_idr_lock);
343 idr_remove(&ls->ls_recover_idr, r->res_id);
344 r->res_id = 0;
345 ls->ls_recover_list_count--;
346 spin_unlock(&ls->ls_recover_idr_lock);
347
348 dlm_put_rsb(r);
349}
350
351static struct dlm_rsb *recover_idr_find(struct dlm_ls *ls, uint64_t id)
352{
353 struct dlm_rsb *r;
354
355 spin_lock(&ls->ls_recover_idr_lock);
356 r = idr_find(&ls->ls_recover_idr, (int)id);
357 spin_unlock(&ls->ls_recover_idr_lock);
358 return r;
359}
360
361static int recover_idr_clear_rsb(int id, void *p, void *data)
362{
363 struct dlm_ls *ls = data;
364 struct dlm_rsb *r = p;
365
366 r->res_id = 0;
367 r->res_recover_locks_count = 0;
368 ls->ls_recover_list_count--;
369
370 dlm_put_rsb(r);
371 return 0;
372}
373
374static void recover_idr_clear(struct dlm_ls *ls)
375{
376 spin_lock(&ls->ls_recover_idr_lock);
377 idr_for_each(&ls->ls_recover_idr, recover_idr_clear_rsb, ls);
378 idr_remove_all(&ls->ls_recover_idr);
379
380 if (ls->ls_recover_list_count != 0) {
381 log_error(ls, "warning: recover_list_count %d",
382 ls->ls_recover_list_count);
383 ls->ls_recover_list_count = 0;
384 }
385 spin_unlock(&ls->ls_recover_idr_lock);
386}
387
316 388
317/* Master recovery: find new master node for rsb's that were 389/* Master recovery: find new master node for rsb's that were
318 mastered on nodes that have been removed. 390 mastered on nodes that have been removed.
@@ -408,7 +480,7 @@ static int recover_master(struct dlm_rsb *r, unsigned int *count)
408 set_new_master(r); 480 set_new_master(r);
409 error = 0; 481 error = 0;
410 } else { 482 } else {
411 recover_list_add(r); 483 recover_idr_add(r);
412 error = dlm_send_rcom_lookup(r, dir_nodeid); 484 error = dlm_send_rcom_lookup(r, dir_nodeid);
413 } 485 }
414 486
@@ -493,10 +565,10 @@ int dlm_recover_masters(struct dlm_ls *ls)
493 565
494 log_debug(ls, "dlm_recover_masters %u of %u", count, total); 566 log_debug(ls, "dlm_recover_masters %u of %u", count, total);
495 567
496 error = dlm_wait_function(ls, &recover_list_empty); 568 error = dlm_wait_function(ls, &recover_idr_empty);
497 out: 569 out:
498 if (error) 570 if (error)
499 recover_list_clear(ls); 571 recover_idr_clear(ls);
500 return error; 572 return error;
501} 573}
502 574
@@ -505,7 +577,7 @@ int dlm_recover_master_reply(struct dlm_ls *ls, struct dlm_rcom *rc)
505 struct dlm_rsb *r; 577 struct dlm_rsb *r;
506 int ret_nodeid, new_master; 578 int ret_nodeid, new_master;
507 579
508 r = recover_list_find(ls, rc->rc_id); 580 r = recover_idr_find(ls, rc->rc_id);
509 if (!r) { 581 if (!r) {
510 log_error(ls, "dlm_recover_master_reply no id %llx", 582 log_error(ls, "dlm_recover_master_reply no id %llx",
511 (unsigned long long)rc->rc_id); 583 (unsigned long long)rc->rc_id);
@@ -524,9 +596,9 @@ int dlm_recover_master_reply(struct dlm_ls *ls, struct dlm_rcom *rc)
524 r->res_nodeid = new_master; 596 r->res_nodeid = new_master;
525 set_new_master(r); 597 set_new_master(r);
526 unlock_rsb(r); 598 unlock_rsb(r);
527 recover_list_del(r); 599 recover_idr_del(r);
528 600
529 if (recover_list_empty(ls)) 601 if (recover_idr_empty(ls))
530 wake_up(&ls->ls_wait_general); 602 wake_up(&ls->ls_wait_general);
531 out: 603 out:
532 return 0; 604 return 0;