aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_actlog.c
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2013-12-20 05:39:48 -0500
committerPhilipp Reisner <philipp.reisner@linbit.com>2014-07-10 12:34:49 -0400
commitc7a58db4e9dc523b18bbfbc3aa311d8308acc293 (patch)
tree0860df4c69658c43adb83bd690b6d54a964ef9f2 /drivers/block/drbd/drbd_actlog.c
parent70df70927b75eb86f12b14167c398b99dc3a56e4 (diff)
drbd: get rid of atomic update on disk bitmap works
Just trigger the occasional lazy bitmap write-out during resync from the central wait_for_work() helper. Previously, during resync, bitmap pages would be written out separately, synchronously, one at a time, at least 8 times each (every 512 bytes worth of bitmap cleared). Now we trigger "merge friendly" bulk write out of all cleared pages every two seconds during resync, and once the resync is finished. Most pages will be written out only once. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_actlog.c')
-rw-r--r--drivers/block/drbd/drbd_actlog.c63
1 files changed, 1 insertions, 62 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index 05a1780ffa85..9c42edf4871b 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -92,12 +92,6 @@ struct __packed al_transaction_on_disk {
92 __be32 context[AL_CONTEXT_PER_TRANSACTION]; 92 __be32 context[AL_CONTEXT_PER_TRANSACTION];
93}; 93};
94 94
95struct update_odbm_work {
96 struct drbd_work w;
97 struct drbd_device *device;
98 unsigned int enr;
99};
100
101struct update_al_work { 95struct update_al_work {
102 struct drbd_work w; 96 struct drbd_work w;
103 struct drbd_device *device; 97 struct drbd_device *device;
@@ -452,15 +446,6 @@ static unsigned int al_extent_to_bm_page(unsigned int al_enr)
452 (AL_EXTENT_SHIFT - BM_BLOCK_SHIFT)); 446 (AL_EXTENT_SHIFT - BM_BLOCK_SHIFT));
453} 447}
454 448
455static unsigned int rs_extent_to_bm_page(unsigned int rs_enr)
456{
457 return rs_enr >>
458 /* bit to page */
459 ((PAGE_SHIFT + 3) -
460 /* resync extent number to bit */
461 (BM_EXT_SHIFT - BM_BLOCK_SHIFT));
462}
463
464static sector_t al_tr_number_to_on_disk_sector(struct drbd_device *device) 449static sector_t al_tr_number_to_on_disk_sector(struct drbd_device *device)
465{ 450{
466 const unsigned int stripes = device->ldev->md.al_stripes; 451 const unsigned int stripes = device->ldev->md.al_stripes;
@@ -682,40 +667,6 @@ int drbd_initialize_al(struct drbd_device *device, void *buffer)
682 return 0; 667 return 0;
683} 668}
684 669
685static int w_update_odbm(struct drbd_work *w, int unused)
686{
687 struct update_odbm_work *udw = container_of(w, struct update_odbm_work, w);
688 struct drbd_device *device = udw->device;
689 struct sib_info sib = { .sib_reason = SIB_SYNC_PROGRESS, };
690
691 if (!get_ldev(device)) {
692 if (__ratelimit(&drbd_ratelimit_state))
693 drbd_warn(device, "Can not update on disk bitmap, local IO disabled.\n");
694 kfree(udw);
695 return 0;
696 }
697
698 drbd_bm_write_page(device, rs_extent_to_bm_page(udw->enr));
699 put_ldev(device);
700
701 kfree(udw);
702
703 if (drbd_bm_total_weight(device) <= device->rs_failed) {
704 switch (device->state.conn) {
705 case C_SYNC_SOURCE: case C_SYNC_TARGET:
706 case C_PAUSED_SYNC_S: case C_PAUSED_SYNC_T:
707 drbd_resync_finished(device);
708 default:
709 /* nothing to do */
710 break;
711 }
712 }
713 drbd_bcast_event(device, &sib);
714
715 return 0;
716}
717
718
719/* ATTENTION. The AL's extents are 4MB each, while the extents in the 670/* ATTENTION. The AL's extents are 4MB each, while the extents in the
720 * resync LRU-cache are 16MB each. 671 * resync LRU-cache are 16MB each.
721 * The caller of this function has to hold an get_ldev() reference. 672 * The caller of this function has to hold an get_ldev() reference.
@@ -726,8 +677,6 @@ static void drbd_try_clear_on_disk_bm(struct drbd_device *device, sector_t secto
726 int count, int success) 677 int count, int success)
727{ 678{
728 struct lc_element *e; 679 struct lc_element *e;
729 struct update_odbm_work *udw;
730
731 unsigned int enr; 680 unsigned int enr;
732 681
733 D_ASSERT(device, atomic_read(&device->local_cnt)); 682 D_ASSERT(device, atomic_read(&device->local_cnt));
@@ -791,17 +740,7 @@ static void drbd_try_clear_on_disk_bm(struct drbd_device *device, sector_t secto
791 740
792 if (ext->rs_left == ext->rs_failed) { 741 if (ext->rs_left == ext->rs_failed) {
793 ext->rs_failed = 0; 742 ext->rs_failed = 0;
794 743 wake_up(&first_peer_device(device)->connection->sender_work.q_wait);
795 udw = kmalloc(sizeof(*udw), GFP_ATOMIC);
796 if (udw) {
797 udw->enr = ext->lce.lc_number;
798 udw->w.cb = w_update_odbm;
799 udw->device = device;
800 drbd_queue_work_front(&first_peer_device(device)->connection->sender_work,
801 &udw->w);
802 } else {
803 drbd_warn(device, "Could not kmalloc an udw\n");
804 }
805 } 744 }
806 } else { 745 } else {
807 drbd_err(device, "lc_get() failed! locked=%d/%d flags=%lu\n", 746 drbd_err(device, "lc_get() failed! locked=%d/%d flags=%lu\n",