summaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_req.c
diff options
context:
space:
mode:
authorPhilipp Reisner2011-03-01 11:08:28 +0100
committerPhilipp Reisner2011-03-10 11:48:16 +0100
commit7fde2be93080c028c20078a2d6abec8a95891192 (patch)
tree47993e3c52d550d22ab8035de94d526d226bc2e6 /drivers/block/drbd/drbd_req.c
parentdrbd: Remove unused function atodb_endio() (diff)
downloadkernel-qcow2-linux-7fde2be93080c028c20078a2d6abec8a95891192.tar.gz
kernel-qcow2-linux-7fde2be93080c028c20078a2d6abec8a95891192.tar.xz
kernel-qcow2-linux-7fde2be93080c028c20078a2d6abec8a95891192.zip
drbd: Implemented real timeout checking for request processing time
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_req.c')
-rw-r--r--drivers/block/drbd/drbd_req.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 94fd5a2be559..c2cc28a55907 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -1194,3 +1194,42 @@ int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct
}
return limit;
}
+
+void request_timer_fn(unsigned long data)
+{
+ struct drbd_conf *mdev = (struct drbd_conf *) data;
+ struct drbd_request *req; /* oldest request */
+ struct list_head *le;
+ unsigned long et = 0; /* effective timeout = ko_count * timeout */
+
+ if (get_net_conf(mdev)) {
+ et = mdev->net_conf->timeout*HZ/10 * mdev->net_conf->ko_count;
+ put_net_conf(mdev);
+ }
+ if (!et || mdev->state.conn < C_WF_REPORT_PARAMS)
+ return; /* Recurring timer stopped */
+
+ spin_lock_irq(&mdev->req_lock);
+ le = &mdev->oldest_tle->requests;
+ if (list_empty(le)) {
+ spin_unlock_irq(&mdev->req_lock);
+ mod_timer(&mdev->request_timer, jiffies + et);
+ return;
+ }
+
+ le = le->prev;
+ req = list_entry(le, struct drbd_request, tl_requests);
+ if (time_is_before_eq_jiffies(req->start_time + et)) {
+ if (req->rq_state & RQ_NET_PENDING) {
+ dev_warn(DEV, "Remote failed to finish a request within ko-count * timeout\n");
+ _drbd_set_state(_NS(mdev, conn, C_TIMEOUT), CS_VERBOSE, NULL);
+ } else {
+ dev_warn(DEV, "Local backing block device frozen?\n");
+ mod_timer(&mdev->request_timer, jiffies + et);
+ }
+ } else {
+ mod_timer(&mdev->request_timer, req->start_time + et);
+ }
+
+ spin_unlock_irq(&mdev->req_lock);
+}