Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Lars Ellenberg and committed by
Philipp Reisner
4ce49266 c5a2c150

+51 -36
+34 -36
drivers/block/drbd/drbd_bitmap.c
··· 928 928 spin_unlock_irq(&b->bm_lock); 929 929 } 930 930 931 - struct bm_aio_ctx { 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 - 943 - static void bm_aio_ctx_destroy(struct kref *kref) 931 + static void drbd_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 939 put_ldev(ctx->device); 948 940 kfree(ctx); 949 941 } ··· 943 951 /* bv_page may be a copy, or may be the original */ 944 952 static void bm_async_io_complete(struct bio *bio, int error) 945 953 { 946 - struct bm_aio_ctx *ctx = bio->bi_private; 954 + struct drbd_bm_aio_ctx *ctx = bio->bi_private; 947 955 struct drbd_device *device = ctx->device; 948 956 struct drbd_bitmap *b = device->bitmap; 949 957 unsigned int idx = bm_page_to_idx(bio->bi_io_vec[0].bv_page); ··· 986 994 if (atomic_dec_and_test(&ctx->in_flight)) { 987 995 ctx->done = 1; 988 996 wake_up(&device->misc_wait); 989 - kref_put(&ctx->kref, &bm_aio_ctx_destroy); 997 + kref_put(&ctx->kref, &drbd_bm_aio_ctx_destroy); 990 998 } 991 999 } 992 1000 993 - static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must_hold(local) 1001 + static void bm_page_io_async(struct drbd_bm_aio_ctx *ctx, int page_nr) __must_hold(local) 994 1002 { 995 1003 struct bio *bio = bio_alloc_drbd(GFP_NOIO); 996 1004 struct drbd_device *device = ctx->device; 997 1005 struct drbd_bitmap *b = device->bitmap; 998 1006 struct page *page; 999 1007 unsigned int len; 1008 + unsigned int rw = (ctx->flags & BM_AIO_READ) ? READ : WRITE; 1000 1009 1001 1010 sector_t on_disk_sector = 1002 1011 device->ldev->md.md_offset + device->ldev->md.bm_offset; ··· 1043 1050 /* 1044 1051 * bm_rw: read/write the whole bitmap from/to its on disk location. 1045 1052 */ 1046 - static int bm_rw(struct drbd_device *device, int rw, unsigned flags, unsigned lazy_writeout_upper_idx) __must_hold(local) 1053 + static int bm_rw(struct drbd_device *device, const unsigned int flags, unsigned lazy_writeout_upper_idx) __must_hold(local) 1047 1054 { 1048 - struct bm_aio_ctx *ctx; 1055 + struct drbd_bm_aio_ctx *ctx; 1049 1056 struct drbd_bitmap *b = device->bitmap; 1050 1057 int num_pages, i, count = 0; 1051 1058 unsigned long now; ··· 1061 1068 * as we submit copies of pages anyways. 1062 1069 */ 1063 1070 1064 - ctx = kmalloc(sizeof(struct bm_aio_ctx), GFP_NOIO); 1071 + ctx = kmalloc(sizeof(struct drbd_bm_aio_ctx), GFP_NOIO); 1065 1072 if (!ctx) 1066 1073 return -ENOMEM; 1067 1074 1068 - *ctx = (struct bm_aio_ctx) { 1075 + *ctx = (struct drbd_bm_aio_ctx) { 1069 1076 .device = device, 1077 + .start_jif = jiffies, 1070 1078 .in_flight = ATOMIC_INIT(1), 1071 1079 .done = 0, 1072 1080 .flags = flags, ··· 1075 1081 .kref = { ATOMIC_INIT(2) }, 1076 1082 }; 1077 1083 1078 - if (!get_ldev_if_state(device, D_ATTACHING)) { /* put is in bm_aio_ctx_destroy() */ 1084 + if (!get_ldev_if_state(device, D_ATTACHING)) { /* put is in drbd_bm_aio_ctx_destroy() */ 1079 1085 drbd_err(device, "ASSERT FAILED: get_ldev_if_state() == 1 in bm_rw()\n"); 1080 1086 kfree(ctx); 1081 1087 return -ENODEV; ··· 1083 1089 /* Here D_ATTACHING is sufficient since drbd_bm_read() is called only from 1084 1090 drbd_adm_attach(), after device->ldev was assigned. */ 1085 1091 1086 - if (!ctx->flags) 1092 + if (0 == (ctx->flags & ~BM_AIO_READ)) 1087 1093 WARN_ON(!(BM_LOCKED_MASK & b->bm_flags)); 1094 + 1095 + spin_lock_irq(&device->resource->req_lock); 1096 + list_add_tail(&ctx->list, &device->pending_bitmap_io); 1097 + spin_unlock_irq(&device->resource->req_lock); 1088 1098 1089 1099 num_pages = b->bm_number_of_pages; 1090 1100 ··· 1099 1101 /* ignore completely unchanged pages */ 1100 1102 if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx) 1101 1103 break; 1102 - if (rw & WRITE) { 1104 + if (!(flags & BM_AIO_READ)) { 1103 1105 if ((flags & BM_AIO_WRITE_HINTED) && 1104 1106 !test_and_clear_bit(BM_PAGE_HINT_WRITEOUT, 1105 1107 &page_private(b->bm_pages[i]))) 1106 1108 continue; 1107 1109 1108 - if (!(flags & BM_WRITE_ALL_PAGES) && 1110 + if (!(flags & BM_AIO_WRITE_ALL_PAGES) && 1109 1111 bm_test_page_unchanged(b->bm_pages[i])) { 1110 1112 dynamic_drbd_dbg(device, "skipped bm write for idx %u\n", i); 1111 1113 continue; ··· 1119 1121 } 1120 1122 } 1121 1123 atomic_inc(&ctx->in_flight); 1122 - bm_page_io_async(ctx, i, rw); 1124 + bm_page_io_async(ctx, i); 1123 1125 ++count; 1124 1126 cond_resched(); 1125 1127 } ··· 1135 1137 if (!atomic_dec_and_test(&ctx->in_flight)) 1136 1138 wait_until_done_or_force_detached(device, device->ldev, &ctx->done); 1137 1139 else 1138 - kref_put(&ctx->kref, &bm_aio_ctx_destroy); 1140 + kref_put(&ctx->kref, &drbd_bm_aio_ctx_destroy); 1139 1141 1140 1142 /* summary for global bitmap IO */ 1141 1143 if (flags == 0) 1142 1144 drbd_info(device, "bitmap %s of %u pages took %lu jiffies\n", 1143 - rw == WRITE ? "WRITE" : "READ", 1145 + (flags & BM_AIO_READ) ? "READ" : "WRITE", 1144 1146 count, jiffies - now); 1145 1147 1146 1148 if (ctx->error) { ··· 1153 1155 err = -EIO; /* Disk timeout/force-detach during IO... */ 1154 1156 1155 1157 now = jiffies; 1156 - if (rw == READ) { 1158 + if (flags & BM_AIO_READ) { 1157 1159 b->bm_set = bm_count_bits(b); 1158 1160 drbd_info(device, "recounting of set bits took additional %lu jiffies\n", 1159 1161 jiffies - now); 1160 1162 } 1161 1163 now = b->bm_set; 1162 1164 1163 - if (flags == 0) 1165 + if ((flags & ~BM_AIO_READ) == 0) 1164 1166 drbd_info(device, "%s (%lu bits) marked out-of-sync by on disk bit-map.\n", 1165 1167 ppsize(ppb, now << (BM_BLOCK_SHIFT-10)), now); 1166 1168 1167 - kref_put(&ctx->kref, &bm_aio_ctx_destroy); 1169 + kref_put(&ctx->kref, &drbd_bm_aio_ctx_destroy); 1168 1170 return err; 1169 1171 } 1170 1172 ··· 1174 1176 */ 1175 1177 int drbd_bm_read(struct drbd_device *device) __must_hold(local) 1176 1178 { 1177 - return bm_rw(device, READ, 0, 0); 1179 + return bm_rw(device, BM_AIO_READ, 0); 1178 1180 } 1179 1181 1180 1182 /** ··· 1185 1187 */ 1186 1188 int drbd_bm_write(struct drbd_device *device) __must_hold(local) 1187 1189 { 1188 - return bm_rw(device, WRITE, 0, 0); 1190 + return bm_rw(device, 0, 0); 1189 1191 } 1190 1192 1191 1193 /** ··· 1196 1198 */ 1197 1199 int drbd_bm_write_all(struct drbd_device *device) __must_hold(local) 1198 1200 { 1199 - return bm_rw(device, WRITE, BM_WRITE_ALL_PAGES, 0); 1201 + return bm_rw(device, BM_AIO_WRITE_ALL_PAGES, 0); 1200 1202 } 1201 1203 1202 1204 /** ··· 1222 1224 */ 1223 1225 int drbd_bm_write_copy_pages(struct drbd_device *device) __must_hold(local) 1224 1226 { 1225 - return bm_rw(device, WRITE, BM_AIO_COPY_PAGES, 0); 1227 + return bm_rw(device, BM_AIO_COPY_PAGES, 0); 1226 1228 } 1227 1229 1228 1230 /** ··· 1231 1233 */ 1232 1234 int drbd_bm_write_hinted(struct drbd_device *device) __must_hold(local) 1233 1235 { 1234 - return bm_rw(device, WRITE, BM_AIO_WRITE_HINTED | BM_AIO_COPY_PAGES, 0); 1236 + return bm_rw(device, BM_AIO_WRITE_HINTED | BM_AIO_COPY_PAGES, 0); 1235 1237 } 1236 1238 1237 1239 /* NOTE
+16
drivers/block/drbd/drbd_int.h
··· 777 777 struct drbd_device { 778 778 struct drbd_resource *resource; 779 779 struct list_head peer_devices; 780 + struct list_head pending_bitmap_io; 780 781 int vnr; /* volume number within the connection */ 781 782 struct kref kref; 782 783 ··· 917 916 /* any requests that would block in drbd_make_request() 918 917 * are deferred to this single-threaded work queue */ 919 918 struct submit_worker submit; 919 + }; 920 + 921 + struct drbd_bm_aio_ctx { 922 + struct drbd_device *device; 923 + struct list_head list; /* on device->pending_bitmap_io */; 924 + unsigned long start_jif; 925 + atomic_t in_flight; 926 + unsigned int done; 927 + unsigned flags; 928 + #define BM_AIO_COPY_PAGES 1 929 + #define BM_AIO_WRITE_HINTED 2 930 + #define BM_AIO_WRITE_ALL_PAGES 4 931 + #define BM_AIO_READ 8 932 + int error; 933 + struct kref kref; 920 934 }; 921 935 922 936 struct drbd_config_context {
+1
drivers/block/drbd/drbd_main.c
··· 2793 2793 kref_get(&device->kref); 2794 2794 2795 2795 INIT_LIST_HEAD(&device->peer_devices); 2796 + INIT_LIST_HEAD(&device->pending_bitmap_io); 2796 2797 for_each_connection(connection, resource) { 2797 2798 peer_device = kzalloc(sizeof(struct drbd_peer_device), GFP_KERNEL); 2798 2799 if (!peer_device)