aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2014-05-05 18:44:59 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2014-07-10 12:35:15 -0400
commit4ce4926683b820c5c85b8033891dbfb53cc8754f (patch)
tree9e9c24f1f3d6cb5ffc1b723bc2b2d9c472e49cbf /drivers/block/drbd
parentc5a2c1509ea55d074bf0cd8ff0679b247f70cbe3 (diff)
drbd: track details of bitmap IO
Track start and submit time of bitmap operations, and add pending bitmap IO contexts to a new pending_bitmap_io list. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r--drivers/block/drbd/drbd_bitmap.c70
-rw-r--r--drivers/block/drbd/drbd_int.h16
-rw-r--r--drivers/block/drbd/drbd_main.c1
3 files changed, 51 insertions, 36 deletions
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index 29af96038e69..426c97aef900 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -928,22 +928,14 @@ void drbd_bm_clear_all(struct drbd_device *device)
928 spin_unlock_irq(&b->bm_lock); 928 spin_unlock_irq(&b->bm_lock);
929} 929}
930 930
931struct bm_aio_ctx { 931static void drbd_bm_aio_ctx_destroy(struct kref *kref)
932 struct drbd_device *device;
933 atomic_t in_flight;
934 unsigned int done;
935 unsigned flags;
936#define BM_AIO_COPY_PAGES 1
937#define BM_AIO_WRITE_HINTED 2
938#define BM_WRITE_ALL_PAGES 4
939 int error;
940 struct kref kref;
941};
942
943static void bm_aio_ctx_destroy(struct kref *kref)
944{ 932{
945 struct bm_aio_ctx *ctx = container_of(kref, struct bm_aio_ctx, kref); 933 struct drbd_bm_aio_ctx *ctx = container_of(kref, struct drbd_bm_aio_ctx, kref);
934 unsigned long flags;
946 935
936 spin_lock_irqsave(&ctx->device->resource->req_lock, flags);
937 list_del(&ctx->list);
938 spin_unlock_irqrestore(&ctx->device->resource->req_lock, flags);
947 put_ldev(ctx->device); 939 put_ldev(ctx->device);
948 kfree(ctx); 940 kfree(ctx);
949} 941}
@@ -951,7 +943,7 @@ static void bm_aio_ctx_destroy(struct kref *kref)
951/* bv_page may be a copy, or may be the original */ 943/* bv_page may be a copy, or may be the original */
952static void bm_async_io_complete(struct bio *bio, int error) 944static void bm_async_io_complete(struct bio *bio, int error)
953{ 945{
954 struct bm_aio_ctx *ctx = bio->bi_private; 946 struct drbd_bm_aio_ctx *ctx = bio->bi_private;
955 struct drbd_device *device = ctx->device; 947 struct drbd_device *device = ctx->device;
956 struct drbd_bitmap *b = device->bitmap; 948 struct drbd_bitmap *b = device->bitmap;
957 unsigned int idx = bm_page_to_idx(bio->bi_io_vec[0].bv_page); 949 unsigned int idx = bm_page_to_idx(bio->bi_io_vec[0].bv_page);
@@ -994,17 +986,18 @@ static void bm_async_io_complete(struct bio *bio, int error)
994 if (atomic_dec_and_test(&ctx->in_flight)) { 986 if (atomic_dec_and_test(&ctx->in_flight)) {
995 ctx->done = 1; 987 ctx->done = 1;
996 wake_up(&device->misc_wait); 988 wake_up(&device->misc_wait);
997 kref_put(&ctx->kref, &bm_aio_ctx_destroy); 989 kref_put(&ctx->kref, &drbd_bm_aio_ctx_destroy);
998 } 990 }
999} 991}
1000 992
1001static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must_hold(local) 993static void bm_page_io_async(struct drbd_bm_aio_ctx *ctx, int page_nr) __must_hold(local)
1002{ 994{
1003 struct bio *bio = bio_alloc_drbd(GFP_NOIO); 995 struct bio *bio = bio_alloc_drbd(GFP_NOIO);
1004 struct drbd_device *device = ctx->device; 996 struct drbd_device *device = ctx->device;
1005 struct drbd_bitmap *b = device->bitmap; 997 struct drbd_bitmap *b = device->bitmap;
1006 struct page *page; 998 struct page *page;
1007 unsigned int len; 999 unsigned int len;
1000 unsigned int rw = (ctx->flags & BM_AIO_READ) ? READ : WRITE;
1008 1001
1009 sector_t on_disk_sector = 1002 sector_t on_disk_sector =
1010 device->ldev->md.md_offset + device->ldev->md.bm_offset; 1003 device->ldev->md.md_offset + device->ldev->md.bm_offset;
@@ -1050,9 +1043,9 @@ static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must
1050/* 1043/*
1051 * bm_rw: read/write the whole bitmap from/to its on disk location. 1044 * bm_rw: read/write the whole bitmap from/to its on disk location.
1052 */ 1045 */
1053static int bm_rw(struct drbd_device *device, int rw, unsigned flags, unsigned lazy_writeout_upper_idx) __must_hold(local) 1046static int bm_rw(struct drbd_device *device, const unsigned int flags, unsigned lazy_writeout_upper_idx) __must_hold(local)
1054{ 1047{
1055 struct bm_aio_ctx *ctx; 1048 struct drbd_bm_aio_ctx *ctx;
1056 struct drbd_bitmap *b = device->bitmap; 1049 struct drbd_bitmap *b = device->bitmap;
1057 int num_pages, i, count = 0; 1050 int num_pages, i, count = 0;
1058 unsigned long now; 1051 unsigned long now;
@@ -1068,12 +1061,13 @@ static int bm_rw(struct drbd_device *device, int rw, unsigned flags, unsigned la
1068 * as we submit copies of pages anyways. 1061 * as we submit copies of pages anyways.
1069 */ 1062 */
1070 1063
1071 ctx = kmalloc(sizeof(struct bm_aio_ctx), GFP_NOIO); 1064 ctx = kmalloc(sizeof(struct drbd_bm_aio_ctx), GFP_NOIO);
1072 if (!ctx) 1065 if (!ctx)
1073 return -ENOMEM; 1066 return -ENOMEM;
1074 1067
1075 *ctx = (struct bm_aio_ctx) { 1068 *ctx = (struct drbd_bm_aio_ctx) {
1076 .device = device, 1069 .device = device,
1070 .start_jif = jiffies,
1077 .in_flight = ATOMIC_INIT(1), 1071 .in_flight = ATOMIC_INIT(1),
1078 .done = 0, 1072 .done = 0,
1079 .flags = flags, 1073 .flags = flags,
@@ -1081,7 +1075,7 @@ static int bm_rw(struct drbd_device *device, int rw, unsigned flags, unsigned la
1081 .kref = { ATOMIC_INIT(2) }, 1075 .kref = { ATOMIC_INIT(2) },
1082 }; 1076 };
1083 1077
1084 if (!get_ldev_if_state(device, D_ATTACHING)) { /* put is in bm_aio_ctx_destroy() */ 1078 if (!get_ldev_if_state(device, D_ATTACHING)) { /* put is in drbd_bm_aio_ctx_destroy() */
1085 drbd_err(device, "ASSERT FAILED: get_ldev_if_state() == 1 in bm_rw()\n"); 1079 drbd_err(device, "ASSERT FAILED: get_ldev_if_state() == 1 in bm_rw()\n");
1086 kfree(ctx); 1080 kfree(ctx);
1087 return -ENODEV; 1081 return -ENODEV;
@@ -1089,9 +1083,13 @@ static int bm_rw(struct drbd_device *device, int rw, unsigned flags, unsigned la
1089 /* Here D_ATTACHING is sufficient since drbd_bm_read() is called only from 1083 /* Here D_ATTACHING is sufficient since drbd_bm_read() is called only from
1090 drbd_adm_attach(), after device->ldev was assigned. */ 1084 drbd_adm_attach(), after device->ldev was assigned. */
1091 1085
1092 if (!ctx->flags) 1086 if (0 == (ctx->flags & ~BM_AIO_READ))
1093 WARN_ON(!(BM_LOCKED_MASK & b->bm_flags)); 1087 WARN_ON(!(BM_LOCKED_MASK & b->bm_flags));
1094 1088
1089 spin_lock_irq(&device->resource->req_lock);
1090 list_add_tail(&ctx->list, &device->pending_bitmap_io);
1091 spin_unlock_irq(&device->resource->req_lock);
1092
1095 num_pages = b->bm_number_of_pages; 1093 num_pages = b->bm_number_of_pages;
1096 1094
1097 now = jiffies; 1095 now = jiffies;
@@ -1101,13 +1099,13 @@ static int bm_rw(struct drbd_device *device, int rw, unsigned flags, unsigned la
1101 /* ignore completely unchanged pages */ 1099 /* ignore completely unchanged pages */
1102 if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx) 1100 if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx)
1103 break; 1101 break;
1104 if (rw & WRITE) { 1102 if (!(flags & BM_AIO_READ)) {
1105 if ((flags & BM_AIO_WRITE_HINTED) && 1103 if ((flags & BM_AIO_WRITE_HINTED) &&
1106 !test_and_clear_bit(BM_PAGE_HINT_WRITEOUT, 1104 !test_and_clear_bit(BM_PAGE_HINT_WRITEOUT,
1107 &page_private(b->bm_pages[i]))) 1105 &page_private(b->bm_pages[i])))
1108 continue; 1106 continue;
1109 1107
1110 if (!(flags & BM_WRITE_ALL_PAGES) && 1108 if (!(flags & BM_AIO_WRITE_ALL_PAGES) &&
1111 bm_test_page_unchanged(b->bm_pages[i])) { 1109 bm_test_page_unchanged(b->bm_pages[i])) {
1112 dynamic_drbd_dbg(device, "skipped bm write for idx %u\n", i); 1110 dynamic_drbd_dbg(device, "skipped bm write for idx %u\n", i);
1113 continue; 1111 continue;
@@ -1121,7 +1119,7 @@ static int bm_rw(struct drbd_device *device, int rw, unsigned flags, unsigned la
1121 } 1119 }
1122 } 1120 }
1123 atomic_inc(&ctx->in_flight); 1121 atomic_inc(&ctx->in_flight);
1124 bm_page_io_async(ctx, i, rw); 1122 bm_page_io_async(ctx, i);
1125 ++count; 1123 ++count;
1126 cond_resched(); 1124 cond_resched();
1127 } 1125 }
@@ -1137,12 +1135,12 @@ static int bm_rw(struct drbd_device *device, int rw, unsigned flags, unsigned la
1137 if (!atomic_dec_and_test(&ctx->in_flight)) 1135 if (!atomic_dec_and_test(&ctx->in_flight))
1138 wait_until_done_or_force_detached(device, device->ldev, &ctx->done); 1136 wait_until_done_or_force_detached(device, device->ldev, &ctx->done);
1139 else 1137 else
1140 kref_put(&ctx->kref, &bm_aio_ctx_destroy); 1138 kref_put(&ctx->kref, &drbd_bm_aio_ctx_destroy);
1141 1139
1142 /* summary for global bitmap IO */ 1140 /* summary for global bitmap IO */
1143 if (flags == 0) 1141 if (flags == 0)
1144 drbd_info(device, "bitmap %s of %u pages took %lu jiffies\n", 1142 drbd_info(device, "bitmap %s of %u pages took %lu jiffies\n",
1145 rw == WRITE ? "WRITE" : "READ", 1143 (flags & BM_AIO_READ) ? "READ" : "WRITE",
1146 count, jiffies - now); 1144 count, jiffies - now);
1147 1145
1148 if (ctx->error) { 1146 if (ctx->error) {
@@ -1155,18 +1153,18 @@ static int bm_rw(struct drbd_device *device, int rw, unsigned flags, unsigned la
1155 err = -EIO; /* Disk timeout/force-detach during IO... */ 1153 err = -EIO; /* Disk timeout/force-detach during IO... */
1156 1154
1157 now = jiffies; 1155 now = jiffies;
1158 if (rw == READ) { 1156 if (flags & BM_AIO_READ) {
1159 b->bm_set = bm_count_bits(b); 1157 b->bm_set = bm_count_bits(b);
1160 drbd_info(device, "recounting of set bits took additional %lu jiffies\n", 1158 drbd_info(device, "recounting of set bits took additional %lu jiffies\n",
1161 jiffies - now); 1159 jiffies - now);
1162 } 1160 }
1163 now = b->bm_set; 1161 now = b->bm_set;
1164 1162
1165 if (flags == 0) 1163 if ((flags & ~BM_AIO_READ) == 0)
1166 drbd_info(device, "%s (%lu bits) marked out-of-sync by on disk bit-map.\n", 1164 drbd_info(device, "%s (%lu bits) marked out-of-sync by on disk bit-map.\n",
1167 ppsize(ppb, now << (BM_BLOCK_SHIFT-10)), now); 1165 ppsize(ppb, now << (BM_BLOCK_SHIFT-10)), now);
1168 1166
1169 kref_put(&ctx->kref, &bm_aio_ctx_destroy); 1167 kref_put(&ctx->kref, &drbd_bm_aio_ctx_destroy);
1170 return err; 1168 return err;
1171} 1169}
1172 1170
@@ -1176,7 +1174,7 @@ static int bm_rw(struct drbd_device *device, int rw, unsigned flags, unsigned la
1176 */ 1174 */
1177int drbd_bm_read(struct drbd_device *device) __must_hold(local) 1175int drbd_bm_read(struct drbd_device *device) __must_hold(local)
1178{ 1176{
1179 return bm_rw(device, READ, 0, 0); 1177 return bm_rw(device, BM_AIO_READ, 0);
1180} 1178}
1181 1179
1182/** 1180/**
@@ -1187,7 +1185,7 @@ int drbd_bm_read(struct drbd_device *device) __must_hold(local)
1187 */ 1185 */
1188int drbd_bm_write(struct drbd_device *device) __must_hold(local) 1186int drbd_bm_write(struct drbd_device *device) __must_hold(local)
1189{ 1187{
1190 return bm_rw(device, WRITE, 0, 0); 1188 return bm_rw(device, 0, 0);
1191} 1189}
1192 1190
1193/** 1191/**
@@ -1198,7 +1196,7 @@ int drbd_bm_write(struct drbd_device *device) __must_hold(local)
1198 */ 1196 */
1199int drbd_bm_write_all(struct drbd_device *device) __must_hold(local) 1197int drbd_bm_write_all(struct drbd_device *device) __must_hold(local)
1200{ 1198{
1201 return bm_rw(device, WRITE, BM_WRITE_ALL_PAGES, 0); 1199 return bm_rw(device, BM_AIO_WRITE_ALL_PAGES, 0);
1202} 1200}
1203 1201
1204/** 1202/**
@@ -1224,7 +1222,7 @@ int drbd_bm_write_lazy(struct drbd_device *device, unsigned upper_idx) __must_ho
1224 */ 1222 */
1225int drbd_bm_write_copy_pages(struct drbd_device *device) __must_hold(local) 1223int drbd_bm_write_copy_pages(struct drbd_device *device) __must_hold(local)
1226{ 1224{
1227 return bm_rw(device, WRITE, BM_AIO_COPY_PAGES, 0); 1225 return bm_rw(device, BM_AIO_COPY_PAGES, 0);
1228} 1226}
1229 1227
1230/** 1228/**
@@ -1233,7 +1231,7 @@ int drbd_bm_write_copy_pages(struct drbd_device *device) __must_hold(local)
1233 */ 1231 */
1234int drbd_bm_write_hinted(struct drbd_device *device) __must_hold(local) 1232int drbd_bm_write_hinted(struct drbd_device *device) __must_hold(local)
1235{ 1233{
1236 return bm_rw(device, WRITE, BM_AIO_WRITE_HINTED | BM_AIO_COPY_PAGES, 0); 1234 return bm_rw(device, BM_AIO_WRITE_HINTED | BM_AIO_COPY_PAGES, 0);
1237} 1235}
1238 1236
1239/* NOTE 1237/* NOTE
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index c7a409f3aaf8..40c816ce8d75 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -777,6 +777,7 @@ struct drbd_peer_device {
777struct drbd_device { 777struct drbd_device {
778 struct drbd_resource *resource; 778 struct drbd_resource *resource;
779 struct list_head peer_devices; 779 struct list_head peer_devices;
780 struct list_head pending_bitmap_io;
780 int vnr; /* volume number within the connection */ 781 int vnr; /* volume number within the connection */
781 struct kref kref; 782 struct kref kref;
782 783
@@ -918,6 +919,21 @@ struct drbd_device {
918 struct submit_worker submit; 919 struct submit_worker submit;
919}; 920};
920 921
922struct drbd_bm_aio_ctx {
923 struct drbd_device *device;
924 struct list_head list; /* on device->pending_bitmap_io */;
925 unsigned long start_jif;
926 atomic_t in_flight;
927 unsigned int done;
928 unsigned flags;
929#define BM_AIO_COPY_PAGES 1
930#define BM_AIO_WRITE_HINTED 2
931#define BM_AIO_WRITE_ALL_PAGES 4
932#define BM_AIO_READ 8
933 int error;
934 struct kref kref;
935};
936
921struct drbd_config_context { 937struct drbd_config_context {
922 /* assigned from drbd_genlmsghdr */ 938 /* assigned from drbd_genlmsghdr */
923 unsigned int minor; 939 unsigned int minor;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index ad7c0e8843c4..922d631c10b3 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2793,6 +2793,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
2793 kref_get(&device->kref); 2793 kref_get(&device->kref);
2794 2794
2795 INIT_LIST_HEAD(&device->peer_devices); 2795 INIT_LIST_HEAD(&device->peer_devices);
2796 INIT_LIST_HEAD(&device->pending_bitmap_io);
2796 for_each_connection(connection, resource) { 2797 for_each_connection(connection, resource) {
2797 peer_device = kzalloc(sizeof(struct drbd_peer_device), GFP_KERNEL); 2798 peer_device = kzalloc(sizeof(struct drbd_peer_device), GFP_KERNEL);
2798 if (!peer_device) 2799 if (!peer_device)