diff options
author | Philipp Reisner <philipp.reisner@linbit.com> | 2010-10-26 10:02:27 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2011-03-10 05:34:43 -0500 |
commit | 759fbdfba66e620aceb3e73167e6003d1b8b0b0b (patch) | |
tree | 34080a67cfdee2c0a2000126622bf65d4a7e0936 | |
parent | 688593c5a82068aea64df0b836793dfbbaa646d7 (diff) |
drbd: Track the numbers of sectors in flight
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
-rw-r--r-- | drivers/block/drbd/drbd_int.h | 1 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_main.c | 1 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_req.c | 13 | ||||
-rw-r--r-- | drivers/block/drbd/drbd_req.h | 12 |
4 files changed, 21 insertions, 6 deletions
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index bcba2742cfba..c804e44b9455 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -1102,6 +1102,7 @@ struct drbd_conf { | |||
1102 | struct fifo_buffer rs_plan_s; /* correction values of resync planer */ | 1102 | struct fifo_buffer rs_plan_s; /* correction values of resync planer */ |
1103 | int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */ | 1103 | int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */ |
1104 | int rs_planed; /* resync sectors already planed */ | 1104 | int rs_planed; /* resync sectors already planed */ |
1105 | atomic_t ap_in_flight; /* App sectors in flight (waiting for ack) */ | ||
1105 | }; | 1106 | }; |
1106 | 1107 | ||
1107 | static inline struct drbd_conf *minor_to_mdev(unsigned int minor) | 1108 | 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 9d9c2ed31e9a..e81d009dd061 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -2799,6 +2799,7 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) | |||
2799 | atomic_set(&mdev->pp_in_use_by_net, 0); | 2799 | atomic_set(&mdev->pp_in_use_by_net, 0); |
2800 | atomic_set(&mdev->rs_sect_in, 0); | 2800 | atomic_set(&mdev->rs_sect_in, 0); |
2801 | atomic_set(&mdev->rs_sect_ev, 0); | 2801 | atomic_set(&mdev->rs_sect_ev, 0); |
2802 | atomic_set(&mdev->ap_in_flight, 0); | ||
2802 | 2803 | ||
2803 | mutex_init(&mdev->md_io_mutex); | 2804 | mutex_init(&mdev->md_io_mutex); |
2804 | mutex_init(&mdev->data.mutex); | 2805 | mutex_init(&mdev->data.mutex); |
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 08f53ce9b88f..5c60d77d447c 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -558,6 +558,9 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, | |||
558 | 558 | ||
559 | case handed_over_to_network: | 559 | case handed_over_to_network: |
560 | /* assert something? */ | 560 | /* assert something? */ |
561 | if (bio_data_dir(req->master_bio) == WRITE) | ||
562 | atomic_add(req->size>>9, &mdev->ap_in_flight); | ||
563 | |||
561 | if (bio_data_dir(req->master_bio) == WRITE && | 564 | if (bio_data_dir(req->master_bio) == WRITE && |
562 | mdev->net_conf->wire_protocol == DRBD_PROT_A) { | 565 | mdev->net_conf->wire_protocol == DRBD_PROT_A) { |
563 | /* this is what is dangerous about protocol A: | 566 | /* this is what is dangerous about protocol A: |
@@ -591,6 +594,9 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, | |||
591 | dec_ap_pending(mdev); | 594 | dec_ap_pending(mdev); |
592 | req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING); | 595 | req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING); |
593 | req->rq_state |= RQ_NET_DONE; | 596 | req->rq_state |= RQ_NET_DONE; |
597 | if (req->rq_state & RQ_NET_SENT && req->rq_state & RQ_WRITE) | ||
598 | atomic_sub(req->size>>9, &mdev->ap_in_flight); | ||
599 | |||
594 | /* if it is still queued, we may not complete it here. | 600 | /* if it is still queued, we may not complete it here. |
595 | * it will be canceled soon. */ | 601 | * it will be canceled soon. */ |
596 | if (!(req->rq_state & RQ_NET_QUEUED)) | 602 | if (!(req->rq_state & RQ_NET_QUEUED)) |
@@ -628,14 +634,17 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, | |||
628 | req->rq_state |= RQ_NET_OK; | 634 | req->rq_state |= RQ_NET_OK; |
629 | D_ASSERT(req->rq_state & RQ_NET_PENDING); | 635 | D_ASSERT(req->rq_state & RQ_NET_PENDING); |
630 | dec_ap_pending(mdev); | 636 | dec_ap_pending(mdev); |
637 | atomic_sub(req->size>>9, &mdev->ap_in_flight); | ||
631 | req->rq_state &= ~RQ_NET_PENDING; | 638 | req->rq_state &= ~RQ_NET_PENDING; |
632 | _req_may_be_done_not_susp(req, m); | 639 | _req_may_be_done_not_susp(req, m); |
633 | break; | 640 | break; |
634 | 641 | ||
635 | case neg_acked: | 642 | case neg_acked: |
636 | /* assert something? */ | 643 | /* assert something? */ |
637 | if (req->rq_state & RQ_NET_PENDING) | 644 | if (req->rq_state & RQ_NET_PENDING) { |
638 | dec_ap_pending(mdev); | 645 | dec_ap_pending(mdev); |
646 | atomic_sub(req->size>>9, &mdev->ap_in_flight); | ||
647 | } | ||
639 | req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING); | 648 | req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING); |
640 | 649 | ||
641 | req->rq_state |= RQ_NET_DONE; | 650 | req->rq_state |= RQ_NET_DONE; |
@@ -692,6 +701,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, | |||
692 | } | 701 | } |
693 | D_ASSERT(req->rq_state & RQ_NET_SENT); | 702 | D_ASSERT(req->rq_state & RQ_NET_SENT); |
694 | req->rq_state |= RQ_NET_DONE; | 703 | req->rq_state |= RQ_NET_DONE; |
704 | if (mdev->net_conf->wire_protocol == DRBD_PROT_A) | ||
705 | atomic_sub(req->size>>9, &mdev->ap_in_flight); | ||
695 | _req_may_be_done(req, m); /* Allowed while state.susp */ | 706 | _req_may_be_done(req, m); /* Allowed while state.susp */ |
696 | break; | 707 | break; |
697 | 708 | ||
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h index ab2bd09d54b4..69d350fe7c1e 100644 --- a/drivers/block/drbd/drbd_req.h +++ b/drivers/block/drbd/drbd_req.h | |||
@@ -338,19 +338,21 @@ static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what) | |||
338 | return rv; | 338 | return rv; |
339 | } | 339 | } |
340 | 340 | ||
341 | /* completion of master bio is outside of spinlock. | 341 | /* completion of master bio is outside of our spinlock. |
342 | * If you need it irqsave, do it your self! | 342 | * We still may or may not be inside some irqs disabled section |
343 | * Which means: don't use from bio endio callback. */ | 343 | * of the lower level driver completion callback, so we need to |
344 | * spin_lock_irqsave here. */ | ||
344 | static inline int req_mod(struct drbd_request *req, | 345 | static inline int req_mod(struct drbd_request *req, |
345 | enum drbd_req_event what) | 346 | enum drbd_req_event what) |
346 | { | 347 | { |
348 | unsigned long flags; | ||
347 | struct drbd_conf *mdev = req->mdev; | 349 | struct drbd_conf *mdev = req->mdev; |
348 | struct bio_and_error m; | 350 | struct bio_and_error m; |
349 | int rv; | 351 | int rv; |
350 | 352 | ||
351 | spin_lock_irq(&mdev->req_lock); | 353 | spin_lock_irqsave(&mdev->req_lock, flags); |
352 | rv = __req_mod(req, what, &m); | 354 | rv = __req_mod(req, what, &m); |
353 | spin_unlock_irq(&mdev->req_lock); | 355 | spin_unlock_irqrestore(&mdev->req_lock, flags); |
354 | 356 | ||
355 | if (m.bio) | 357 | if (m.bio) |
356 | complete_master_bio(mdev, &m); | 358 | complete_master_bio(mdev, &m); |