aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/drbd/drbd_bitmap.c')
-rw-r--r--drivers/block/drbd/drbd_bitmap.c84
1 files changed, 62 insertions, 22 deletions
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index e5d89f623b90..ab62b81c2ca7 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -96,6 +96,13 @@ struct drbd_bitmap {
96 struct page **bm_pages; 96 struct page **bm_pages;
97 spinlock_t bm_lock; 97 spinlock_t bm_lock;
98 98
99 /* exclusively to be used by __al_write_transaction(),
100 * drbd_bm_mark_for_writeout() and
101 * and drbd_bm_write_hinted() -> bm_rw() called from there.
102 */
103 unsigned int n_bitmap_hints;
104 unsigned int al_bitmap_hints[AL_UPDATES_PER_TRANSACTION];
105
99 /* see LIMITATIONS: above */ 106 /* see LIMITATIONS: above */
100 107
101 unsigned long bm_set; /* nr of set bits; THINK maybe atomic_t? */ 108 unsigned long bm_set; /* nr of set bits; THINK maybe atomic_t? */
@@ -242,6 +249,11 @@ static void bm_set_page_need_writeout(struct page *page)
242 set_bit(BM_PAGE_NEED_WRITEOUT, &page_private(page)); 249 set_bit(BM_PAGE_NEED_WRITEOUT, &page_private(page));
243} 250}
244 251
252void drbd_bm_reset_al_hints(struct drbd_device *device)
253{
254 device->bitmap->n_bitmap_hints = 0;
255}
256
245/** 257/**
246 * drbd_bm_mark_for_writeout() - mark a page with a "hint" to be considered for writeout 258 * drbd_bm_mark_for_writeout() - mark a page with a "hint" to be considered for writeout
247 * @device: DRBD device. 259 * @device: DRBD device.
@@ -253,6 +265,7 @@ static void bm_set_page_need_writeout(struct page *page)
253 */ 265 */
254void drbd_bm_mark_for_writeout(struct drbd_device *device, int page_nr) 266void drbd_bm_mark_for_writeout(struct drbd_device *device, int page_nr)
255{ 267{
268 struct drbd_bitmap *b = device->bitmap;
256 struct page *page; 269 struct page *page;
257 if (page_nr >= device->bitmap->bm_number_of_pages) { 270 if (page_nr >= device->bitmap->bm_number_of_pages) {
258 drbd_warn(device, "BAD: page_nr: %u, number_of_pages: %u\n", 271 drbd_warn(device, "BAD: page_nr: %u, number_of_pages: %u\n",
@@ -260,7 +273,9 @@ void drbd_bm_mark_for_writeout(struct drbd_device *device, int page_nr)
260 return; 273 return;
261 } 274 }
262 page = device->bitmap->bm_pages[page_nr]; 275 page = device->bitmap->bm_pages[page_nr];
263 set_bit(BM_PAGE_HINT_WRITEOUT, &page_private(page)); 276 BUG_ON(b->n_bitmap_hints >= ARRAY_SIZE(b->al_bitmap_hints));
277 if (!test_and_set_bit(BM_PAGE_HINT_WRITEOUT, &page_private(page)))
278 b->al_bitmap_hints[b->n_bitmap_hints++] = page_nr;
264} 279}
265 280
266static int bm_test_page_unchanged(struct page *page) 281static int bm_test_page_unchanged(struct page *page)
@@ -427,8 +442,7 @@ static struct page **bm_realloc_pages(struct drbd_bitmap *b, unsigned long want)
427} 442}
428 443
429/* 444/*
430 * called on driver init only. TODO call when a device is created. 445 * allocates the drbd_bitmap and stores it in device->bitmap.
431 * allocates the drbd_bitmap, and stores it in device->bitmap.
432 */ 446 */
433int drbd_bm_init(struct drbd_device *device) 447int drbd_bm_init(struct drbd_device *device)
434{ 448{
@@ -633,7 +647,8 @@ int drbd_bm_resize(struct drbd_device *device, sector_t capacity, int set_new_bi
633 unsigned long bits, words, owords, obits; 647 unsigned long bits, words, owords, obits;
634 unsigned long want, have, onpages; /* number of pages */ 648 unsigned long want, have, onpages; /* number of pages */
635 struct page **npages, **opages = NULL; 649 struct page **npages, **opages = NULL;
636 int err = 0, growing; 650 int err = 0;
651 bool growing;
637 652
638 if (!expect(b)) 653 if (!expect(b))
639 return -ENOMEM; 654 return -ENOMEM;
@@ -1030,7 +1045,7 @@ static int bm_rw(struct drbd_device *device, const unsigned int flags, unsigned
1030{ 1045{
1031 struct drbd_bm_aio_ctx *ctx; 1046 struct drbd_bm_aio_ctx *ctx;
1032 struct drbd_bitmap *b = device->bitmap; 1047 struct drbd_bitmap *b = device->bitmap;
1033 int num_pages, i, count = 0; 1048 unsigned int num_pages, i, count = 0;
1034 unsigned long now; 1049 unsigned long now;
1035 char ppb[10]; 1050 char ppb[10];
1036 int err = 0; 1051 int err = 0;
@@ -1078,16 +1093,37 @@ static int bm_rw(struct drbd_device *device, const unsigned int flags, unsigned
1078 now = jiffies; 1093 now = jiffies;
1079 1094
1080 /* let the layers below us try to merge these bios... */ 1095 /* let the layers below us try to merge these bios... */
1081 for (i = 0; i < num_pages; i++) {
1082 /* ignore completely unchanged pages */
1083 if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx)
1084 break;
1085 if (!(flags & BM_AIO_READ)) {
1086 if ((flags & BM_AIO_WRITE_HINTED) &&
1087 !test_and_clear_bit(BM_PAGE_HINT_WRITEOUT,
1088 &page_private(b->bm_pages[i])))
1089 continue;
1090 1096
1097 if (flags & BM_AIO_READ) {
1098 for (i = 0; i < num_pages; i++) {
1099 atomic_inc(&ctx->in_flight);
1100 bm_page_io_async(ctx, i);
1101 ++count;
1102 cond_resched();
1103 }
1104 } else if (flags & BM_AIO_WRITE_HINTED) {
1105 /* ASSERT: BM_AIO_WRITE_ALL_PAGES is not set. */
1106 unsigned int hint;
1107 for (hint = 0; hint < b->n_bitmap_hints; hint++) {
1108 i = b->al_bitmap_hints[hint];
1109 if (i >= num_pages) /* == -1U: no hint here. */
1110 continue;
1111 /* Several AL-extents may point to the same page. */
1112 if (!test_and_clear_bit(BM_PAGE_HINT_WRITEOUT,
1113 &page_private(b->bm_pages[i])))
1114 continue;
1115 /* Has it even changed? */
1116 if (bm_test_page_unchanged(b->bm_pages[i]))
1117 continue;
1118 atomic_inc(&ctx->in_flight);
1119 bm_page_io_async(ctx, i);
1120 ++count;
1121 }
1122 } else {
1123 for (i = 0; i < num_pages; i++) {
1124 /* ignore completely unchanged pages */
1125 if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx)
1126 break;
1091 if (!(flags & BM_AIO_WRITE_ALL_PAGES) && 1127 if (!(flags & BM_AIO_WRITE_ALL_PAGES) &&
1092 bm_test_page_unchanged(b->bm_pages[i])) { 1128 bm_test_page_unchanged(b->bm_pages[i])) {
1093 dynamic_drbd_dbg(device, "skipped bm write for idx %u\n", i); 1129 dynamic_drbd_dbg(device, "skipped bm write for idx %u\n", i);
@@ -1100,11 +1136,11 @@ static int bm_rw(struct drbd_device *device, const unsigned int flags, unsigned
1100 dynamic_drbd_dbg(device, "skipped bm lazy write for idx %u\n", i); 1136 dynamic_drbd_dbg(device, "skipped bm lazy write for idx %u\n", i);
1101 continue; 1137 continue;
1102 } 1138 }
1139 atomic_inc(&ctx->in_flight);
1140 bm_page_io_async(ctx, i);
1141 ++count;
1142 cond_resched();
1103 } 1143 }
1104 atomic_inc(&ctx->in_flight);
1105 bm_page_io_async(ctx, i);
1106 ++count;
1107 cond_resched();
1108 } 1144 }
1109 1145
1110 /* 1146 /*
@@ -1121,10 +1157,14 @@ static int bm_rw(struct drbd_device *device, const unsigned int flags, unsigned
1121 kref_put(&ctx->kref, &drbd_bm_aio_ctx_destroy); 1157 kref_put(&ctx->kref, &drbd_bm_aio_ctx_destroy);
1122 1158
1123 /* summary for global bitmap IO */ 1159 /* summary for global bitmap IO */
1124 if (flags == 0) 1160 if (flags == 0) {
1125 drbd_info(device, "bitmap %s of %u pages took %lu jiffies\n", 1161 unsigned int ms = jiffies_to_msecs(jiffies - now);
1126 (flags & BM_AIO_READ) ? "READ" : "WRITE", 1162 if (ms > 5) {
1127 count, jiffies - now); 1163 drbd_info(device, "bitmap %s of %u pages took %u ms\n",
1164 (flags & BM_AIO_READ) ? "READ" : "WRITE",
1165 count, ms);
1166 }
1167 }
1128 1168
1129 if (ctx->error) { 1169 if (ctx->error) {
1130 drbd_alert(device, "we had at least one MD IO ERROR during bitmap IO\n"); 1170 drbd_alert(device, "we had at least one MD IO ERROR during bitmap IO\n");