diff options
| -rw-r--r-- | drivers/block/drbd/drbd_int.h | 16 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_main.c | 75 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_nl.c | 4 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_proc.c | 19 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_receiver.c | 113 | ||||
| -rw-r--r-- | drivers/block/drbd/drbd_worker.c | 15 | ||||
| -rw-r--r-- | include/linux/drbd.h | 2 | ||||
| -rw-r--r-- | include/linux/drbd_nl.h | 9 |
8 files changed, 28 insertions, 225 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 485ed8c7d623..352441b0f92f 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
| @@ -550,12 +550,6 @@ struct p_delay_probe { | |||
| 550 | u32 offset; /* usecs the probe got sent after the reference time point */ | 550 | u32 offset; /* usecs the probe got sent after the reference time point */ |
| 551 | } __packed; | 551 | } __packed; |
| 552 | 552 | ||
| 553 | struct delay_probe { | ||
| 554 | struct list_head list; | ||
| 555 | unsigned int seq_num; | ||
| 556 | struct timeval time; | ||
| 557 | }; | ||
| 558 | |||
| 559 | /* DCBP: Drbd Compressed Bitmap Packet ... */ | 553 | /* DCBP: Drbd Compressed Bitmap Packet ... */ |
| 560 | static inline enum drbd_bitmap_code | 554 | static inline enum drbd_bitmap_code |
| 561 | DCBP_get_code(struct p_compressed_bm *p) | 555 | DCBP_get_code(struct p_compressed_bm *p) |
| @@ -942,11 +936,9 @@ struct drbd_conf { | |||
| 942 | unsigned int ko_count; | 936 | unsigned int ko_count; |
| 943 | struct drbd_work resync_work, | 937 | struct drbd_work resync_work, |
| 944 | unplug_work, | 938 | unplug_work, |
| 945 | md_sync_work, | 939 | md_sync_work; |
| 946 | delay_probe_work; | ||
| 947 | struct timer_list resync_timer; | 940 | struct timer_list resync_timer; |
| 948 | struct timer_list md_sync_timer; | 941 | struct timer_list md_sync_timer; |
| 949 | struct timer_list delay_probe_timer; | ||
| 950 | 942 | ||
| 951 | /* Used after attach while negotiating new disk state. */ | 943 | /* Used after attach while negotiating new disk state. */ |
| 952 | union drbd_state new_state_tmp; | 944 | union drbd_state new_state_tmp; |
| @@ -1062,12 +1054,6 @@ struct drbd_conf { | |||
| 1062 | u64 ed_uuid; /* UUID of the exposed data */ | 1054 | u64 ed_uuid; /* UUID of the exposed data */ |
| 1063 | struct mutex state_mutex; | 1055 | struct mutex state_mutex; |
| 1064 | char congestion_reason; /* Why we where congested... */ | 1056 | char congestion_reason; /* Why we where congested... */ |
| 1065 | struct list_head delay_probes; /* protected by peer_seq_lock */ | ||
| 1066 | int data_delay; /* Delay of packets on the data-sock behind meta-sock */ | ||
| 1067 | unsigned int delay_seq; /* To generate sequence numbers of delay probes */ | ||
| 1068 | struct timeval dps_time; /* delay-probes-start-time */ | ||
| 1069 | unsigned int dp_volume_last; /* send_cnt of last delay probe */ | ||
| 1070 | int c_sync_rate; /* current resync rate after delay_probe magic */ | ||
| 1071 | }; | 1057 | }; |
| 1072 | 1058 | ||
| 1073 | static inline struct drbd_conf *minor_to_mdev(unsigned int minor) | 1059 | static inline struct drbd_conf *minor_to_mdev(unsigned int minor) |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 668f06378214..fa650dd85b90 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
| @@ -2184,43 +2184,6 @@ int drbd_send_ov_request(struct drbd_conf *mdev, sector_t sector, int size) | |||
| 2184 | return ok; | 2184 | return ok; |
| 2185 | } | 2185 | } |
| 2186 | 2186 | ||
| 2187 | static int drbd_send_delay_probe(struct drbd_conf *mdev, struct drbd_socket *ds) | ||
| 2188 | { | ||
| 2189 | struct p_delay_probe dp; | ||
| 2190 | int offset, ok = 0; | ||
| 2191 | struct timeval now; | ||
| 2192 | |||
| 2193 | mutex_lock(&ds->mutex); | ||
| 2194 | if (likely(ds->socket)) { | ||
| 2195 | do_gettimeofday(&now); | ||
| 2196 | offset = now.tv_usec - mdev->dps_time.tv_usec + | ||
| 2197 | (now.tv_sec - mdev->dps_time.tv_sec) * 1000000; | ||
| 2198 | dp.seq_num = cpu_to_be32(mdev->delay_seq); | ||
| 2199 | dp.offset = cpu_to_be32(offset); | ||
| 2200 | |||
| 2201 | ok = _drbd_send_cmd(mdev, ds->socket, P_DELAY_PROBE, | ||
| 2202 | (struct p_header *)&dp, sizeof(dp), 0); | ||
| 2203 | } | ||
| 2204 | mutex_unlock(&ds->mutex); | ||
| 2205 | |||
| 2206 | return ok; | ||
| 2207 | } | ||
| 2208 | |||
| 2209 | static int drbd_send_delay_probes(struct drbd_conf *mdev) | ||
| 2210 | { | ||
| 2211 | int ok; | ||
| 2212 | |||
| 2213 | mdev->delay_seq++; | ||
| 2214 | do_gettimeofday(&mdev->dps_time); | ||
| 2215 | ok = drbd_send_delay_probe(mdev, &mdev->meta); | ||
| 2216 | ok = ok && drbd_send_delay_probe(mdev, &mdev->data); | ||
| 2217 | |||
| 2218 | mdev->dp_volume_last = mdev->send_cnt; | ||
| 2219 | mod_timer(&mdev->delay_probe_timer, jiffies + mdev->sync_conf.dp_interval * HZ / 10); | ||
| 2220 | |||
| 2221 | return ok; | ||
| 2222 | } | ||
| 2223 | |||
| 2224 | /* called on sndtimeo | 2187 | /* called on sndtimeo |
| 2225 | * returns FALSE if we should retry, | 2188 | * returns FALSE if we should retry, |
| 2226 | * TRUE if we think connection is dead | 2189 | * TRUE if we think connection is dead |
| @@ -2369,27 +2332,6 @@ static int _drbd_send_zc_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e) | |||
| 2369 | return 1; | 2332 | return 1; |
| 2370 | } | 2333 | } |
| 2371 | 2334 | ||
| 2372 | static void consider_delay_probes(struct drbd_conf *mdev) | ||
| 2373 | { | ||
| 2374 | return; | ||
| 2375 | } | ||
| 2376 | |||
| 2377 | static int w_delay_probes(struct drbd_conf *mdev, struct drbd_work *w, int cancel) | ||
| 2378 | { | ||
| 2379 | if (!cancel && mdev->state.conn == C_SYNC_SOURCE) | ||
| 2380 | drbd_send_delay_probes(mdev); | ||
| 2381 | |||
| 2382 | return 1; | ||
| 2383 | } | ||
| 2384 | |||
| 2385 | static void delay_probe_timer_fn(unsigned long data) | ||
| 2386 | { | ||
| 2387 | struct drbd_conf *mdev = (struct drbd_conf *) data; | ||
| 2388 | |||
| 2389 | if (list_empty(&mdev->delay_probe_work.list)) | ||
| 2390 | drbd_queue_work(&mdev->data.work, &mdev->delay_probe_work); | ||
| 2391 | } | ||
| 2392 | |||
| 2393 | /* Used to send write requests | 2335 | /* Used to send write requests |
| 2394 | * R_PRIMARY -> Peer (P_DATA) | 2336 | * R_PRIMARY -> Peer (P_DATA) |
| 2395 | */ | 2337 | */ |
| @@ -2453,9 +2395,6 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req) | |||
| 2453 | 2395 | ||
| 2454 | drbd_put_data_sock(mdev); | 2396 | drbd_put_data_sock(mdev); |
| 2455 | 2397 | ||
| 2456 | if (ok) | ||
| 2457 | consider_delay_probes(mdev); | ||
| 2458 | |||
| 2459 | return ok; | 2398 | return ok; |
| 2460 | } | 2399 | } |
| 2461 | 2400 | ||
| @@ -2502,9 +2441,6 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd, | |||
| 2502 | 2441 | ||
| 2503 | drbd_put_data_sock(mdev); | 2442 | drbd_put_data_sock(mdev); |
| 2504 | 2443 | ||
| 2505 | if (ok) | ||
| 2506 | consider_delay_probes(mdev); | ||
| 2507 | |||
| 2508 | return ok; | 2444 | return ok; |
| 2509 | } | 2445 | } |
| 2510 | 2446 | ||
| @@ -2666,10 +2602,6 @@ static void drbd_set_defaults(struct drbd_conf *mdev) | |||
| 2666 | /* .rate = */ DRBD_RATE_DEF, | 2602 | /* .rate = */ DRBD_RATE_DEF, |
| 2667 | /* .after = */ DRBD_AFTER_DEF, | 2603 | /* .after = */ DRBD_AFTER_DEF, |
| 2668 | /* .al_extents = */ DRBD_AL_EXTENTS_DEF, | 2604 | /* .al_extents = */ DRBD_AL_EXTENTS_DEF, |
| 2669 | /* .dp_volume = */ DRBD_DP_VOLUME_DEF, | ||
| 2670 | /* .dp_interval = */ DRBD_DP_INTERVAL_DEF, | ||
| 2671 | /* .throttle_th = */ DRBD_RS_THROTTLE_TH_DEF, | ||
| 2672 | /* .hold_off_th = */ DRBD_RS_HOLD_OFF_TH_DEF, | ||
| 2673 | /* .verify_alg = */ {}, 0, | 2605 | /* .verify_alg = */ {}, 0, |
| 2674 | /* .cpu_mask = */ {}, 0, | 2606 | /* .cpu_mask = */ {}, 0, |
| 2675 | /* .csums_alg = */ {}, 0, | 2607 | /* .csums_alg = */ {}, 0, |
| @@ -2736,24 +2668,17 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) | |||
| 2736 | INIT_LIST_HEAD(&mdev->unplug_work.list); | 2668 | INIT_LIST_HEAD(&mdev->unplug_work.list); |
| 2737 | INIT_LIST_HEAD(&mdev->md_sync_work.list); | 2669 | INIT_LIST_HEAD(&mdev->md_sync_work.list); |
| 2738 | INIT_LIST_HEAD(&mdev->bm_io_work.w.list); | 2670 | INIT_LIST_HEAD(&mdev->bm_io_work.w.list); |
| 2739 | INIT_LIST_HEAD(&mdev->delay_probes); | ||
| 2740 | INIT_LIST_HEAD(&mdev->delay_probe_work.list); | ||
| 2741 | 2671 | ||
| 2742 | mdev->resync_work.cb = w_resync_inactive; | 2672 | mdev->resync_work.cb = w_resync_inactive; |
| 2743 | mdev->unplug_work.cb = w_send_write_hint; | 2673 | mdev->unplug_work.cb = w_send_write_hint; |
| 2744 | mdev->md_sync_work.cb = w_md_sync; | 2674 | mdev->md_sync_work.cb = w_md_sync; |
| 2745 | mdev->bm_io_work.w.cb = w_bitmap_io; | 2675 | mdev->bm_io_work.w.cb = w_bitmap_io; |
| 2746 | mdev->delay_probe_work.cb = w_delay_probes; | ||
| 2747 | init_timer(&mdev->resync_timer); | 2676 | init_timer(&mdev->resync_timer); |
| 2748 | init_timer(&mdev->md_sync_timer); | 2677 | init_timer(&mdev->md_sync_timer); |
| 2749 | init_timer(&mdev->delay_probe_timer); | ||
| 2750 | mdev->resync_timer.function = resync_timer_fn; | 2678 | mdev->resync_timer.function = resync_timer_fn; |
| 2751 | mdev->resync_timer.data = (unsigned long) mdev; | 2679 | mdev->resync_timer.data = (unsigned long) mdev; |
| 2752 | mdev->md_sync_timer.function = md_sync_timer_fn; | 2680 | mdev->md_sync_timer.function = md_sync_timer_fn; |
| 2753 | mdev->md_sync_timer.data = (unsigned long) mdev; | 2681 | mdev->md_sync_timer.data = (unsigned long) mdev; |
| 2754 | mdev->delay_probe_timer.function = delay_probe_timer_fn; | ||
| 2755 | mdev->delay_probe_timer.data = (unsigned long) mdev; | ||
| 2756 | |||
| 2757 | 2682 | ||
| 2758 | init_waitqueue_head(&mdev->misc_wait); | 2683 | init_waitqueue_head(&mdev->misc_wait); |
| 2759 | init_waitqueue_head(&mdev->state_wait); | 2684 | init_waitqueue_head(&mdev->state_wait); |
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 2151f18b21de..73131c5ae339 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
| @@ -1557,10 +1557,6 @@ static int drbd_nl_syncer_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *n | |||
| 1557 | sc.rate = DRBD_RATE_DEF; | 1557 | sc.rate = DRBD_RATE_DEF; |
| 1558 | sc.after = DRBD_AFTER_DEF; | 1558 | sc.after = DRBD_AFTER_DEF; |
| 1559 | sc.al_extents = DRBD_AL_EXTENTS_DEF; | 1559 | sc.al_extents = DRBD_AL_EXTENTS_DEF; |
| 1560 | sc.dp_volume = DRBD_DP_VOLUME_DEF; | ||
| 1561 | sc.dp_interval = DRBD_DP_INTERVAL_DEF; | ||
| 1562 | sc.throttle_th = DRBD_RS_THROTTLE_TH_DEF; | ||
| 1563 | sc.hold_off_th = DRBD_RS_HOLD_OFF_TH_DEF; | ||
| 1564 | } else | 1560 | } else |
| 1565 | memcpy(&sc, &mdev->sync_conf, sizeof(struct syncer_conf)); | 1561 | memcpy(&sc, &mdev->sync_conf, sizeof(struct syncer_conf)); |
| 1566 | 1562 | ||
diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c index d0f1767ea4c3..be3374b68460 100644 --- a/drivers/block/drbd/drbd_proc.c +++ b/drivers/block/drbd/drbd_proc.c | |||
| @@ -73,21 +73,14 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) | |||
| 73 | seq_printf(seq, "sync'ed:%3u.%u%% ", res / 10, res % 10); | 73 | seq_printf(seq, "sync'ed:%3u.%u%% ", res / 10, res % 10); |
| 74 | /* if more than 1 GB display in MB */ | 74 | /* if more than 1 GB display in MB */ |
| 75 | if (mdev->rs_total > 0x100000L) | 75 | if (mdev->rs_total > 0x100000L) |
| 76 | seq_printf(seq, "(%lu/%lu)M", | 76 | seq_printf(seq, "(%lu/%lu)M\n\t", |
| 77 | (unsigned long) Bit2KB(rs_left >> 10), | 77 | (unsigned long) Bit2KB(rs_left >> 10), |
| 78 | (unsigned long) Bit2KB(mdev->rs_total >> 10)); | 78 | (unsigned long) Bit2KB(mdev->rs_total >> 10)); |
| 79 | else | 79 | else |
| 80 | seq_printf(seq, "(%lu/%lu)K", | 80 | seq_printf(seq, "(%lu/%lu)K\n\t", |
| 81 | (unsigned long) Bit2KB(rs_left), | 81 | (unsigned long) Bit2KB(rs_left), |
| 82 | (unsigned long) Bit2KB(mdev->rs_total)); | 82 | (unsigned long) Bit2KB(mdev->rs_total)); |
| 83 | 83 | ||
| 84 | if (mdev->state.conn == C_SYNC_TARGET) | ||
| 85 | seq_printf(seq, " queue_delay: %d.%d ms\n\t", | ||
| 86 | mdev->data_delay / 1000, | ||
| 87 | (mdev->data_delay % 1000) / 100); | ||
| 88 | else if (mdev->state.conn == C_SYNC_SOURCE) | ||
| 89 | seq_printf(seq, " delay_probe: %u\n\t", mdev->delay_seq); | ||
| 90 | |||
| 91 | /* see drivers/md/md.c | 84 | /* see drivers/md/md.c |
| 92 | * We do not want to overflow, so the order of operands and | 85 | * We do not want to overflow, so the order of operands and |
| 93 | * the * 100 / 100 trick are important. We do a +1 to be | 86 | * the * 100 / 100 trick are important. We do a +1 to be |
| @@ -135,14 +128,6 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) | |||
| 135 | else | 128 | else |
| 136 | seq_printf(seq, " (%ld)", dbdt); | 129 | seq_printf(seq, " (%ld)", dbdt); |
| 137 | 130 | ||
| 138 | if (mdev->state.conn == C_SYNC_TARGET) { | ||
| 139 | if (mdev->c_sync_rate > 1000) | ||
| 140 | seq_printf(seq, " want: %d,%03d", | ||
| 141 | mdev->c_sync_rate / 1000, mdev->c_sync_rate % 1000); | ||
| 142 | else | ||
| 143 | seq_printf(seq, " want: %d", mdev->c_sync_rate); | ||
| 144 | } | ||
| 145 | |||
| 146 | seq_printf(seq, " K/sec\n"); | 131 | seq_printf(seq, " K/sec\n"); |
| 147 | } | 132 | } |
| 148 | 133 | ||
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index cba1deb7b271..20abef531c99 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
| @@ -3555,14 +3555,15 @@ static int receive_bitmap(struct drbd_conf *mdev, struct p_header *h) | |||
| 3555 | return ok; | 3555 | return ok; |
| 3556 | } | 3556 | } |
| 3557 | 3557 | ||
| 3558 | static int receive_skip(struct drbd_conf *mdev, struct p_header *h) | 3558 | static int receive_skip_(struct drbd_conf *mdev, struct p_header *h, int silent) |
| 3559 | { | 3559 | { |
| 3560 | /* TODO zero copy sink :) */ | 3560 | /* TODO zero copy sink :) */ |
| 3561 | static char sink[128]; | 3561 | static char sink[128]; |
| 3562 | int size, want, r; | 3562 | int size, want, r; |
| 3563 | 3563 | ||
| 3564 | dev_warn(DEV, "skipping unknown optional packet type %d, l: %d!\n", | 3564 | if (!silent) |
| 3565 | h->command, h->length); | 3565 | dev_warn(DEV, "skipping unknown optional packet type %d, l: %d!\n", |
| 3566 | h->command, h->length); | ||
| 3566 | 3567 | ||
| 3567 | size = h->length; | 3568 | size = h->length; |
| 3568 | while (size > 0) { | 3569 | while (size > 0) { |
| @@ -3574,101 +3575,25 @@ static int receive_skip(struct drbd_conf *mdev, struct p_header *h) | |||
| 3574 | return size == 0; | 3575 | return size == 0; |
| 3575 | } | 3576 | } |
| 3576 | 3577 | ||
| 3577 | static int receive_UnplugRemote(struct drbd_conf *mdev, struct p_header *h) | 3578 | static int receive_skip(struct drbd_conf *mdev, struct p_header *h) |
| 3578 | { | ||
| 3579 | if (mdev->state.disk >= D_INCONSISTENT) | ||
| 3580 | drbd_kick_lo(mdev); | ||
| 3581 | |||
| 3582 | /* Make sure we've acked all the TCP data associated | ||
| 3583 | * with the data requests being unplugged */ | ||
| 3584 | drbd_tcp_quickack(mdev->data.socket); | ||
| 3585 | |||
| 3586 | return TRUE; | ||
| 3587 | } | ||
| 3588 | |||
| 3589 | static void timeval_sub_us(struct timeval* tv, unsigned int us) | ||
| 3590 | { | 3579 | { |
| 3591 | tv->tv_sec -= us / 1000000; | 3580 | return receive_skip_(mdev, h, 0); |
| 3592 | us = us % 1000000; | ||
| 3593 | if (tv->tv_usec > us) { | ||
| 3594 | tv->tv_usec += 1000000; | ||
| 3595 | tv->tv_sec--; | ||
| 3596 | } | ||
| 3597 | tv->tv_usec -= us; | ||
| 3598 | } | 3581 | } |
| 3599 | 3582 | ||
| 3600 | static void got_delay_probe(struct drbd_conf *mdev, int from, struct p_delay_probe *p) | 3583 | static int receive_skip_silent(struct drbd_conf *mdev, struct p_header *h) |
| 3601 | { | 3584 | { |
| 3602 | struct delay_probe *dp; | 3585 | return receive_skip_(mdev, h, 1); |
| 3603 | struct list_head *le; | ||
| 3604 | struct timeval now; | ||
| 3605 | int seq_num; | ||
| 3606 | int offset; | ||
| 3607 | int data_delay; | ||
| 3608 | |||
| 3609 | seq_num = be32_to_cpu(p->seq_num); | ||
| 3610 | offset = be32_to_cpu(p->offset); | ||
| 3611 | |||
| 3612 | spin_lock(&mdev->peer_seq_lock); | ||
| 3613 | if (!list_empty(&mdev->delay_probes)) { | ||
| 3614 | if (from == USE_DATA_SOCKET) | ||
| 3615 | le = mdev->delay_probes.next; | ||
| 3616 | else | ||
| 3617 | le = mdev->delay_probes.prev; | ||
| 3618 | |||
| 3619 | dp = list_entry(le, struct delay_probe, list); | ||
| 3620 | |||
| 3621 | if (dp->seq_num == seq_num) { | ||
| 3622 | list_del(le); | ||
| 3623 | spin_unlock(&mdev->peer_seq_lock); | ||
| 3624 | do_gettimeofday(&now); | ||
| 3625 | timeval_sub_us(&now, offset); | ||
| 3626 | data_delay = | ||
| 3627 | now.tv_usec - dp->time.tv_usec + | ||
| 3628 | (now.tv_sec - dp->time.tv_sec) * 1000000; | ||
| 3629 | |||
| 3630 | if (data_delay > 0) | ||
| 3631 | mdev->data_delay = data_delay; | ||
| 3632 | |||
| 3633 | kfree(dp); | ||
| 3634 | return; | ||
| 3635 | } | ||
| 3636 | |||
| 3637 | if (dp->seq_num > seq_num) { | ||
| 3638 | spin_unlock(&mdev->peer_seq_lock); | ||
| 3639 | dev_warn(DEV, "Previous allocation failure of struct delay_probe?\n"); | ||
| 3640 | return; /* Do not alloca a struct delay_probe.... */ | ||
| 3641 | } | ||
| 3642 | } | ||
| 3643 | spin_unlock(&mdev->peer_seq_lock); | ||
| 3644 | |||
| 3645 | dp = kmalloc(sizeof(struct delay_probe), GFP_NOIO); | ||
| 3646 | if (!dp) { | ||
| 3647 | dev_warn(DEV, "Failed to allocate a struct delay_probe, do not worry.\n"); | ||
| 3648 | return; | ||
| 3649 | } | ||
| 3650 | |||
| 3651 | dp->seq_num = seq_num; | ||
| 3652 | do_gettimeofday(&dp->time); | ||
| 3653 | timeval_sub_us(&dp->time, offset); | ||
| 3654 | |||
| 3655 | spin_lock(&mdev->peer_seq_lock); | ||
| 3656 | if (from == USE_DATA_SOCKET) | ||
| 3657 | list_add(&dp->list, &mdev->delay_probes); | ||
| 3658 | else | ||
| 3659 | list_add_tail(&dp->list, &mdev->delay_probes); | ||
| 3660 | spin_unlock(&mdev->peer_seq_lock); | ||
| 3661 | } | 3586 | } |
| 3662 | 3587 | ||
| 3663 | static int receive_delay_probe(struct drbd_conf *mdev, struct p_header *h) | 3588 | static int receive_UnplugRemote(struct drbd_conf *mdev, struct p_header *h) |
| 3664 | { | 3589 | { |
| 3665 | struct p_delay_probe *p = (struct p_delay_probe *)h; | 3590 | if (mdev->state.disk >= D_INCONSISTENT) |
| 3591 | drbd_kick_lo(mdev); | ||
| 3666 | 3592 | ||
| 3667 | ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; | 3593 | /* Make sure we've acked all the TCP data associated |
| 3668 | if (drbd_recv(mdev, h->payload, h->length) != h->length) | 3594 | * with the data requests being unplugged */ |
| 3669 | return FALSE; | 3595 | drbd_tcp_quickack(mdev->data.socket); |
| 3670 | 3596 | ||
| 3671 | got_delay_probe(mdev, USE_DATA_SOCKET, p); | ||
| 3672 | return TRUE; | 3597 | return TRUE; |
| 3673 | } | 3598 | } |
| 3674 | 3599 | ||
| @@ -3695,7 +3620,7 @@ static drbd_cmd_handler_f drbd_default_handler[] = { | |||
| 3695 | [P_OV_REQUEST] = receive_DataRequest, | 3620 | [P_OV_REQUEST] = receive_DataRequest, |
| 3696 | [P_OV_REPLY] = receive_DataRequest, | 3621 | [P_OV_REPLY] = receive_DataRequest, |
| 3697 | [P_CSUM_RS_REQUEST] = receive_DataRequest, | 3622 | [P_CSUM_RS_REQUEST] = receive_DataRequest, |
| 3698 | [P_DELAY_PROBE] = receive_delay_probe, | 3623 | [P_DELAY_PROBE] = receive_skip_silent, |
| 3699 | /* anything missing from this table is in | 3624 | /* anything missing from this table is in |
| 3700 | * the asender_tbl, see get_asender_cmd */ | 3625 | * the asender_tbl, see get_asender_cmd */ |
| 3701 | [P_MAX_CMD] = NULL, | 3626 | [P_MAX_CMD] = NULL, |
| @@ -4472,11 +4397,9 @@ static int got_OVResult(struct drbd_conf *mdev, struct p_header *h) | |||
| 4472 | return TRUE; | 4397 | return TRUE; |
| 4473 | } | 4398 | } |
| 4474 | 4399 | ||
| 4475 | static int got_delay_probe_m(struct drbd_conf *mdev, struct p_header *h) | 4400 | static int got_something_to_ignore_m(struct drbd_conf *mdev, struct p_header *h) |
| 4476 | { | 4401 | { |
| 4477 | struct p_delay_probe *p = (struct p_delay_probe *)h; | 4402 | /* IGNORE */ |
| 4478 | |||
| 4479 | got_delay_probe(mdev, USE_META_SOCKET, p); | ||
| 4480 | return TRUE; | 4403 | return TRUE; |
| 4481 | } | 4404 | } |
| 4482 | 4405 | ||
| @@ -4504,7 +4427,7 @@ static struct asender_cmd *get_asender_cmd(int cmd) | |||
| 4504 | [P_BARRIER_ACK] = { sizeof(struct p_barrier_ack), got_BarrierAck }, | 4427 | [P_BARRIER_ACK] = { sizeof(struct p_barrier_ack), got_BarrierAck }, |
| 4505 | [P_STATE_CHG_REPLY] = { sizeof(struct p_req_state_reply), got_RqSReply }, | 4428 | [P_STATE_CHG_REPLY] = { sizeof(struct p_req_state_reply), got_RqSReply }, |
| 4506 | [P_RS_IS_IN_SYNC] = { sizeof(struct p_block_ack), got_IsInSync }, | 4429 | [P_RS_IS_IN_SYNC] = { sizeof(struct p_block_ack), got_IsInSync }, |
| 4507 | [P_DELAY_PROBE] = { sizeof(struct p_delay_probe), got_delay_probe_m }, | 4430 | [P_DELAY_PROBE] = { sizeof(struct p_delay_probe), got_something_to_ignore_m }, |
| 4508 | [P_MAX_CMD] = { 0, NULL }, | 4431 | [P_MAX_CMD] = { 0, NULL }, |
| 4509 | }; | 4432 | }; |
| 4510 | if (cmd > P_MAX_CMD || asender_tbl[cmd].process == NULL) | 4433 | if (cmd > P_MAX_CMD || asender_tbl[cmd].process == NULL) |
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index b623ceee2a4a..ca4a16cea2d8 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
| @@ -424,18 +424,6 @@ void resync_timer_fn(unsigned long data) | |||
| 424 | drbd_queue_work(&mdev->data.work, &mdev->resync_work); | 424 | drbd_queue_work(&mdev->data.work, &mdev->resync_work); |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | static int calc_resync_rate(struct drbd_conf *mdev) | ||
| 428 | { | ||
| 429 | int d = mdev->data_delay / 1000; /* us -> ms */ | ||
| 430 | int td = mdev->sync_conf.throttle_th * 100; /* 0.1s -> ms */ | ||
| 431 | int hd = mdev->sync_conf.hold_off_th * 100; /* 0.1s -> ms */ | ||
| 432 | int cr = mdev->sync_conf.rate; | ||
| 433 | |||
| 434 | return d <= td ? cr : | ||
| 435 | d >= hd ? 0 : | ||
| 436 | cr + (cr * (td - d) / (hd - td)); | ||
| 437 | } | ||
| 438 | |||
| 439 | int w_make_resync_request(struct drbd_conf *mdev, | 427 | int w_make_resync_request(struct drbd_conf *mdev, |
| 440 | struct drbd_work *w, int cancel) | 428 | struct drbd_work *w, int cancel) |
| 441 | { | 429 | { |
| @@ -473,8 +461,7 @@ int w_make_resync_request(struct drbd_conf *mdev, | |||
| 473 | max_segment_size = mdev->agreed_pro_version < 94 ? | 461 | max_segment_size = mdev->agreed_pro_version < 94 ? |
| 474 | queue_max_segment_size(mdev->rq_queue) : DRBD_MAX_SEGMENT_SIZE; | 462 | queue_max_segment_size(mdev->rq_queue) : DRBD_MAX_SEGMENT_SIZE; |
| 475 | 463 | ||
| 476 | mdev->c_sync_rate = calc_resync_rate(mdev); | 464 | number = SLEEP_TIME * mdev->sync_conf.rate / ((BM_BLOCK_SIZE / 1024) * HZ); |
| 477 | number = SLEEP_TIME * mdev->c_sync_rate / ((BM_BLOCK_SIZE / 1024) * HZ); | ||
| 478 | pe = atomic_read(&mdev->rs_pending_cnt); | 465 | pe = atomic_read(&mdev->rs_pending_cnt); |
| 479 | 466 | ||
| 480 | mutex_lock(&mdev->data.mutex); | 467 | mutex_lock(&mdev->data.mutex); |
diff --git a/include/linux/drbd.h b/include/linux/drbd.h index b8d2516668aa..479ee3a1d901 100644 --- a/include/linux/drbd.h +++ b/include/linux/drbd.h | |||
| @@ -53,7 +53,7 @@ | |||
| 53 | 53 | ||
| 54 | 54 | ||
| 55 | extern const char *drbd_buildtag(void); | 55 | extern const char *drbd_buildtag(void); |
| 56 | #define REL_VERSION "8.3.8" | 56 | #define REL_VERSION "8.3.8.1" |
| 57 | #define API_VERSION 88 | 57 | #define API_VERSION 88 |
| 58 | #define PRO_VERSION_MIN 86 | 58 | #define PRO_VERSION_MIN 86 |
| 59 | #define PRO_VERSION_MAX 94 | 59 | #define PRO_VERSION_MAX 94 |
diff --git a/include/linux/drbd_nl.h b/include/linux/drbd_nl.h index ce77a746fc9d..5f042810a56c 100644 --- a/include/linux/drbd_nl.h +++ b/include/linux/drbd_nl.h | |||
| @@ -78,10 +78,11 @@ NL_PACKET(syncer_conf, 8, | |||
| 78 | NL_INTEGER( 30, T_MAY_IGNORE, rate) | 78 | NL_INTEGER( 30, T_MAY_IGNORE, rate) |
| 79 | NL_INTEGER( 31, T_MAY_IGNORE, after) | 79 | NL_INTEGER( 31, T_MAY_IGNORE, after) |
| 80 | NL_INTEGER( 32, T_MAY_IGNORE, al_extents) | 80 | NL_INTEGER( 32, T_MAY_IGNORE, al_extents) |
| 81 | NL_INTEGER( 71, T_MAY_IGNORE, dp_volume) | 81 | /* NL_INTEGER( 71, T_MAY_IGNORE, dp_volume) |
| 82 | NL_INTEGER( 72, T_MAY_IGNORE, dp_interval) | 82 | * NL_INTEGER( 72, T_MAY_IGNORE, dp_interval) |
| 83 | NL_INTEGER( 73, T_MAY_IGNORE, throttle_th) | 83 | * NL_INTEGER( 73, T_MAY_IGNORE, throttle_th) |
| 84 | NL_INTEGER( 74, T_MAY_IGNORE, hold_off_th) | 84 | * NL_INTEGER( 74, T_MAY_IGNORE, hold_off_th) |
| 85 | * feature will be reimplemented differently with 8.3.9 */ | ||
| 85 | NL_STRING( 52, T_MAY_IGNORE, verify_alg, SHARED_SECRET_MAX) | 86 | NL_STRING( 52, T_MAY_IGNORE, verify_alg, SHARED_SECRET_MAX) |
| 86 | NL_STRING( 51, T_MAY_IGNORE, cpu_mask, 32) | 87 | NL_STRING( 51, T_MAY_IGNORE, cpu_mask, 32) |
| 87 | NL_STRING( 64, T_MAY_IGNORE, csums_alg, SHARED_SECRET_MAX) | 88 | NL_STRING( 64, T_MAY_IGNORE, csums_alg, SHARED_SECRET_MAX) |
