Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7fde2be9 authored by Philipp Reisner's avatar Philipp Reisner
Browse files

drbd: Implemented real timeout checking for request processing time

parent c5a91619
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -990,6 +990,7 @@ struct drbd_conf {
	struct timer_list resync_timer;
	struct timer_list resync_timer;
	struct timer_list md_sync_timer;
	struct timer_list md_sync_timer;
	struct timer_list start_resync_timer;
	struct timer_list start_resync_timer;
	struct timer_list request_timer;
#ifdef DRBD_DEBUG_MD_SYNC
#ifdef DRBD_DEBUG_MD_SYNC
	struct {
	struct {
		unsigned int line;
		unsigned int line;
+3 −0
Original line number Original line Diff line number Diff line
@@ -3017,12 +3017,15 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
	init_timer(&mdev->resync_timer);
	init_timer(&mdev->resync_timer);
	init_timer(&mdev->md_sync_timer);
	init_timer(&mdev->md_sync_timer);
	init_timer(&mdev->start_resync_timer);
	init_timer(&mdev->start_resync_timer);
	init_timer(&mdev->request_timer);
	mdev->resync_timer.function = resync_timer_fn;
	mdev->resync_timer.function = resync_timer_fn;
	mdev->resync_timer.data = (unsigned long) mdev;
	mdev->resync_timer.data = (unsigned long) mdev;
	mdev->md_sync_timer.function = md_sync_timer_fn;
	mdev->md_sync_timer.function = md_sync_timer_fn;
	mdev->md_sync_timer.data = (unsigned long) mdev;
	mdev->md_sync_timer.data = (unsigned long) mdev;
	mdev->start_resync_timer.function = start_resync_timer_fn;
	mdev->start_resync_timer.function = start_resync_timer_fn;
	mdev->start_resync_timer.data = (unsigned long) mdev;
	mdev->start_resync_timer.data = (unsigned long) mdev;
	mdev->request_timer.function = request_timer_fn;
	mdev->request_timer.data = (unsigned long) mdev;


	init_waitqueue_head(&mdev->misc_wait);
	init_waitqueue_head(&mdev->misc_wait);
	init_waitqueue_head(&mdev->state_wait);
	init_waitqueue_head(&mdev->state_wait);
+3 −0
Original line number Original line Diff line number Diff line
@@ -912,6 +912,7 @@ static int drbd_connect(struct drbd_conf *mdev)
	drbd_send_state(mdev);
	drbd_send_state(mdev);
	clear_bit(USE_DEGR_WFC_T, &mdev->flags);
	clear_bit(USE_DEGR_WFC_T, &mdev->flags);
	clear_bit(RESIZE_PENDING, &mdev->flags);
	clear_bit(RESIZE_PENDING, &mdev->flags);
	mod_timer(&mdev->request_timer, jiffies + HZ); /* just start it here. */


	return 1;
	return 1;


@@ -3822,6 +3823,8 @@ static void drbd_disconnect(struct drbd_conf *mdev)
	atomic_set(&mdev->rs_pending_cnt, 0);
	atomic_set(&mdev->rs_pending_cnt, 0);
	wake_up(&mdev->misc_wait);
	wake_up(&mdev->misc_wait);


	del_timer(&mdev->request_timer);

	/* make sure syncer is stopped and w_resume_next_sg queued */
	/* make sure syncer is stopped and w_resume_next_sg queued */
	del_timer_sync(&mdev->resync_timer);
	del_timer_sync(&mdev->resync_timer);
	resync_timer_fn((unsigned long)mdev);
	resync_timer_fn((unsigned long)mdev);
+39 −0
Original line number Original line Diff line number Diff line
@@ -1194,3 +1194,42 @@ int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct
	}
	}
	return limit;
	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);
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -322,6 +322,7 @@ extern int __req_mod(struct drbd_request *req, enum drbd_req_event what,
		struct bio_and_error *m);
		struct bio_and_error *m);
extern void complete_master_bio(struct drbd_conf *mdev,
extern void complete_master_bio(struct drbd_conf *mdev,
		struct bio_and_error *m);
		struct bio_and_error *m);
extern void request_timer_fn(unsigned long data);


/* use this if you don't want to deal with calling complete_master_bio()
/* use this if you don't want to deal with calling complete_master_bio()
 * outside the spinlock, e.g. when walking some list on cleanup. */
 * outside the spinlock, e.g. when walking some list on cleanup. */