[DRBD-cvs] svn commit by phil - r2293 - in trunk: . drbd - * Send remote read requests from the worker context.

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Mon Jul 24 14:11:42 CEST 2006


* 
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Author: phil
Date: 2006-07-24 14:11:40 +0200 (Mon, 24 Jul 2006)
New Revision: 2293

Modified:
   trunk/ROADMAP
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/drbd_req.c
   trunk/drbd/drbd_worker.c
Log:
* Send remote read requests from the worker context.
* Impose the max_buffers setting also on a primary node.


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-07-21 08:24:20 UTC (rev 2292)
+++ trunk/ROADMAP	2006-07-24 12:11:40 UTC (rev 2293)
@@ -803,9 +803,8 @@
    Simon works on this. 
 
 39 Send mirrored write requests out of the worker context.
-   30% DONE
-   TODO:   Honour the max-buffers setting for this.
-           Think about read requests.
+   90% DONE
+       TODO: Get rid of the "send_task" thing.
 
 
 Maybe:

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2006-07-21 08:24:20 UTC (rev 2292)
+++ trunk/drbd/drbd_int.h	2006-07-24 12:11:40 UTC (rev 2293)
@@ -756,6 +756,7 @@
 
 	drbd_state_t state;
 	wait_queue_head_t cstate_wait; // TODO Rename into "misc_wait".
+	wait_queue_head_t rq_wait;
 	unsigned int send_cnt;
 	unsigned int recv_cnt;
 	unsigned int read_cnt;
@@ -1126,7 +1127,6 @@
 extern int drbd_md_sync_page_io(drbd_dev *mdev, struct drbd_backing_dev *bdev,
 				sector_t sector, int rw);
 // worker callbacks
-extern int w_is_app_read         (drbd_dev *, struct drbd_work *, int);
 extern int w_is_resync_read      (drbd_dev *, struct drbd_work *, int);
 extern int w_read_retry_remote   (drbd_dev *, struct drbd_work *, int);
 extern int w_e_end_data_req      (drbd_dev *, struct drbd_work *, int);
@@ -1139,6 +1139,8 @@
 extern int w_make_resync_request (drbd_dev *, struct drbd_work *, int);
 extern int w_send_dblock         (drbd_dev *, struct drbd_work *, int);
 extern int w_send_barrier        (drbd_dev *, struct drbd_work *, int);
+extern int w_send_read_req       (drbd_dev *, struct drbd_work *, int);
+
 extern void resync_timer_fn(unsigned long data);
 
 // drbd_receiver.c
@@ -1564,16 +1566,25 @@
 	D_ASSERT(atomic_read(&mdev->local_cnt)>=0);
 }
 
+/* 
 static inline void inc_ap_bio(drbd_dev* mdev)
 {
 	atomic_inc(&mdev->ap_bio_cnt);
 }
+*/
 
 static inline void dec_ap_bio(drbd_dev* mdev)
 {
-	if(atomic_dec_and_test(&mdev->ap_bio_cnt))
-		wake_up(&mdev->cstate_wait);
+	int ap_bio = atomic_dec_return(&mdev->ap_bio_cnt);
 
+	if(ap_bio == 0) wake_up(&mdev->cstate_wait);
+
+	if(inc_net(mdev)) {
+		if(ap_bio < mdev->net_conf->max_buffers) 
+			wake_up(&mdev->rq_wait);
+		dec_net(mdev);
+	}
+
 	D_ASSERT(atomic_read(&mdev->ap_bio_cnt)>=0);
 }
 

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-07-21 08:24:20 UTC (rev 2292)
+++ trunk/drbd/drbd_main.c	2006-07-24 12:11:40 UTC (rev 2293)
@@ -1978,12 +1978,12 @@
 	if (mdev->state.pdsk >= Inconsistent) /* implies cs >= Connected */ {
 		D_ASSERT(mdev->state.role == Primary);
 		if (test_and_clear_bit(UNPLUG_REMOTE,&mdev->flags)) {
-			/* add to the front of the data.work queue,
+			/* add to the data.work queue,
 			 * unless already queued.
 			 * XXX this might be a good addition to drbd_queue_work
 			 * anyways, to detect "double queuing" ... */
 			if (list_empty(&mdev->unplug_work.list))
-				_drbd_queue_work_front(&mdev->data.work,&mdev->unplug_work);
+				_drbd_queue_work(&mdev->data.work,&mdev->unplug_work);
 		}
 	}
 	spin_unlock_irq(&mdev->req_lock);
@@ -2064,6 +2064,7 @@
 	mdev->md_sync_timer.data = (unsigned long) mdev;
 
 	init_waitqueue_head(&mdev->cstate_wait);
+	init_waitqueue_head(&mdev->rq_wait);
 	init_waitqueue_head(&mdev->ee_wait);
 	init_waitqueue_head(&mdev->al_wait);
 

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-07-21 08:24:20 UTC (rev 2292)
+++ trunk/drbd/drbd_receiver.c	2006-07-24 12:11:40 UTC (rev 2293)
@@ -1045,8 +1045,6 @@
 		return FALSE;
 	}
 
-	D_ASSERT(req->w.cb == w_is_app_read);
-
 	spin_lock(&mdev->pr_lock);
 	hlist_del(&req->colision);
 	spin_unlock(&mdev->pr_lock);
@@ -2940,7 +2938,6 @@
 		ERR("Got a corrupt block_id/sector pair(3).\n");
 		return FALSE;
 	}
-	D_ASSERT(req->w.cb == w_is_app_read);
 
 	spin_lock(&mdev->pr_lock);
 	list_del(&req->w.list);

Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c	2006-07-21 08:24:20 UTC (rev 2292)
+++ trunk/drbd/drbd_req.c	2006-07-24 12:11:40 UTC (rev 2293)
@@ -124,19 +124,17 @@
 
 int drbd_read_remote(drbd_dev *mdev, drbd_request_t *req)
 {
-	int rv;
-	struct bio *bio = req->master_bio;
-
-	req->w.cb = w_is_app_read;
+	req->w.cb = w_send_read_req;
 	spin_lock(&mdev->pr_lock);
 	INIT_HLIST_NODE(&req->colision);
 	hlist_add_head( &req->colision, mdev->app_reads_hash +
 			ar_hash_fn(mdev, drbd_req_get_sector(req) ));
 	spin_unlock(&mdev->pr_lock);
 	set_bit(UNPLUG_REMOTE,&mdev->flags);
-	rv=drbd_send_drequest(mdev, DataRequest, bio->bi_sector, bio->bi_size,
-			      (unsigned long)req);
-	return rv;
+
+	drbd_queue_work(mdev, &mdev->data.work, &req->w);
+
+	return 1;
 }
 
 int drbd_pr_verify(drbd_dev *mdev, drbd_request_t * req, sector_t sector)
@@ -224,7 +222,14 @@
 {
 	drbd_request_t *req;
 	int local, remote;
+	int mxb;
 
+	mxb = 1000000; /* Artificial limit on open requests */
+	if(inc_net(mdev)) {
+		mxb = mdev->net_conf->max_buffers;
+		dec_net(mdev);
+	}
+
 	/* allocate outside of all locks
 	 */
 	req = drbd_req_new(mdev,bio);
@@ -237,10 +242,6 @@
 		return 0;
 	}
 
-	/* XXX req->w.cb = something; drbd_queue_work() ....
-	 * Not yet.
-	 */
-
 	// down_read(mdev->device_lock);
 
 	wait_event( mdev->cstate_wait,
@@ -321,7 +322,9 @@
 	/* we need to plug ALWAYS since we possibly need to kick lo_dev */
 	drbd_plug_device(mdev);
 
-	inc_ap_bio(mdev); // XXX maybe make this the first thing to do in drbd_make_request
+	// inc_ap_bio(mdev); do not allow more open requests than max_buffers!
+	wait_event( mdev->rq_wait,atomic_add_unless(&mdev->ap_bio_cnt,1,mxb) );
+
 	if (remote) {
 		/* either WRITE and Connected,
 		 * or READ, and no local disk,
@@ -368,7 +371,6 @@
 			up(&mdev->data.mutex);
 		} else {
 			// this node is diskless ...
-			inc_ap_pending(mdev);
 			drbd_read_remote(mdev,req);
 		}
 	}

Modified: trunk/drbd/drbd_worker.c
===================================================================
--- trunk/drbd/drbd_worker.c	2006-07-21 08:24:20 UTC (rev 2292)
+++ trunk/drbd/drbd_worker.c	2006-07-24 12:11:40 UTC (rev 2293)
@@ -242,7 +242,6 @@
 	ok = drbd_io_error(mdev);
 	if(unlikely(!ok)) ERR("Sending in w_read_retry_remote() failed\n");
 	
-	inc_ap_pending(mdev);
 	ok = drbd_read_remote(mdev,req);
 	if(unlikely(!ok)) {
 		ERR("drbd_read_remote() failed\n");
@@ -270,15 +269,6 @@
 	return 0;
 }
 
-/* in case we need it. currently unused,
- * since should be assigned to "w_read_retry_remote"
- */
-int w_is_app_read(drbd_dev *mdev, struct drbd_work *w, int unused)
-{
-	ERR("%s: Typecheck only, should never be called!\n", __FUNCTION__ );
-	return 0;
-}
-
 void resync_timer_fn(unsigned long data)
 {
 	unsigned long flags;
@@ -443,6 +433,9 @@
 	return 1;
 }
 
+/**
+ * w_e_end_data_req: Send the answer (DataReply) to a DataRequest.
+ */
 int w_e_end_data_req(drbd_dev *mdev, struct drbd_work *w, int cancel)
 {
 	struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w;
@@ -478,6 +471,9 @@
 	return ok;
 }
 
+/**
+ * w_e_end_data_req: Send the answer (RSDataReply) to a RSDataRequest.
+ */
 int w_e_end_rsdata_req(drbd_dev *mdev, struct drbd_work *w, int cancel)
 {
 	struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w;
@@ -557,6 +553,9 @@
 	return drbd_send_short_cmd(mdev,UnplugRemote);
 }
 
+/**
+ * w_send_dblock: Send a mirrored write request.
+ */
 int w_send_dblock(drbd_dev *mdev, struct drbd_work *w, int cancel)
 {
 	drbd_request_t *req = (drbd_request_t *)w;
@@ -582,6 +581,31 @@
 	return ok;
 }
 
+/**
+ * w_send_read_req: Send a read requests.
+ */
+int w_send_read_req(drbd_dev *mdev, struct drbd_work *w, int cancel)
+{
+	drbd_request_t *req = (drbd_request_t *)w;
+	struct bio *bio = req->master_bio;
+	int ok;
+
+	inc_ap_pending(mdev);
+
+	if (unlikely(cancel)) return 1;
+
+	ok = drbd_send_drequest(mdev, DataRequest, bio->bi_sector, bio->bi_size,
+				(unsigned long)req);
+
+	if (!ok) {
+		if (mdev->state.conn >= Connected) 
+			drbd_force_state(mdev,NS(conn,NetworkFailure));
+		drbd_thread_restart_nowait(&mdev->receiver);
+	}
+
+	return ok;
+}
+
 STATIC void drbd_global_lock(void)
 {
 	int i;



More information about the drbd-cvs mailing list