aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/drbd/drbd_bitmap.c49
-rw-r--r--drivers/block/drbd/drbd_int.h13
2 files changed, 52 insertions, 10 deletions
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index 4be737055718..bc89c4a30cbc 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -188,6 +188,9 @@ void drbd_bm_unlock(struct drbd_conf *mdev)
188/* to mark for lazy writeout once syncer cleared all clearable bits, 188/* to mark for lazy writeout once syncer cleared all clearable bits,
189 * we if bits have been cleared since last IO. */ 189 * we if bits have been cleared since last IO. */
190#define BM_PAGE_LAZY_WRITEOUT 28 190#define BM_PAGE_LAZY_WRITEOUT 28
191/* pages marked with this "HINT" will be considered for writeout
192 * on activity log transactions */
193#define BM_PAGE_HINT_WRITEOUT 27
191 194
192/* store_page_idx uses non-atomic assignment. It is only used directly after 195/* store_page_idx uses non-atomic assignment. It is only used directly after
193 * allocating the page. All other bm_set_page_* and bm_clear_page_* need to 196 * allocating the page. All other bm_set_page_* and bm_clear_page_* need to
@@ -237,6 +240,27 @@ static void bm_set_page_need_writeout(struct page *page)
237 set_bit(BM_PAGE_NEED_WRITEOUT, &page_private(page)); 240 set_bit(BM_PAGE_NEED_WRITEOUT, &page_private(page));
238} 241}
239 242
243/**
244 * drbd_bm_mark_for_writeout() - mark a page with a "hint" to be considered for writeout
245 * @mdev: DRBD device.
246 * @page_nr: the bitmap page to mark with the "hint" flag
247 *
248 * From within an activity log transaction, we mark a few pages with these
249 * hints, then call drbd_bm_write_hinted(), which will only write out changed
250 * pages which are flagged with this mark.
251 */
252void drbd_bm_mark_for_writeout(struct drbd_conf *mdev, int page_nr)
253{
254 struct page *page;
255 if (page_nr >= mdev->bitmap->bm_number_of_pages) {
256 dev_warn(DEV, "BAD: page_nr: %u, number_of_pages: %u\n",
257 page_nr, (int)mdev->bitmap->bm_number_of_pages);
258 return;
259 }
260 page = mdev->bitmap->bm_pages[page_nr];
261 set_bit(BM_PAGE_HINT_WRITEOUT, &page_private(page));
262}
263
240static int bm_test_page_unchanged(struct page *page) 264static int bm_test_page_unchanged(struct page *page)
241{ 265{
242 volatile const unsigned long *addr = &page_private(page); 266 volatile const unsigned long *addr = &page_private(page);
@@ -897,6 +921,7 @@ struct bm_aio_ctx {
897 struct completion done; 921 struct completion done;
898 unsigned flags; 922 unsigned flags;
899#define BM_AIO_COPY_PAGES 1 923#define BM_AIO_COPY_PAGES 1
924#define BM_AIO_WRITE_HINTED 2
900 int error; 925 int error;
901}; 926};
902 927
@@ -1007,13 +1032,13 @@ static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must
1007/* 1032/*
1008 * bm_rw: read/write the whole bitmap from/to its on disk location. 1033 * bm_rw: read/write the whole bitmap from/to its on disk location.
1009 */ 1034 */
1010static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_idx) __must_hold(local) 1035static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_writeout_upper_idx) __must_hold(local)
1011{ 1036{
1012 struct bm_aio_ctx ctx = { 1037 struct bm_aio_ctx ctx = {
1013 .mdev = mdev, 1038 .mdev = mdev,
1014 .in_flight = ATOMIC_INIT(1), 1039 .in_flight = ATOMIC_INIT(1),
1015 .done = COMPLETION_INITIALIZER_ONSTACK(ctx.done), 1040 .done = COMPLETION_INITIALIZER_ONSTACK(ctx.done),
1016 .flags = lazy_writeout_upper_idx ? BM_AIO_COPY_PAGES : 0, 1041 .flags = flags,
1017 }; 1042 };
1018 struct drbd_bitmap *b = mdev->bitmap; 1043 struct drbd_bitmap *b = mdev->bitmap;
1019 int num_pages, i, count = 0; 1044 int num_pages, i, count = 0;
@@ -1042,6 +1067,10 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_id
1042 if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx) 1067 if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx)
1043 break; 1068 break;
1044 if (rw & WRITE) { 1069 if (rw & WRITE) {
1070 if ((flags & BM_AIO_WRITE_HINTED) &&
1071 !test_and_clear_bit(BM_PAGE_HINT_WRITEOUT,
1072 &page_private(b->bm_pages[i])))
1073 continue;
1045 if (bm_test_page_unchanged(b->bm_pages[i])) { 1074 if (bm_test_page_unchanged(b->bm_pages[i])) {
1046 dynamic_dev_dbg(DEV, "skipped bm write for idx %u\n", i); 1075 dynamic_dev_dbg(DEV, "skipped bm write for idx %u\n", i);
1047 continue; 1076 continue;
@@ -1099,7 +1128,7 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_id
1099 */ 1128 */
1100int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local) 1129int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local)
1101{ 1130{
1102 return bm_rw(mdev, READ, 0); 1131 return bm_rw(mdev, READ, 0, 0);
1103} 1132}
1104 1133
1105/** 1134/**
@@ -1110,7 +1139,7 @@ int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local)
1110 */ 1139 */
1111int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local) 1140int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local)
1112{ 1141{
1113 return bm_rw(mdev, WRITE, 0); 1142 return bm_rw(mdev, WRITE, 0, 0);
1114} 1143}
1115 1144
1116/** 1145/**
@@ -1120,12 +1149,20 @@ int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local)
1120 */ 1149 */
1121int drbd_bm_write_lazy(struct drbd_conf *mdev, unsigned upper_idx) __must_hold(local) 1150int drbd_bm_write_lazy(struct drbd_conf *mdev, unsigned upper_idx) __must_hold(local)
1122{ 1151{
1123 return bm_rw(mdev, WRITE, upper_idx); 1152 return bm_rw(mdev, WRITE, BM_AIO_COPY_PAGES, upper_idx);
1124} 1153}
1125 1154
1155/**
1156 * drbd_bm_write_hinted() - Write bitmap pages with "hint" marks, if they have changed.
1157 * @mdev: DRBD device.
1158 */
1159int drbd_bm_write_hinted(struct drbd_conf *mdev) __must_hold(local)
1160{
1161 return bm_rw(mdev, WRITE, BM_AIO_WRITE_HINTED | BM_AIO_COPY_PAGES, 0);
1162}
1126 1163
1127/** 1164/**
1128 * drbd_bm_write_page: Writes a PAGE_SIZE aligned piece of bitmap 1165 * drbd_bm_write_page() - Writes a PAGE_SIZE aligned piece of bitmap
1129 * @mdev: DRBD device. 1166 * @mdev: DRBD device.
1130 * @idx: bitmap page index 1167 * @idx: bitmap page index
1131 * 1168 *
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 93eb3a7ac711..edfdeb62c18f 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1310,11 +1310,14 @@ struct bm_extent {
1310 1310
1311#define SLEEP_TIME (HZ/10) 1311#define SLEEP_TIME (HZ/10)
1312 1312
1313#define BM_BLOCK_SHIFT 12 /* 4k per bit */ 1313/* We do bitmap IO in units of 4k blocks.
1314 * We also still have a hardcoded 4k per bit relation. */
1315#define BM_BLOCK_SHIFT 12 /* 4k per bit */
1314#define BM_BLOCK_SIZE (1<<BM_BLOCK_SHIFT) 1316#define BM_BLOCK_SIZE (1<<BM_BLOCK_SHIFT)
1315/* (9+3) : 512 bytes @ 8 bits; representing 16M storage 1317/* mostly arbitrarily set the represented size of one bitmap extent,
1316 * per sector of on disk bitmap */ 1318 * aka resync extent, to 16 MiB (which is also 512 Byte worth of bitmap
1317#define BM_EXT_SHIFT (BM_BLOCK_SHIFT + MD_SECTOR_SHIFT + 3) /* = 24 */ 1319 * at 4k per bit resolution) */
1320#define BM_EXT_SHIFT 24 /* 16 MiB per resync extent */
1318#define BM_EXT_SIZE (1<<BM_EXT_SHIFT) 1321#define BM_EXT_SIZE (1<<BM_EXT_SHIFT)
1319 1322
1320#if (BM_EXT_SHIFT != 24) || (BM_BLOCK_SHIFT != 12) 1323#if (BM_EXT_SHIFT != 24) || (BM_BLOCK_SHIFT != 12)
@@ -1408,7 +1411,9 @@ extern int drbd_bm_test_bit(struct drbd_conf *mdev, unsigned long bitnr);
1408extern int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr); 1411extern int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr);
1409extern int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local); 1412extern int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local);
1410extern int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local); 1413extern int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local);
1414extern void drbd_bm_mark_for_writeout(struct drbd_conf *mdev, int page_nr);
1411extern int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local); 1415extern int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local);
1416extern int drbd_bm_write_hinted(struct drbd_conf *mdev) __must_hold(local);
1412extern unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, 1417extern unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev,
1413 unsigned long al_enr); 1418 unsigned long al_enr);
1414extern size_t drbd_bm_words(struct drbd_conf *mdev); 1419extern size_t drbd_bm_words(struct drbd_conf *mdev);